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

Commit 6aca0e1

Browse files
committed
rpi: import RPi TDAQ server
1 parent 0960396 commit 6aca0e1

File tree

11 files changed

+1403
-0
lines changed

11 files changed

+1403
-0
lines changed

.github/workflows/ci.yml

+6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ jobs:
4040
- name: Checkout code
4141
uses: actions/checkout@v2
4242

43+
- name: Install Linux packages
44+
if: matrix.platform == 'ubuntu-latest'
45+
run: |
46+
sudo apt-get update
47+
sudo apt-get install -qq pkg-config libftdi1-dev
48+
4349
## - name: Build-Linux-32b
4450
## if: matrix.platform == 'ubuntu-latest'
4551
## run: |

.github/workflows/lint.yml

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ jobs:
1212
runs-on: ubuntu-latest
1313
steps:
1414
- uses: actions/checkout@v2
15+
- name: cgo-deps
16+
run: sudo apt install pkg-config libftdi1-dev
1517
- name: golangci-lint
1618
uses: golangci/golangci-lint-action@v2
1719
with:

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
github.com/go-sql-driver/mysql v1.5.0
88
github.com/peterh/liner v1.2.0
99
github.com/sbinet/pmon v0.4.1
10+
github.com/ziutek/ftdi v0.0.0-20200720221836-9d134ea90daf
1011
go-hep.org/x/hep v0.27.0
1112
golang.org/x/sync v0.0.0-20200930132711-30421366ff76
1213
golang.org/x/sys v0.0.0-20201005065044-765f4ea38db3

go.sum

+3
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4A
9494
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
9595
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY=
9696
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
97+
github.com/ziutek/ftdi v0.0.0-20200720221836-9d134ea90daf h1:uCbjtVaxaCk6327PBfIiXW591Ck23mVwh0GRIfJZaoY=
98+
github.com/ziutek/ftdi v0.0.0-20200720221836-9d134ea90daf/go.mod h1:fUzQhjslJJSlwoMW5Cd+0RUc8KuMDfsuZB+wfJAz1eg=
99+
github.com/ziutek/lcd v0.0.0-20141212131202-924f223d0903/go.mod h1:ZBCPhfHIcCtzsrXIcyEiSPDKHrjT9fXtJNKj2t1HCKw=
97100
gitlab.com/cznic/ebnf2y v1.0.0/go.mod h1:jx14dqOldV2pRvSi8HASTB/k5fkIv2TwjYAp5py0MTs=
98101
gitlab.com/cznic/golex v1.0.0/go.mod h1:vkWdDgqbbThjRHoOLU7yNPgMxaubAkwnvF/4zeG8cvU=
99102
go-hep.org/x/exp v0.3.0/go.mod h1:j7kUcLWPIO1Qb+yoWtOuYSqpnN1JsZE0LqDD9yDJOnI=

rpi/const.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2020 The go-lpc Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package rpi
6+
7+
const (
8+
MaxEventSize = (hardrocV2SLCFrameSize+1)*MaxNumASICs + (20*ASICMemDepth+2)*MaxNumASICs + 3 + MaxFwHeaderSize + 2 + MaxAnalogDataSize + 50
9+
10+
MaxAnalogDataSize = 1024*64*2 + 20
11+
MaxFwHeaderSize = 50
12+
MaxNumASICs = 48 // max number of hardrocs per dif that the system can handle
13+
MaxNumDIFs = 200 // max number of difs that the system can handle
14+
ASICMemDepth = 128 // memory depth of one asic . 128 is for hardroc v1
15+
16+
hardrocV2SLCFrameSize = 109
17+
microrocSLCFrameSize = 74
18+
)

rpi/device.go

