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

Commit 1c5ca06

Browse files
committed
eda: add I2C + INJ handling
1 parent 43d2dc3 commit 1c5ca06

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
@@ -366,6 +366,9 @@ func (dev *Device) initFPGA() error {
366366

367367
dev.msg.Printf("trigger mode: %v", dev.cfg.daq.mode)
368368
switch dev.cfg.daq.mode {
369+
default:
370+
return fmt.Errorf("eda: invalid trigger mode: %v", dev.cfg.daq.mode)
371+
369372
case "dcc":
370373
err = dev.syncSelectCmdDCC()
371374
if err != nil {
@@ -379,14 +382,40 @@ func (dev *Device) initFPGA() error {
379382
if err != nil {
380383
return fmt.Errorf("eda: could not enable DCC RAM-full: %w", err)
381384
}
385+
382386
case "noise":
383387
err = dev.syncSelectCmdSoft()
384388
if err != nil {
385389
return fmt.Errorf("eda: could not select SOFT cmd: %w", err)
386390
}
387391

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

392421
return nil
@@ -406,6 +435,18 @@ func (dev *Device) initHRFromDB() error {
406435
dev.hrscSetRShaper(0, dev.cfg.hr.rshaper)
407436
dev.hrscSetCShaper(0, dev.cfg.hr.cshaper)
408437

438+
if dev.cfg.mode == "inj" {
439+
dev.hrscSetCtest(0, 31, 1)
440+
dev.hrscSetCtest(1, 31, 1)
441+
dev.hrscSetCtest(2, 31, 1)
442+
dev.hrscSetCtest(3, 31, 1)
443+
dev.hrscSetCtest(4, 31, 1)
444+
dev.hrscSetCtest(5, 31, 1)
445+
dev.hrscSetCtest(6, 31, 1)
446+
dev.hrscSetCtest(7, 31, 1)
447+
dev.hrscSetCtest(8, 31, 1)
448+
}
449+
409450
// set chip IDs
410451
for hr := uint32(0); hr < nHR; hr++ {
411452
dev.hrscSetChipID(hr, hr+1)
@@ -592,6 +633,8 @@ func (dev *Device) Start(run uint32) error {
592633
return dev.startRunDCC(run)
593634
case "noise":
594635
return dev.startRunNoise(run)
636+
case "inj":
637+
return dev.startRunInj(run)
595638
default:
596639
err := fmt.Errorf("eda: unknown trig-mode %q", dev.cfg.daq.mode)
597640
dev.msg.Printf("%+v", err)
@@ -693,6 +736,47 @@ func (dev *Device) startRunNoise(run uint32) error {
693736
return nil
694737
}
695738

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

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

10331252
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)