Skip to content
This repository was archived by the owner on Dec 24, 2024. It is now read-only.

Commit e355d84

Browse files
committed
eda: add I2C + INJ handling
1 parent 9240465 commit e355d84

File tree

4 files changed

+299
-7
lines changed

4 files changed

+299
-7
lines changed

eda/device.go

Lines changed: 221 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,9 @@ func (dev *Device) initFPGA() error {
368368

369369
dev.msg.Printf("trigger mode: %v", dev.cfg.daq.mode)
370370
switch dev.cfg.daq.mode {
371+
default:
372+
return fmt.Errorf("eda: invalid trigger mode: %v", dev.cfg.daq.mode)
373+
371374
case "dcc":
372375
err = dev.syncSelectCmdDCC()
373376
if err != nil {
@@ -381,14 +384,40 @@ func (dev *Device) initFPGA() error {
381384
if err != nil {
382385
return fmt.Errorf("eda: could not enable DCC RAM-full: %w", err)
383386
}
387+
384388
case "noise":
385389
err = dev.syncSelectCmdSoft()
386390
if err != nil {
387391
return fmt.Errorf("eda: could not select SOFT cmd: %w", err)
388392
}
389393

390-
default:
391-
return fmt.Errorf("eda: invalid trigger mode: %v", dev.cfg.daq.mode)
394+
case "inj":
395+
// set injector DAC
396+
const injDAC = 100
397+
dev.msg.Printf("setting injector DAC with value %d", injDAC)
398+
for _, rfm := range dev.rfms {
399+
dev.msg.Printf("rfm %d...", rfm)
400+
err = dev.injDACSelect(rfm)
401+
if err != nil {
402+
return fmt.Errorf(
403+
"eda: could select injector DAC for rfm=%d: %w",
404+
rfm, err,
405+
)
406+
}
407+
408+
err = dev.injDACSet(rfm, injDAC)
409+
if err != nil {
410+
return fmt.Errorf(
411+
"eda: could not set injector DAC for rfm=%d: %w",
412+
rfm, err,
413+
)
414+
}
415+
}
416+
417+
err = dev.syncSelectCmdSoft()
418+
if err != nil {
419+
return fmt.Errorf("eda: could not select SOFT cmd: %w", err)
420+
}
392421
}
393422

394423
return nil
@@ -408,6 +437,18 @@ func (dev *Device) initHRFromDB() error {
408437
dev.hrscSetRShaper(0, dev.cfg.hr.rshaper)
409438
dev.hrscSetCShaper(0, dev.cfg.hr.cshaper)
410439

440+
if dev.cfg.mode == "inj" {
441+
dev.hrscSetCtest(0, 31, 1)
442+
dev.hrscSetCtest(1, 31, 1)
443+
dev.hrscSetCtest(2, 31, 1)
444+
dev.hrscSetCtest(3, 31, 1)
445+
dev.hrscSetCtest(4, 31, 1)
446+
dev.hrscSetCtest(5, 31, 1)
447+
dev.hrscSetCtest(6, 31, 1)
448+
dev.hrscSetCtest(7, 31, 1)
449+
dev.hrscSetCtest(8, 31, 1)
450+
}
451+
411452
// set chip IDs
412453
for hr := uint32(0); hr < nHR; hr++ {
413454
dev.hrscSetChipID(hr, hr+1)
@@ -594,6 +635,8 @@ func (dev *Device) Start(run uint32) error {
594635
return dev.startRunDCC(run)
595636
case "noise":
596637
return dev.startRunNoise(run)
638+
case "inj":
639+
return dev.startRunInj(run)
597640
default:
598641
err := fmt.Errorf("eda: unknown trig-mode %q", dev.cfg.daq.mode)
599642
dev.msg.Printf("%+v", err)
@@ -695,6 +738,47 @@ func (dev *Device) startRunNoise(run uint32) error {
695738
return nil
696739
}
697740

741+
func (dev *Device) startRunInj(run uint32) error {
742+
var err error
743+
744+
err = dev.injStartCTestPulser(25000, 0) // 100Hz
745+
if err != nil {
746+
return fmt.Errorf("eda: could not start ctest pulser: %w", err)
747+
}
748+
749+
for _, rfm := range dev.rfms {
750+
err = dev.daqFIFOInit(rfm)
751+
if err != nil {
752+
return fmt.Errorf("eda: could not initialize DAQ FIFO (RFM=%d): %w", rfm, err)
753+
}
754+
}
755+
756+
err = dev.cntReset()
757+
if err != nil {
758+
return fmt.Errorf("eda: could not reset counters: %w", err)
759+
}
760+
761+
err = dev.syncResetBCID()
762+
if err != nil {
763+
return fmt.Errorf("eda: could not reset BCID: %w", err)
764+
}
765+
766+
err = dev.syncStart()
767+
if err != nil {
768+
return fmt.Errorf("eda: could not start acquisition: %w", err)
769+
}
770+
771+
err = dev.syncArmFIFO()
772+
if err != nil {
773+
return fmt.Errorf("eda: could not arm FIFO: %w", err)
774+
}
775+
776+
dev.daq.done = make(chan int)
777+
778+
go dev.loop()
779+
return nil
780+
}
781+
698782
func (dev *Device) initRun(run uint32) error {
699783
// save run-dependant settings
700784
dev.msg.Printf(
@@ -769,6 +853,8 @@ func (dev *Device) loop() {
769853
dev.loopDCC()
770854
case "noise":
771855
dev.loopNoise()
856+
case "inj":
857+
dev.loopInj()
772858
default:
773859
err := fmt.Errorf("eda: invalid trig-mode %q", dev.cfg.daq.mode)
774860
panic(err)
@@ -998,6 +1084,126 @@ func (dev *Device) loopNoise() {
9981084
}
9991085
}
10001086

1087+
func (dev *Device) loopInj() {
1088+
var (
1089+
w = dev.msg.Writer()
1090+
printf = fmt.Fprintf
1091+
errorf = func(format string, args ...interface{}) {
1092+
dev.err = fmt.Errorf(format, args...)
1093+
dev.msg.Printf("%+v", dev.err)
1094+
}
1095+
cycle int
1096+
err error
1097+
)
1098+
1099+
if len(dev.daq.rfm) != 0 {
1100+
for i := range dev.daq.rfm {
1101+
rfm := &dev.daq.rfm[i]
1102+
if !rfm.valid() {
1103+
continue
1104+
}
1105+
defer rfm.sck.Close()
1106+
}
1107+
}
1108+
1109+
for i := range dev.daq.rfm {
1110+
rfm := &dev.daq.rfm[i]
1111+
rfm.w = &wbuf{
1112+
p: make([]byte, daqBufferSize),
1113+
}
1114+
}
1115+
1116+
for {
1117+
printf(w, "trigger %07d, state: acq-", cycle)
1118+
// wait until readout is done
1119+
readout:
1120+
for {
1121+
state := dev.syncState()
1122+
switch {
1123+
case state >= regs.S_RAMFULL:
1124+
break readout
1125+
default:
1126+
select {
1127+
case <-dev.daq.done:
1128+
dev.daq.done <- 1
1129+
return
1130+
default:
1131+
}
1132+
}
1133+
}
1134+
printf(w, "ramfull-")
1135+
err = dev.syncRAMFullExt()
1136+
if err != nil {
1137+
errorf("could not set RAMFULL: %+v", err)
1138+
return
1139+
}
1140+
1141+
dataReady:
1142+
for {
1143+
state := dev.syncState()
1144+
switch {
1145+
case state >= regs.S_FIFO_READY:
1146+
break dataReady
1147+
default:
1148+
select {
1149+
case <-dev.daq.done:
1150+
dev.daq.done <- 1
1151+
return
1152+
default:
1153+
}
1154+
}
1155+
}
1156+
1157+
printf(w, "cp-") // copy
1158+
1159+
// read hardroc data
1160+
for i, rfm := range dev.rfms {
1161+
dev.daqWriteDIFData(dev.daq.rfm[i].w, rfm)
1162+
}
1163+
err = dev.syncAckFIFO()
1164+
if err != nil {
1165+
errorf("eda: could not ACK FIFO: %w", err)
1166+
return
1167+
}
1168+
printf(w, "tx-")
1169+
var grp errgroup.Group
1170+
for i := range dev.daq.rfm {
1171+
if !dev.daq.rfm[i].valid() {
1172+
continue
1173+
}
1174+
ii := i
1175+
grp.Go(func() error {
1176+
err := dev.daqSendDIFData(ii)
1177+
if err != nil {
1178+
errorf("eda: could not send DIF data (RFM=%d): %w", dev.rfms[ii], err)
1179+
return err
1180+
}
1181+
return nil
1182+
})
1183+
}
1184+
err = grp.Wait()
1185+
if err != nil {
1186+
errorf("eda: could not send DIF data: %w", err)
1187+
return
1188+
}
1189+
1190+
printf(w, "\n")
1191+
cycle++
1192+
1193+
select {
1194+
case <-dev.daq.done:
1195+
dev.daq.done <- 1
1196+
return
1197+
default:
1198+
err = dev.syncStart()
1199+
if err != nil {
1200+
errorf("eda: could not start acquisition: %w", err)
1201+
return
1202+
}
1203+
}
1204+
}
1205+
}
1206+
10011207
func (dev *Device) Stop() error {
10021208
const timeout = 10 * time.Second
10031209
tck := time.NewTimer(timeout)
@@ -1030,6 +1236,19 @@ func (dev *Device) Stop() error {
10301236
if err != nil {
10311237
return fmt.Errorf("eda: could not stop counters: %w", err)
10321238
}
1239+
case "inj":
1240+
err = dev.syncStop()
1241+
if err != nil {
1242+
return fmt.Errorf("eda: could not stop acquisition: %w", err)
1243+
}
1244+
err = dev.cntStop()
1245+
if err != nil {
1246+
return fmt.Errorf("eda: could not stop counters: %w", err)
1247+
}
1248+
err = dev.injStopCTestPulser()
1249+
if err != nil {
1250+
return fmt.Errorf("eda: could not stop ctest pulser: %w", err)
1251+
}
10331252
}
10341253

10351254
err = dev.cntReset()

eda/pio.go

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"strings"
1616
"time"
1717

18+
"github.com/go-daq/smbus"
1819
"github.com/go-lpc/mim/eda/internal/regs"
1920
"github.com/go-lpc/mim/internal/eformat"
2021
"github.com/go-lpc/mim/internal/mmap"
@@ -1164,11 +1165,11 @@ func (dev *Device) hrscWriteConfHRs(fname string) error {
11641165
return nil
11651166
}
11661167

1167-
// // hrscSetCtest switches the test capacitor (1=closed).
1168-
// func (dev *Device) hrscSetCtest(hr, ch, v uint32) {
1169-
// dev.hrscSetBit(hr, ch, v&0x01)
1170-
// }
1171-
//
1168+
// hrscSetCtest switches the test capacitor (1=closed).
1169+
func (dev *Device) hrscSetCtest(hr, ch, v uint32) {
1170+
dev.hrscSetBit(hr, ch, v&0x01)
1171+
}
1172+
11721173
// func (dev *Device) hrscSetAllCtestOff() {
11731174
// for hr := uint32(0); hr < nHR; hr++ {
11741175
// for ch := uint32(0); ch < nChans; ch++ {
@@ -2006,3 +2007,72 @@ func (dev *Device) daqSendDIFData(i int) error {
20062007

20072008
return nil
20082009
}
2010+
2011+
// --- test injector ---
2012+
2013+
func (dev *Device) i2c(rfm int) (*smbus.Conn, error) {
2014+
addr := 0b00100000 + (uint8(rfm) & 0x3)
2015+
conn, err := smbus.Open(0, addr)
2016+
if err != nil {
2017+
return nil, fmt.Errorf("eda: could not connect to I2C bus(0,rfm=%d): %w", rfm, err)
2018+
}
2019+
2020+
return conn, nil
2021+
}
2022+
2023+
func (dev *Device) injDACSelect(rfm int) error {
2024+
conn, err := dev.i2c(rfm)
2025+
if err != nil {
2026+
return err
2027+
}
2028+
defer conn.Close()
2029+
2030+
return nil
2031+
}
2032+
2033+
func (dev *Device) injDACSet(rfm int, v uint32) error {
2034+
conn, err := dev.i2c(rfm)
2035+
if err != nil {
2036+
return err
2037+
}
2038+
defer conn.Close()
2039+
2040+
_, err = conn.Write([]byte{
2041+
0, // command byte
2042+
uint8(v % 0x100), // lsb
2043+
uint8(v >> 8), // msb
2044+
})
2045+
if err != nil {
2046+
return fmt.Errorf("eda: could not write 3 bytes to LTC1668 DAC: %w", err)
2047+
}
2048+
2049+
time.Sleep(200 * time.Microsecond) // for stabilization.
2050+
return nil
2051+
}
2052+
2053+
func (dev *Device) injStartCTestPulser(halfPeriod, phase uint32) error {
2054+
// half period unit = 200 ns
2055+
// phase unit = 6.25 ns
2056+
v := (phase&0x1f)<<16 | (halfPeriod & 0xffff)
2057+
dev.regs.pio.pulser.w(v) // set timing registers
2058+
time.Sleep(1 * time.Microsecond)
2059+
dev.regs.pio.ctrl.w(dev.regs.pio.ctrl.r() | regs.O_CTEST) // enable
2060+
2061+
if dev.err != nil {
2062+
return fmt.Errorf("eda: could not start ctest pulser: %w", dev.err)
2063+
}
2064+
return nil
2065+
}
2066+
2067+
func (dev *Device) injStopCTestPulser() error {
2068+
ctrl := dev.regs.pio.ctrl.r()
2069+
ctrl &= ^uint32(regs.O_CTEST)
2070+
dev.regs.pio.ctrl.w(ctrl)
2071+
2072+
dev.regs.pio.pulser.w(0)
2073+
2074+
if dev.err != nil {
2075+
return fmt.Errorf("eda: could not stop ctest pulser: %w", dev.err)
2076+
}
2077+
return nil
2078+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/go-lpc/mim
33
go 1.16
44

55
require (
6+
github.com/go-daq/smbus v0.0.0-20201216173259-5725b4593606
67
github.com/go-daq/tdaq v0.14.2
78
github.com/go-sql-driver/mysql v1.6.0
89
github.com/peterh/liner v1.2.1

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/
3232
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
3333
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
3434
github.com/gdamore/optopia v0.2.0/go.mod h1:YKYEwo5C1Pa617H7NlPcmQXl+vG6YnSSNB44n8dNL0Q=
35+
github.com/go-daq/smbus v0.0.0-20201216173259-5725b4593606 h1:1lyGjYJXpYkF6fGQbhAIOdIaeymKQuS6RJVLVlTzc5w=
36+
github.com/go-daq/smbus v0.0.0-20201216173259-5725b4593606/go.mod h1:KDYiP7UvrtHRqnVLE6ziKupbojinMHjFUdo+1VA7r/Q=
3537
github.com/go-daq/tdaq v0.14.2 h1:17hEikzmQfLl57mSTxwMaILszGjm+jHSj49/RYPPbEs=
3638
github.com/go-daq/tdaq v0.14.2/go.mod h1:oiqGEED+dzinsAHVJ1Lq/HZf7RYbaTB8KpHTRDUhxNc=
3739
github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=

0 commit comments

Comments
 (0)