+257
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
// Copyright 2020 The go-lpc Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package rpi
6+
7+
import (
8+
"encoding/binary"
9+
"fmt"
10+
"io"
11+
12+
"github.com/ziutek/ftdi"
13+
)
14+
15+
type ftdiDevice interface {
16+
Reset() error
17+
18+
SetBitmode(iomask byte, mode ftdi.Mode) error
19+
SetFlowControl(flowctrl ftdi.FlowCtrl) error
20+
SetLatencyTimer(lt int) error
21+
SetWriteChunkSize(cs int) error
22+
SetReadChunkSize(cs int) error
23+
PurgeBuffers() error
24+
25+
io.Writer
26+
io.Reader
27+
io.Closer
28+
}
29+
30+
type device struct {
31+
vid uint16 // vendor ID
32+
pid uint16 // product ID
33+
ft ftdiDevice // handle to the FTDI device
34+
}
35+
36+
var (
37+
ftdiOpen = ftdiOpenImpl
38+
)
39+
40+
func ftdiOpenImpl(vid, pid uint16) (ftdiDevice, error) {
41+
dev, err := ftdi.OpenFirst(int(vid), int(pid), ftdi.ChannelAny)
42+
return dev, err
43+
}
44+
45+
func newDevice(vid, pid uint16) (*device, error) {
46+
ft, err := ftdiOpen(vid, pid)
47+
if err != nil {
48+
return nil, fmt.Errorf("could not open FTDI device (vid=0x%x, pid=0x%x): %w", vid, pid, err)
49+
}
50+
51+
dev := &device{vid: vid, pid: pid, ft: ft}
52+
err = dev.init()
53+
if err != nil {
54+
ft.Close()
55+
return nil, fmt.Errorf("could not initialize FTDI device (vid=0x%x, pid=0x%x): %w", vid, pid, err)
56+
}
57+
58+
return dev, nil
59+
}
60+
61+
func (dev *device) init() error {
62+
var err error
63+
64+
err = dev.ft.Reset()
65+
if err != nil {
66+
return fmt.Errorf("could not reset USB: %w", err)
67+
}
68+
69+
err = dev.ft.SetBitmode(0, ftdi.ModeBitbang)
70+
if err != nil {
71+
return fmt.Errorf("could not disable bitbang: %w", err)
72+
}
73+
74+
err = dev.ft.SetFlowControl(ftdi.FlowCtrlDisable)
75+
if err != nil {
76+
return fmt.Errorf("could not disable flow control: %w", err)
77+
}
78+
79+
err = dev.ft.SetLatencyTimer(2)
80+
if err != nil {
81+
return fmt.Errorf("could not set latency timer to 2: %w", err)
82+
}
83+
84+
err = dev.ft.SetWriteChunkSize(0xffff)
85+
if err != nil {
86+
return fmt.Errorf("could not set write chunk-size to 0xffff: %w", err)
87+
}
88+
89+
err = dev.ft.SetReadChunkSize(0xffff)
90+
if err != nil {
91+
return fmt.Errorf("could not set read chunk-size to 0xffff: %w", err)
92+
}
93+
94+
if dev.pid == 0x6014 {
95+
err = dev.ft.SetBitmode(0, ftdi.ModeReset)
96+
if err != nil {
97+
return fmt.Errorf("could not reset bit mode: %w", err)
98+
}
99+
}
100+
101+
err = dev.ft.PurgeBuffers()
102+
if err != nil {
103+
return fmt.Errorf("could not purge USB buffers: %w", err)
104+
}
105+
106+
return err
107+
}
108+
109+
func (dev *device) close() error {
110+
return dev.ft.Close()
111+
}
112+
113+
func (dev *device) usbRegRead(addr uint32) (uint32, error) {
114+
a := (addr | 0x4000) & 0x7fff
115+
p := []byte{uint8(a>>8) & 0xff, uint8(a>>0) & 0xff, 0, 0}
116+
117+
n, err := dev.ft.Write(p[:2])
118+
switch {
119+
case err != nil:
120+
return 0, fmt.Errorf("could not write USB addr 0x%x: %w", addr, err)
121+
case n != len(p[:2]):
122+
return 0, fmt.Errorf("could not write USB addr 0x%x: %w", addr, io.ErrShortWrite)
123+
}
124+
125+
_, err = io.ReadFull(dev.ft, p)
126+
if err != nil {
127+
return 0, fmt.Errorf("could not read register 0x%x: %w", addr, err)
128+
}
129+
130+
v := binary.BigEndian.Uint32(p)
131+
return v, nil
132+
}
133+
134+
func (dev *device) usbCmdWrite(cmd uint32) error {
135+
addr := cmd | 0x8000 // keep only 14 LSB, write, so bit 14=0,register mode, so bit 15=0
136+
buf := []byte{uint8(addr>>8) & 0xff, uint8(addr>>0) & 0xff}
137+
138+
n, err := dev.ft.Write(buf)
139+
switch {
140+
case err != nil:
141+
return fmt.Errorf("could not write USB command 0x%x: %w", cmd, err)
142+
case n != len(buf):
143+
return fmt.Errorf("could not write USB command 0x%x: %w", cmd, io.ErrShortWrite)
144+
}
145+
146+
return nil
147+
}
148+
149+
func (dev *device) usbRegWrite(addr, v uint32) error {
150+
var (
151+
a = addr & 0x3fff
152+
p = make([]byte, 6)
153+
)
154+
155+
binary.BigEndian.PutUint16(p[:2], uint16(a))
156+
binary.BigEndian.PutUint32(p[2:], uint32(v))
157+
and0xff(p)
158+
159+
n, err := dev.ft.Write(p)
160+
switch {
161+
case err != nil:
162+
return fmt.Errorf("could not write USB register (0x%x, 0x%x): %w", addr, v, err)
163+
case n != len(p):
164+
return fmt.Errorf("could not write USB register (0x%x, 0x%x): %w", addr, v, io.ErrShortWrite)
165+
}
166+
return nil
167+
}
168+
169+
func (dev *device) setChipTypeRegister(v uint32) error {
170+
return dev.usbRegWrite(0x00, v)
171+
}
172+
173+
func (dev *device) setDIFID(v uint32) error {
174+
return dev.usbRegWrite(0x01, v)
175+
}
176+
177+
func (dev *device) setControlRegister(v uint32) error {
178+
return dev.usbRegWrite(0x03, v)
179+
}
180+
181+
func (dev *device) getControlRegister() (uint32, error) {
182+
return dev.usbRegRead(0x03)
183+
}
184+
185+
func (dev *device) difCptReset() error {
186+
const addr = 0x03
187+
v, err := dev.usbRegRead(addr)
188+
if err != nil {
189+
return fmt.Errorf("could not read register 0x%x", addr)
190+
}
191+
192+
v |= 0x2000
193+
err = dev.usbRegWrite(addr, v)
194+
if err != nil {
195+
return fmt.Errorf("could not write to register 0x%x", addr)
196+
}
197+
198+
v &= 0xffffdfff
199+
err = dev.usbRegWrite(addr, v)
200+
if err != nil {
201+
return fmt.Errorf("could not write to register 0x%x", addr)
202+
}
203+
204+
return nil
205+
}
206+
207+
func (dev *device) setPwr2PwrARegister(v uint32) error { return dev.usbRegWrite(0x40, v) }
208+
func (dev *device) setPwrA2PwrDRegister(v uint32) error { return dev.usbRegWrite(0x41, v) }
209+
func (dev *device) setPwrD2DAQRegister(v uint32) error { return dev.usbRegWrite(0x42, v) }
210+
func (dev *device) setDAQ2PwrDRegister(v uint32) error { return dev.usbRegWrite(0x43, v) }
211+
func (dev *device) setPwrD2PwrARegister(v uint32) error { return dev.usbRegWrite(0x44, v) }
212+
213+
func (dev *device) setEventsBetweenTemperatureReadout(v uint32) error {
214+
return dev.usbRegWrite(0x55, v)
215+
}
216+
217+
func (dev *device) setAnalogConfigureRegister(v uint32) error {
218+
return dev.usbRegWrite(0x60, v)
219+
}
220+
221+
func (dev *device) usbFwVersion() (uint32, error) {
222+
return dev.usbRegRead(0x100)
223+
}
224+
225+
func (dev *device) hardrocFlushDigitalFIFO() error {
226+
return nil
227+
}
228+
229+
func (dev *device) hardrocStopDigitalAcquisitionCommand() error {
230+
return dev.usbCmdWrite(0x02)
231+
}
232+
233+
func (dev *device) hardrocSLCStatusRead() (uint32, error) {
234+
return dev.usbRegRead(0x06)
235+
}
236+
237+
func (dev *device) hardrocCmdSLCWrite() error {
238+
return dev.usbCmdWrite(0x01)
239+
}
240+
241+
func (dev *device) hardrocCmdSLCWriteCRC(v uint16) error {
242+
p := make([]byte, 2)
243+
binary.BigEndian.PutUint16(p, v)
244+
_, err := dev.ft.Write(p)
245+
return err
246+
}
247+
248+
func (dev *device) cmdSLCWriteSingleSLCFrame(p []byte) error {
249+
_, err := dev.ft.Write(p)
250+
return err
251+
}
252+
253+
func and0xff(p []byte) {
254+
for i := range p {
255+
p[i] &= 0xff
256+
}
257+
}

0 commit comments

Comments
 (0)