2025-02-11 20:20:12 +00:00
|
|
|
#! /usr/bin/python3 -i
|
2017-05-17 07:38:01 +00:00
|
|
|
# encoding: UTF-8
|
2013-10-20 19:35:45 +00:00
|
|
|
|
2015-01-12 20:54:16 +00:00
|
|
|
from altera_ctrl import *
|
2025-02-04 15:07:02 +00:00
|
|
|
import math
|
2015-01-12 20:54:16 +00:00
|
|
|
|
2017-05-19 18:35:47 +00:00
|
|
|
def set_prompt(prompt="RPIRENA"):
|
|
|
|
|
sys.ps1 = prompt + "> "
|
|
|
|
|
sys.ps2 = prompt + ". "
|
|
|
|
|
try:
|
|
|
|
|
ip=sys.modules["__main__"].__dict__["get_ipython"]()
|
|
|
|
|
from IPython.terminal.prompts import Prompts, Token
|
|
|
|
|
class soloprompts(Prompts):
|
|
|
|
|
def in_prompt_tokens(self, *wtf):
|
|
|
|
|
return [(Token, prompt+'> ')]
|
|
|
|
|
def continuation_prompt_tokens(self, *wtf):
|
|
|
|
|
return [(Token, prompt+'. ')]
|
|
|
|
|
def out_prompt_tokens(self, *wtf):
|
|
|
|
|
return [(Token, prompt+'= ')]
|
|
|
|
|
def rewrite_prompt_tokens(self, *wtf):
|
|
|
|
|
return [(Token, prompt+'- ')]
|
|
|
|
|
ip.prompts=soloprompts(ip)
|
|
|
|
|
except ImportError:
|
|
|
|
|
ip.prompt_manager.templates.update({
|
|
|
|
|
'in': 'In [{color.number}{count}{color.prompt}] '+prompt+'> ',
|
|
|
|
|
'in2': ' .{dots}. '+prompt+'. ',
|
|
|
|
|
'out': 'Out[{color.number}{count}{color.prompt}] '+prompt+'> ',
|
|
|
|
|
})
|
|
|
|
|
except NameError:
|
|
|
|
|
pass
|
|
|
|
|
except KeyError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
set_prompt()
|
2013-10-20 19:35:45 +00:00
|
|
|
|
2013-11-06 22:48:09 +00:00
|
|
|
DREG_ADDR = 0xc020
|
|
|
|
|
CORE_ADDR = 0x8040
|
|
|
|
|
TRIG_ADDR = 0x8100
|
|
|
|
|
|
|
|
|
|
def filter(ch, p):
|
2021-07-30 17:11:19 +00:00
|
|
|
c = b""
|
2013-11-06 22:48:09 +00:00
|
|
|
for i in range(16):
|
2021-07-30 17:11:19 +00:00
|
|
|
n = p[(i+4)&15][0] & 0x3f
|
2013-11-06 22:48:09 +00:00
|
|
|
a = p[(i+2)&15][1] & 0x1fff
|
|
|
|
|
b = p[(i+2)&15][2] & 0x1fff
|
|
|
|
|
d = (n<<26)|(b<<13)|a;
|
2013-11-07 21:27:02 +00:00
|
|
|
c += struct.pack(">6H", DREG_ADDR+1, d&0xffff, DREG_ADDR+2, d>>16, DREG_ADDR+3, 0x800|(ch*16+i))
|
2013-11-06 22:48:09 +00:00
|
|
|
spidev.sync_transfer(cmd=c, rsize=0)
|
|
|
|
|
|
|
|
|
|
def trigconf(i, v):
|
|
|
|
|
i *= 2
|
|
|
|
|
c = struct.pack(">6H", TRIG_ADDR|0xc000|i, v&0xffff, TRIG_ADDR|0xc001|i, v>>16, 0x8001, 0)
|
|
|
|
|
spidev.sync_transfer(cmd=c, rsize=0)
|
|
|
|
|
|
2013-11-08 15:18:13 +00:00
|
|
|
def i2f(i):
|
|
|
|
|
if i<0:
|
|
|
|
|
s = 0x20000
|
|
|
|
|
i = -i
|
|
|
|
|
else:
|
|
|
|
|
s = 0
|
|
|
|
|
|
|
|
|
|
if i<0x4000:
|
|
|
|
|
return s|i
|
|
|
|
|
e=1
|
|
|
|
|
while i>=0x4000:
|
|
|
|
|
i>>=1
|
|
|
|
|
e+=1
|
|
|
|
|
if e>15:
|
|
|
|
|
return s|0x1ffff
|
|
|
|
|
return s|(e<<13)|(i&0x1fff)
|
|
|
|
|
|
|
|
|
|
def f2i(f):
|
|
|
|
|
e = (f>>13)&15
|
|
|
|
|
if e<2:
|
|
|
|
|
m = f & 0x3fff
|
|
|
|
|
else:
|
|
|
|
|
m = (0x2000|f&0x1fff)<<(e-1)
|
|
|
|
|
return -m if f&0x20000 else m
|
|
|
|
|
|
2020-02-08 18:10:50 +00:00
|
|
|
def ftou16(f):
|
|
|
|
|
e = f>>12
|
|
|
|
|
if e<2:
|
|
|
|
|
return f
|
|
|
|
|
return (0x1000|f&0xfff)<<(e-1)
|
|
|
|
|
|
2023-07-06 19:22:02 +00:00
|
|
|
l1_trig = [[0,222222222],[0,222222222],[0,222222222],[0,222222222],
|
|
|
|
|
[0,222222222],[0,222222222],[0,222222222],[0,222222222]]
|
2021-07-30 17:11:19 +00:00
|
|
|
|
2013-11-06 22:48:09 +00:00
|
|
|
def thres(ch, thr=None, flags=None):
|
2017-05-24 20:16:25 +00:00
|
|
|
if flags is None:
|
2013-11-07 21:27:02 +00:00
|
|
|
flags = l1_trig[ch][0]
|
2013-11-06 22:48:09 +00:00
|
|
|
else:
|
2013-11-07 21:27:02 +00:00
|
|
|
l1_trig[ch][0] = flags
|
2017-05-24 20:16:25 +00:00
|
|
|
if thr is None:
|
2013-11-07 21:27:02 +00:00
|
|
|
thr = l1_trig[ch][1]
|
2013-11-06 22:48:09 +00:00
|
|
|
else:
|
2013-11-07 21:27:02 +00:00
|
|
|
l1_trig[ch][1] = thr
|
2013-11-08 15:18:13 +00:00
|
|
|
trigconf(ch, (flags<<18)|i2f(int(thr)))
|
2013-11-06 22:48:09 +00:00
|
|
|
|
2023-07-06 19:22:02 +00:00
|
|
|
NL1 = 4
|
|
|
|
|
def test_NL1():
|
2025-02-06 22:16:52 +00:00
|
|
|
global NL1
|
2023-07-06 19:22:02 +00:00
|
|
|
for i in range(0x100,0x180):
|
|
|
|
|
reg(i,0x1111)
|
|
|
|
|
sync(0x8044)
|
|
|
|
|
r = [sync(0x8001) for i in range(50)]
|
|
|
|
|
if r[48]==0x1111:
|
|
|
|
|
NL1=8
|
|
|
|
|
elif r[40]==0x1111:
|
|
|
|
|
NL1=4
|
|
|
|
|
else:
|
|
|
|
|
raise ValueError(f"cannot find NL1 from {repr(r)}")
|
|
|
|
|
return NL1
|
|
|
|
|
|
2017-05-28 23:04:11 +00:00
|
|
|
def l2trig(i, all=0, none=0, any=0, mask=0xf):
|
2023-07-06 19:22:02 +00:00
|
|
|
trigconf(2*i+NL1, (all<<20)|(none<<10)|any)
|
|
|
|
|
trigconf(2*i+NL1+1, mask)
|
2013-11-06 22:48:09 +00:00
|
|
|
|
|
|
|
|
def adcmask(m=0xf):
|
|
|
|
|
return reg(CORE_ADDR, m)
|
2020-02-13 13:32:49 +00:00
|
|
|
def age(agemin=2, agetmin=3, agetmax=4, agemax=5):
|
|
|
|
|
return reg(CORE_ADDR+2, (agemin<<12)|(agetmin<<8)|(agetmax<<4)|agemax)
|
2013-11-06 22:48:09 +00:00
|
|
|
def nsamples(n=0, t=0xff):
|
2013-11-07 21:27:02 +00:00
|
|
|
return reg(CORE_ADDR+3, (t<<8)|n)
|
2013-11-06 22:48:09 +00:00
|
|
|
|
|
|
|
|
p22=[
|
2014-06-24 15:10:51 +00:00
|
|
|
(36, 1264, -3708),
|
2013-11-06 22:48:09 +00:00
|
|
|
( 1, 1713, -3708),
|
|
|
|
|
( 5, 3369, 0),
|
|
|
|
|
( 6, 3642, 0),
|
|
|
|
|
( 7, 3798, 0),
|
|
|
|
|
( 8, 3798, 0),
|
|
|
|
|
( 9, 3583, 0),
|
|
|
|
|
(10, 3096, 0),
|
|
|
|
|
(12, 992, 3321),
|
|
|
|
|
(13, -685, 4095),
|
|
|
|
|
(17, -4095, 0),
|
|
|
|
|
(18, -4095, 0),
|
|
|
|
|
(19, -4095, 0),
|
|
|
|
|
(20, -4095, 0),
|
|
|
|
|
(21, -4095, 0),
|
|
|
|
|
(22, -4095, 0),
|
|
|
|
|
]
|
|
|
|
|
p1=[
|
|
|
|
|
(20, -670, -851),
|
|
|
|
|
( 1, -303, -1070),
|
|
|
|
|
( 2, 158, -1153),
|
|
|
|
|
( 3, 656, -1263),
|
|
|
|
|
( 4, 1200, -1208),
|
|
|
|
|
( 5, 1721, -987),
|
|
|
|
|
( 6, 2147, -411),
|
|
|
|
|
( 7, 2325, 339),
|
|
|
|
|
( 8, 2123, 1337),
|
|
|
|
|
( 9, 1330, 2454),
|
|
|
|
|
(10, -128, 2813),
|
|
|
|
|
(12, -2114, 0),
|
|
|
|
|
(13, -2114, 0),
|
|
|
|
|
(14, -2114, 0),
|
|
|
|
|
(15, -2114, 0),
|
|
|
|
|
(16, -2103, 0),
|
|
|
|
|
]
|
|
|
|
|
|
2017-05-17 07:38:01 +00:00
|
|
|
mV=14000.0
|
2021-07-30 17:11:19 +00:00
|
|
|
|
|
|
|
|
class configuration(object):
|
2023-07-06 19:22:02 +00:00
|
|
|
rbf = "rpirena.rbf"
|
2025-02-03 15:05:15 +00:00
|
|
|
coretemp = "/sys/class/hwmon/hwmon0/temp1_input"
|
2025-02-04 14:35:10 +00:00
|
|
|
Vref = 3.300
|
2025-03-18 12:17:24 +00:00
|
|
|
monitor = ("decent", "Vprim", "Tfpga", "Tsleep", "altera", "halt", "reboot")
|
2025-02-03 15:05:15 +00:00
|
|
|
|
2021-07-30 17:11:19 +00:00
|
|
|
def __init__(self,
|
2021-08-01 13:52:26 +00:00
|
|
|
name,
|
2021-07-30 17:11:19 +00:00
|
|
|
channels=0xf,
|
2021-08-01 13:52:26 +00:00
|
|
|
l1=[dict(thr=100*mV, flags=0x001)]*4,
|
|
|
|
|
l2=[dict(any=0x001, mask=0xf)]+[{}]*7,
|
2021-07-30 17:11:19 +00:00
|
|
|
filter=p22,
|
|
|
|
|
age=(),
|
2025-03-18 12:17:24 +00:00
|
|
|
nsamples=(0,),
|
|
|
|
|
**stream ):
|
2021-08-01 13:52:26 +00:00
|
|
|
self.name = name
|
2021-07-30 17:11:19 +00:00
|
|
|
self.channels = channels
|
|
|
|
|
self.filter = filter
|
|
|
|
|
self.thres = thres
|
|
|
|
|
self.l1 = l1
|
|
|
|
|
self.l2 = l2
|
|
|
|
|
self.age = age
|
|
|
|
|
self.nsamples = nsamples
|
2025-02-06 22:16:52 +00:00
|
|
|
self.NL1 = 4
|
2023-07-06 19:22:02 +00:00
|
|
|
if len(self.l1) == 8:
|
|
|
|
|
self.NL1 = 8
|
|
|
|
|
self.rbf = "rpirena_t8.rbf"
|
2025-03-18 12:17:24 +00:00
|
|
|
self.stream = dict(
|
|
|
|
|
i2c = False,
|
|
|
|
|
ttys = [],
|
|
|
|
|
pressure = 1,
|
|
|
|
|
hk = True,
|
|
|
|
|
counter = True
|
|
|
|
|
)
|
2026-06-03 12:56:04 +00:00
|
|
|
self.NTC=[dict()]*8
|
2025-03-18 12:17:24 +00:00
|
|
|
self.stream.update(stream)
|
2025-01-24 09:14:31 +00:00
|
|
|
self.iniz()
|
|
|
|
|
|
|
|
|
|
def iniz(self):
|
|
|
|
|
pass
|
|
|
|
|
def load(self):
|
|
|
|
|
pass
|
2023-07-06 19:22:02 +00:00
|
|
|
|
2025-02-03 15:05:15 +00:00
|
|
|
def load_i2c(self):
|
2025-03-16 15:57:28 +00:00
|
|
|
global i2c, I2C, ACC, MAG
|
2025-02-03 15:05:15 +00:00
|
|
|
import i2c, altera_ctrl
|
2025-03-16 15:57:28 +00:00
|
|
|
i2c.i2c.verbosity = 2
|
2025-02-03 15:05:15 +00:00
|
|
|
I2C = i2c.i2c()
|
|
|
|
|
ACC = i2c.ACC()
|
|
|
|
|
MAG = i2c.MAG()
|
|
|
|
|
i2c._connect(altera_ctrl)
|
2025-03-18 12:17:24 +00:00
|
|
|
for s in (MAG, ACC):
|
2025-03-27 15:25:05 +00:00
|
|
|
for retry in range(100):
|
|
|
|
|
try:
|
2025-03-18 12:17:24 +00:00
|
|
|
s.conf()
|
2025-03-27 15:25:05 +00:00
|
|
|
sleep(0.1)
|
2025-03-18 12:17:24 +00:00
|
|
|
s.who()
|
2025-03-27 15:25:05 +00:00
|
|
|
if not s.verify():
|
|
|
|
|
break
|
|
|
|
|
except Exception as e:
|
|
|
|
|
reg(7, 0x11f0)
|
|
|
|
|
print(s.name, repr(e), file=sys.stderr)
|
2025-02-03 15:05:15 +00:00
|
|
|
I2C.flight_seq(a=0x40)
|
|
|
|
|
|
2021-07-30 17:11:19 +00:00
|
|
|
def __call__(self):
|
|
|
|
|
adcmask(self.channels)
|
|
|
|
|
age(*self.age)
|
|
|
|
|
nsamples(*self.nsamples)
|
|
|
|
|
for ch in range(4):
|
|
|
|
|
filter(ch, self.filter)
|
2025-02-06 22:16:52 +00:00
|
|
|
for ch in range(self.NL1):
|
2021-07-30 17:11:19 +00:00
|
|
|
thres(ch, **self.l1[ch])
|
|
|
|
|
for tr in range(8):
|
|
|
|
|
l2trig(tr, **self.l2[tr])
|
2025-03-18 12:17:24 +00:00
|
|
|
if self.stream["i2c"]:
|
2025-02-03 15:05:15 +00:00
|
|
|
self.load_i2c()
|
2025-01-24 09:14:31 +00:00
|
|
|
self.load()
|
2025-03-18 12:17:24 +00:00
|
|
|
monitor_flags.update(self.monitor)
|
2025-02-06 22:16:52 +00:00
|
|
|
|
2025-02-03 15:05:15 +00:00
|
|
|
threediodes = configuration("3Diodes",
|
2021-07-30 17:11:19 +00:00
|
|
|
channels = 0xd,
|
|
|
|
|
l1 = [
|
2025-02-06 21:44:47 +00:00
|
|
|
dict(thr= 10.0*mV, flags=0b1000000001), # A
|
|
|
|
|
dict(thr= 100*mV, flags=0), # (NTC)
|
|
|
|
|
dict(thr= 10.0*mV, flags=0b1000000010), # B
|
|
|
|
|
dict(thr= 10.0*mV, flags=0b1000000100), # C
|
|
|
|
|
|
|
|
|
|
dict(thr= 6*mV, flags=0b0000001000), # A
|
|
|
|
|
dict(thr= 100*mV, flags=0), # NTC
|
|
|
|
|
dict(thr= 6*mV, flags=0b0000010000), # B
|
|
|
|
|
dict(thr= 6*mV, flags=0b0000100000), # C
|
2021-07-30 17:11:19 +00:00
|
|
|
],
|
|
|
|
|
l2 = [
|
2025-02-06 21:44:47 +00:00
|
|
|
dict(any=0b0000000001, none=0b00110000, mask=0xd), # A¬B¬C
|
|
|
|
|
dict(any=0b0000000010, none=0b00101000, mask=0xd), # B¬A¬C
|
|
|
|
|
dict(any=0b0000000100, none=0b00011000, mask=0xd), # C¬A¬B
|
|
|
|
|
dict(any=0b0000011000, none=0b00100000, mask=0xd), # AB¬C
|
|
|
|
|
dict(any=0b0000101000, none=0b00010000, mask=0xd), # AC¬B
|
|
|
|
|
dict(any=0b0000111000, mask=0xd), # ABC
|
|
|
|
|
dict(any=0b0000110000, none=0b00001000, mask=0xd), # BC¬A
|
|
|
|
|
dict(any=0b1000000000, mask=0xd), # AvBvC
|
2025-03-18 12:17:24 +00:00
|
|
|
],
|
|
|
|
|
i2c = True,
|
|
|
|
|
ttys = ["/dev/ttyAMA0"],
|
|
|
|
|
pressure = 3
|
2021-07-30 17:11:19 +00:00
|
|
|
)
|
|
|
|
|
|
2021-08-01 13:52:26 +00:00
|
|
|
tanos_jr = configuration("TANOS",
|
2021-07-30 17:11:19 +00:00
|
|
|
l1 = [
|
2026-06-03 12:56:04 +00:00
|
|
|
dict(thr= 9.0*mV, flags=0b0100000001), # B2
|
|
|
|
|
dict(thr= 12.0*mV, flags=0b1000000010), # CC
|
|
|
|
|
dict(thr= 12.0*mV, flags=0b1000000100), # AA
|
|
|
|
|
dict(thr= 10.0*mV, flags=0b0100001000), # B1
|
|
|
|
|
dict(thr= 7.0*mV, flags=0b0000010000), # B2
|
2026-05-18 12:48:57 +00:00
|
|
|
dict(thr= 10.0*mV, flags=0b0000100000), # CC
|
|
|
|
|
dict(thr= 10.0*mV, flags=0b0001000000), # AA
|
|
|
|
|
dict(thr= 8.0*mV, flags=0b0010000000), # B1
|
2021-07-30 17:11:19 +00:00
|
|
|
],
|
|
|
|
|
l2 = [
|
2026-05-18 12:48:57 +00:00
|
|
|
dict(any=0b0011100000), # B1 & AA & CC
|
2026-06-03 12:56:04 +00:00
|
|
|
dict(any=0b0000001000, none=0b0001110000), # B1 & ~(others)
|
|
|
|
|
dict(any=0b0100000000), # B1 | B2
|
2021-07-30 17:11:19 +00:00
|
|
|
dict(any=0b0000000010), # CC
|
|
|
|
|
dict(any=0b0000000100), # AA
|
2026-06-03 12:56:04 +00:00
|
|
|
dict(any=0b1000000000, none=0b0010010000 ), # (AA|CC) & ~B1 & ~B2
|
2026-05-18 12:48:57 +00:00
|
|
|
dict(any=0b0001100000), # AA & CC
|
|
|
|
|
dict(any=0b0010010000), # B1 & B2
|
2021-07-30 17:11:19 +00:00
|
|
|
],
|
|
|
|
|
)
|
2026-05-18 12:48:57 +00:00
|
|
|
tanos_jr.Vref = 3.337
|
2026-06-03 12:56:04 +00:00
|
|
|
tanos_jr.NTC[4] = dict(R25=10e3)
|
2021-07-30 17:11:19 +00:00
|
|
|
|
2021-08-01 13:52:26 +00:00
|
|
|
mddm = configuration("MDDM",
|
2021-07-30 17:11:19 +00:00
|
|
|
nsamples=(1,),
|
|
|
|
|
l1 = [
|
|
|
|
|
dict(thr=6*mV, flags=0b0100000001),
|
|
|
|
|
dict(thr=6*mV, flags=0b1000000010),
|
|
|
|
|
dict(thr=6*mV, flags=0b1000000100),
|
|
|
|
|
dict(thr=6*mV, flags=0b0100001000),
|
|
|
|
|
],
|
|
|
|
|
l2 = [
|
|
|
|
|
dict(any=0b1100000000),
|
|
|
|
|
dict(any=0b0000001001),
|
|
|
|
|
dict(any=0b0000000001),
|
|
|
|
|
dict(any=0b0000000010),
|
|
|
|
|
dict(any=0b0000000100),
|
|
|
|
|
dict(any=0b0000001000),
|
|
|
|
|
dict(any=0b0100000010),
|
|
|
|
|
dict(any=0b0100000100),
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
|
2025-02-11 20:20:12 +00:00
|
|
|
chaostest = configuration("CSRTEST",
|
|
|
|
|
nsamples=(48,0xff),
|
|
|
|
|
l1 = [
|
|
|
|
|
dict(thr=74*mV, flags=0b1000000001), # AA (H)
|
|
|
|
|
dict(thr=79*mV, flags=0b1000000010), # CC (H)
|
|
|
|
|
dict(thr=74*mV, flags=0b0100000100), # B1 (H)
|
|
|
|
|
dict(thr=74*mV, flags=0b0100001000), # B2 (H)
|
|
|
|
|
dict(thr=73*mV, flags=0b0000010000), # AA (L)
|
|
|
|
|
dict(thr=70*mV, flags=0b0000100000), # CC (L)
|
|
|
|
|
dict(thr=73*mV, flags=0b0001000000), # B1 (L)
|
|
|
|
|
dict(thr=73*mV, flags=0b0010000000), # B2 (L)
|
|
|
|
|
],
|
|
|
|
|
l2 = [
|
|
|
|
|
dict(any=0b0000010000, none=0b0000000001), # AA
|
|
|
|
|
dict(any=0b0000100000, none=0b0000000010), # CC
|
|
|
|
|
dict(any=0b0001000000, none=0b0000000100), # B1
|
|
|
|
|
dict(any=0b0010000000, none=0b0000001000), # B2
|
|
|
|
|
dict(any=1, none=1), #
|
|
|
|
|
dict(any=1, none=1), #
|
|
|
|
|
dict(any=1, none=1), #
|
|
|
|
|
dict(any=1, none=1), #
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
|
2023-07-06 19:22:02 +00:00
|
|
|
chaos = configuration("CHAOS",
|
|
|
|
|
nsamples=(1,),
|
|
|
|
|
l1 = [
|
2025-02-11 20:20:12 +00:00
|
|
|
dict(thr=7*mV, flags=0b1000000001), # AA (H)
|
|
|
|
|
dict(thr=7*mV, flags=0b1000000010), # CC (H)
|
|
|
|
|
dict(thr=7*mV, flags=0b0100000100), # B1 (H)
|
|
|
|
|
dict(thr=7*mV, flags=0b0100001000), # B2 (H)
|
|
|
|
|
dict(thr=9*mV, flags=0b0000010000), # AA (L)
|
|
|
|
|
dict(thr=9*mV, flags=0b0000100000), # CC (L)
|
|
|
|
|
dict(thr=9*mV, flags=0b0001000000), # B1 (L)
|
|
|
|
|
dict(thr=9*mV, flags=0b0010000000), # B2 (L)
|
2023-07-06 19:22:02 +00:00
|
|
|
],
|
|
|
|
|
l2 = [
|
|
|
|
|
dict(any=0b0011110000), # AA B1 B2 CC (L)
|
|
|
|
|
dict(any=0b0011000000), # B1 B2 (L)
|
|
|
|
|
dict(any=0b0000000001), # AA (H)
|
|
|
|
|
dict(any=0b0000000010), # CC (H)
|
|
|
|
|
dict(any=0b0000000100), # B1 (H)
|
|
|
|
|
dict(any=0b0000001000), # B2 (H)
|
|
|
|
|
dict(any=0b0000000011), # AA CC (H)
|
|
|
|
|
dict(any=0b0000001100), # B1 B2 (H)
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
|
2021-09-17 08:35:19 +00:00
|
|
|
µMustang = configuration("µM",
|
|
|
|
|
l1 = [
|
|
|
|
|
dict(thr=10*mV, flags=0b0000010001),
|
|
|
|
|
dict(thr=10*mV, flags=0b0000010010),
|
|
|
|
|
dict(thr=10*mV, flags=0b0000100100),
|
|
|
|
|
dict(thr=10*mV, flags=0b0000101000),
|
|
|
|
|
],
|
|
|
|
|
l2= [
|
|
|
|
|
dict(any=0b0000010000),
|
2023-07-28 19:01:51 +00:00
|
|
|
dict(any=0b0000100001),
|
2021-09-17 08:35:19 +00:00
|
|
|
dict(any=0b0000000011),
|
|
|
|
|
dict(any=0b0000001100),
|
|
|
|
|
dict(any=0b0000110000),
|
|
|
|
|
dict(all=0b0000001111),
|
|
|
|
|
dict(any=0b0000100011),
|
|
|
|
|
dict(any=0b0000011100),
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
|
2021-08-01 13:52:26 +00:00
|
|
|
default = configuration("default")
|
2025-02-03 15:05:15 +00:00
|
|
|
current = None
|
2021-07-30 17:11:19 +00:00
|
|
|
|
|
|
|
|
def boot(conf=default):
|
2025-02-03 15:05:15 +00:00
|
|
|
global current
|
|
|
|
|
current = None
|
2021-07-30 17:11:19 +00:00
|
|
|
print("Booting altera", file=sys.stderr)
|
2023-07-06 19:22:02 +00:00
|
|
|
altera_from_file(fn=conf.rbf)
|
|
|
|
|
global NL1
|
|
|
|
|
if conf.NL1:
|
|
|
|
|
NL1 = conf.NL1
|
|
|
|
|
else:
|
2025-01-16 11:22:39 +00:00
|
|
|
NL1 = test_NL1()
|
2023-07-06 19:22:02 +00:00
|
|
|
print(f"Number of L1 triggers {NL1}", file=sys.stderr)
|
|
|
|
|
print(f"Configure {conf.name}", file=sys.stderr)
|
2021-07-30 17:11:19 +00:00
|
|
|
conf()
|
2025-02-03 15:05:15 +00:00
|
|
|
current = conf
|
2021-07-30 17:11:19 +00:00
|
|
|
print("Reading irena configuration from FPGA", file=sys.stderr)
|
2018-07-17 15:35:29 +00:00
|
|
|
printtrig()
|
2023-07-06 19:22:02 +00:00
|
|
|
|
2013-11-08 23:07:46 +00:00
|
|
|
def readrecordcmd(a, n, w=0):
|
|
|
|
|
return struct.pack(">%dH"%(n+2+w), *( (a,)+(0,)*w+(0x8001,)*n+(0,) ))
|
|
|
|
|
|
2017-05-25 21:47:44 +00:00
|
|
|
def readrecord(a, n, w=0, cmd=None):
|
|
|
|
|
if cmd is None:
|
|
|
|
|
cmd = readrecordcmd(a, n, w)
|
|
|
|
|
return struct.unpack(">%dH"%n, spidev.sync_transfer(cmd=cmd, rsize=2*n))
|
2013-11-06 22:48:09 +00:00
|
|
|
|
2018-07-17 15:35:29 +00:00
|
|
|
def degC(hk, R1=3.3e3, R25=3.3e3, B25=4500):
|
|
|
|
|
"adc to °C, ERT-J1VT332J: 3.3kΩ, β=4500K"
|
2017-05-17 07:38:01 +00:00
|
|
|
from math import log
|
|
|
|
|
R = R1*hk/(4096-hk)
|
2017-05-28 23:04:11 +00:00
|
|
|
if R:
|
|
|
|
|
NTC = B25/(log(R/R25)+B25/298.0)
|
|
|
|
|
else:
|
|
|
|
|
NTC = 999
|
2017-05-17 07:38:01 +00:00
|
|
|
return NTC - 273
|
|
|
|
|
|
2020-02-13 15:28:28 +00:00
|
|
|
read_hk_cmd = readrecordcmd(0x8030, 8,16)
|
|
|
|
|
read_hk_pressure0_cmd = struct.pack(">3H", 0xc007, 0x0120, 0x837f) + read_hk_cmd
|
|
|
|
|
read_hk_pressure1_cmd = struct.pack(">3H", 0xc007, 0x0120, 0x83ff) + read_hk_cmd
|
|
|
|
|
read_hk_counter_cmd = struct.pack(">3H", 0xc007, 0x0120, 0x824f) + read_hk_cmd
|
2025-02-03 15:05:15 +00:00
|
|
|
read_i2c_cmd = struct.pack(">4H", 0xc007, 0x0120, 0xc032, 0x8d40)
|
2017-05-25 21:47:44 +00:00
|
|
|
|
2017-05-28 23:04:11 +00:00
|
|
|
def read_hk(cmd=read_hk_cmd):
|
|
|
|
|
return [(i>>12, i & 0xfff) for i in readrecord(0x8030, 8,4, cmd=cmd)]
|
|
|
|
|
|
2018-07-17 15:35:29 +00:00
|
|
|
# etsolopi3: Vref=3.337V
|
|
|
|
|
|
2025-02-04 14:35:10 +00:00
|
|
|
def HK(hk=None, **kk):
|
|
|
|
|
Vref = current.Vref
|
2018-07-17 15:35:29 +00:00
|
|
|
if not hk:
|
|
|
|
|
hk = read_hk(**kk)
|
2017-05-17 07:38:01 +00:00
|
|
|
sys.stderr.write("""HK
|
|
|
|
|
Vcore = %.3fV
|
|
|
|
|
Vcc = %.3fV
|
|
|
|
|
Vio = %.3fV
|
|
|
|
|
Vrpi = %.3fV
|
|
|
|
|
T = %.1f°C
|
2018-07-17 15:35:29 +00:00
|
|
|
HK1 = %.3fV %.1f°C
|
|
|
|
|
HK2 = %.3fV %.1f°C
|
2017-05-17 07:38:01 +00:00
|
|
|
Ibias = %.1fnA
|
|
|
|
|
""" % (
|
2018-07-17 15:35:29 +00:00
|
|
|
hk[0][1]*Vref/4096,
|
|
|
|
|
hk[1][1]*Vref*3/4096,
|
|
|
|
|
hk[2][1]*Vref*2/4096,
|
|
|
|
|
hk[3][1]*Vref*2/4096,
|
2017-05-28 23:04:11 +00:00
|
|
|
degC(hk[4][1]),
|
2023-07-06 19:22:02 +00:00
|
|
|
hk[5][1]*Vref/4096, degC(hk[5][1]),
|
2018-07-17 15:35:29 +00:00
|
|
|
hk[6][1]*Vref/4096, degC(hk[6][1]),
|
|
|
|
|
hk[7][1]*Vref/3.3*0.077,
|
2017-05-17 07:38:01 +00:00
|
|
|
))
|
|
|
|
|
return hk
|
2013-11-08 08:50:57 +00:00
|
|
|
|
2017-05-28 23:04:11 +00:00
|
|
|
def read_pressure(unit=0):
|
|
|
|
|
reg(0x37f| (0x80 if unit else 0))
|
2020-02-13 15:28:28 +00:00
|
|
|
sleep(0.5)
|
2017-05-28 23:04:11 +00:00
|
|
|
p = readrecord(0x8015, 8)
|
|
|
|
|
return p
|
|
|
|
|
|
2020-02-08 18:10:50 +00:00
|
|
|
def read_counter(clear=True, size=3):
|
|
|
|
|
reg(0x248 | size&3 | (4 if clear else 0))
|
|
|
|
|
return readrecord(0x8015, [9,16,29,16][size&3])
|
|
|
|
|
|
2017-05-28 23:04:11 +00:00
|
|
|
def pressure_calibrate(p):
|
|
|
|
|
Word = p[1:]
|
|
|
|
|
D = Word[4:]
|
|
|
|
|
|
|
|
|
|
C=[0]*7
|
|
|
|
|
C[1] = Word[1] >> 1
|
|
|
|
|
C[2] = ((Word[3] & 0x3f)<<6) | (Word[4] & 0x3f)
|
|
|
|
|
C[3] = Word[4]>>6
|
|
|
|
|
C[4] = Word[3]>>6
|
|
|
|
|
C[5] = ((Word[1] & 1)<<10) | (Word[2]>>6)
|
|
|
|
|
C[6] = Word[2] & 0x3f
|
|
|
|
|
|
|
|
|
|
UT1 = 8*C[5]+20224
|
|
|
|
|
dT = D[2] - UT1
|
|
|
|
|
TEMP = 200 + dT*(C[6]+50)/1024
|
|
|
|
|
|
|
|
|
|
OFF = C[2]*4 + ((C[4]-512)*dT)/4096
|
|
|
|
|
SENS = C[1] + (C[3]*dT)/1024 + 24576
|
|
|
|
|
X = (SENS * (D[1]-7168))/16384 - OFF
|
|
|
|
|
P = X*10/32 + 2500
|
|
|
|
|
|
|
|
|
|
return (TEMP*0.1,P*0.1)
|
|
|
|
|
|
2017-07-03 17:00:53 +00:00
|
|
|
EN_EVENTS = 1
|
|
|
|
|
EN_CLOCK = 8
|
|
|
|
|
EN_TxD = 2
|
|
|
|
|
EN_RxD = 4
|
|
|
|
|
|
|
|
|
|
def enable(on=True, what=EN_EVENTS | EN_CLOCK):
|
2017-05-19 18:35:47 +00:00
|
|
|
if on:
|
2017-07-03 17:00:53 +00:00
|
|
|
reg(10, what)
|
2017-05-19 18:35:47 +00:00
|
|
|
else:
|
2017-07-03 17:00:53 +00:00
|
|
|
reg(9, what)
|
|
|
|
|
|
|
|
|
|
def sel_RxD(pin=None):
|
|
|
|
|
if pin is None:
|
|
|
|
|
enable(False, EN_RxD)
|
|
|
|
|
else:
|
|
|
|
|
enable(False, (~pin & 3) << 14)
|
|
|
|
|
enable(True, EN_RxD | ((pin & 3) << 14))
|
|
|
|
|
|
|
|
|
|
def sel_TxD(pin=None):
|
|
|
|
|
if pin is None:
|
|
|
|
|
enable(False, EN_TxD)
|
|
|
|
|
else:
|
|
|
|
|
enable(False, (~pin & 3) << 12)
|
|
|
|
|
enable(True, EN_TxD | ((pin & 3) << 12))
|
|
|
|
|
|
2013-11-06 22:48:09 +00:00
|
|
|
def peek(i=0):
|
2013-11-08 23:07:46 +00:00
|
|
|
return readrecord(CORE_ADDR+8+i, 4, w=2)
|
2013-11-06 22:48:09 +00:00
|
|
|
def readcounter(i=1):
|
2013-11-08 23:07:46 +00:00
|
|
|
return readrecord(CORE_ADDR+12+i, 4, w=1)
|
2013-11-06 22:48:09 +00:00
|
|
|
def readtrig():
|
2023-07-06 19:22:02 +00:00
|
|
|
n = 32+2*NL1
|
|
|
|
|
w = readrecord(CORE_ADDR+4, n)
|
|
|
|
|
ww = [(w[i+1]<<16) | w[i] for i in range(0,n,2)]
|
|
|
|
|
l1 = [(i>>18,f2i(i&0x3ffff)) for i in ww[0:NL1]]
|
|
|
|
|
l2 = [(ww[i+1], ww[i]>>20, (ww[i]>>10)&0x3ff, ww[i]&0x3ff) for i in range(NL1,n//2,2)]
|
2013-11-08 15:18:13 +00:00
|
|
|
return (l1,l2)
|
2013-11-07 21:27:02 +00:00
|
|
|
|
2018-07-17 15:35:29 +00:00
|
|
|
def printtrig(t=None, f=sys.stderr, mV=None):
|
|
|
|
|
if not t:
|
|
|
|
|
t = readtrig()
|
2023-07-06 19:22:02 +00:00
|
|
|
for c in range(NL1):
|
2018-07-17 15:35:29 +00:00
|
|
|
if mV:
|
|
|
|
|
f.write("L1 thr mask [%d]: %5.1f mV 0x%03x\n" %
|
|
|
|
|
(c, t[0][c][1]/float(mV), t[0][c][0]) )
|
|
|
|
|
else:
|
|
|
|
|
f.write("L1 thr mask [%d]: %5d 0x%03x\n" %
|
|
|
|
|
(c, t[0][c][1], t[0][c][0]) )
|
|
|
|
|
for c in range(8):
|
|
|
|
|
f.write("L2 all/none/any read [%d]: 0x%03x / 0x%03x / 0x%03x 0x%05x\n" %
|
|
|
|
|
(c, t[1][c][1], t[1][c][2], t[1][c][3], t[1][c][0]) )
|
|
|
|
|
|
2013-11-08 23:07:46 +00:00
|
|
|
def F2ATB(f):
|
|
|
|
|
A = f2i(f>>14)
|
|
|
|
|
e = (f>>27) & 15
|
|
|
|
|
B = (f>>3) & 0x3fe
|
|
|
|
|
if e>1:
|
|
|
|
|
B <<= e-1
|
|
|
|
|
if f & 0x2000:
|
|
|
|
|
B = -B
|
|
|
|
|
T = f&15
|
|
|
|
|
return (A,T,B)
|
|
|
|
|
|
2013-11-15 18:38:31 +00:00
|
|
|
class histogram(object):
|
2017-05-17 07:38:01 +00:00
|
|
|
def __init__(self, fn, mV=14000, b0=-100, n=4000, m=4, resV=0.838214):
|
2013-11-15 18:38:31 +00:00
|
|
|
self.mV=mV
|
2017-05-17 07:38:01 +00:00
|
|
|
self.b0=b0/resV
|
|
|
|
|
self.res=mV*resV
|
2013-11-15 18:38:31 +00:00
|
|
|
self.b=[[0]*n for i in range(m)]
|
|
|
|
|
self.fn = fn
|
|
|
|
|
self.fmt = "%d"+" %d"*m+"\n"
|
|
|
|
|
def __iadd__(self, x):
|
|
|
|
|
for i,xx in enumerate(x):
|
2017-05-17 07:38:01 +00:00
|
|
|
bb = int(xx/self.res - self.b0 - 0.333)
|
2013-11-15 18:38:31 +00:00
|
|
|
if bb<0:
|
|
|
|
|
bb=0
|
|
|
|
|
if bb>=len(self.b[i]):
|
|
|
|
|
bb = len(self.b[i])-1
|
|
|
|
|
self.b[i][bb] += 1
|
|
|
|
|
return self
|
|
|
|
|
def save(self):
|
|
|
|
|
if not self.fn:
|
|
|
|
|
return
|
2013-12-04 21:45:36 +00:00
|
|
|
f = open(self.fn+"+", "w")
|
2017-05-19 18:35:47 +00:00
|
|
|
resV=self.res/self.mV
|
2013-11-15 18:38:31 +00:00
|
|
|
for i in range(len(self.b[0])):
|
2017-05-24 20:16:25 +00:00
|
|
|
f.write(self.fmt % (((i+self.b0+0.167)*resV,)+tuple([b[i] for b in self.b])))
|
2013-11-15 18:38:31 +00:00
|
|
|
f.close()
|
2013-12-04 21:45:36 +00:00
|
|
|
os.rename(self.fn+"+", self.fn)
|
2013-11-15 18:38:31 +00:00
|
|
|
|
2017-06-10 18:56:28 +00:00
|
|
|
from time import time, sleep
|
2017-05-24 20:16:25 +00:00
|
|
|
|
2017-06-01 20:39:49 +00:00
|
|
|
monitor_pressure = []
|
|
|
|
|
monitor_hk = []
|
|
|
|
|
monitor_flags = set()
|
|
|
|
|
monitor_assent = 0
|
2018-07-17 20:17:12 +00:00
|
|
|
monitor_assent_pressure = 500
|
2017-06-01 20:39:49 +00:00
|
|
|
monitor_decent = 0
|
2018-07-17 20:17:12 +00:00
|
|
|
monitor_decent_pressure = 800
|
2017-06-01 20:39:49 +00:00
|
|
|
monitor_Tfpga = 0
|
2018-07-17 20:17:12 +00:00
|
|
|
monitor_Tfpga_temp_sleep = 70
|
|
|
|
|
monitor_Tfpga_temp_shutdown = 75
|
2017-06-01 20:39:49 +00:00
|
|
|
monitor_Vprim = 0
|
2025-03-27 15:25:05 +00:00
|
|
|
monitor_Vprim_Voltage = 4.2
|
2018-07-17 20:17:12 +00:00
|
|
|
monitor_Tsleep = 0
|
|
|
|
|
monitor_Tsleep_duration = 600
|
2017-06-01 20:39:49 +00:00
|
|
|
|
|
|
|
|
def shutdown():
|
|
|
|
|
if "altera" in monitor_flags:
|
|
|
|
|
altera_reset()
|
|
|
|
|
if "halt" in monitor_flags:
|
|
|
|
|
os.system("sudo shutdown -h now")
|
2017-06-10 18:56:28 +00:00
|
|
|
sleep(600)
|
|
|
|
|
sys.exit()
|
2017-06-01 20:39:49 +00:00
|
|
|
|
2018-07-17 15:35:29 +00:00
|
|
|
def reboot():
|
2018-07-17 20:17:12 +00:00
|
|
|
altera_reset()
|
2025-02-06 22:16:52 +00:00
|
|
|
boot(current)
|
2018-07-17 20:17:12 +00:00
|
|
|
reg(7, 0x1f0)
|
2025-03-18 12:17:24 +00:00
|
|
|
enable() # TODO tty bits
|
2017-06-01 20:39:49 +00:00
|
|
|
|
|
|
|
|
def monitor():
|
2025-02-06 22:16:52 +00:00
|
|
|
if "decent" in monitor_flags and monitor_pressure:
|
|
|
|
|
p = pressure_calibrate(monitor_pressure[-1])[1]
|
2025-03-27 15:25:05 +00:00
|
|
|
global monitor_assent, monitor_decent
|
|
|
|
|
print(f"p {p:.1f} mbar"
|
|
|
|
|
f" ({monitor_assent_pressure:.1f}: {monitor_assent})"
|
|
|
|
|
f" ({monitor_decent_pressure:.1f}: {monitor_decent})",
|
|
|
|
|
file=sys.stderr)
|
2025-02-06 22:16:52 +00:00
|
|
|
if p < monitor_assent_pressure:
|
|
|
|
|
monitor_assent += 1
|
|
|
|
|
if monitor_assent > 10 and p > monitor_decent_pressure:
|
|
|
|
|
monitor_decent += 1
|
|
|
|
|
if monitor_decent > 3:
|
|
|
|
|
shutdown()
|
2017-06-01 20:39:49 +00:00
|
|
|
if "Vprim" in monitor_flags and monitor_hk:
|
|
|
|
|
hk = monitor_hk[-1]
|
2017-06-10 18:56:28 +00:00
|
|
|
Vprim = hk[3]*6.6/4096
|
2017-06-01 20:39:49 +00:00
|
|
|
global monitor_Vprim
|
2025-03-27 15:25:05 +00:00
|
|
|
print(f"V_prim {Vprim:.3f} V ({monitor_Vprim_Voltage:.3f}, {monitor_Vprim})",
|
|
|
|
|
file=sys.stderr)
|
2018-07-17 20:17:12 +00:00
|
|
|
if Vprim < monitor_Vprim_Voltage:
|
2017-06-01 20:39:49 +00:00
|
|
|
monitor_Vprim += 1
|
|
|
|
|
if monitor_Vprim > 3:
|
|
|
|
|
shutdown()
|
|
|
|
|
else:
|
|
|
|
|
monitor_Vprim = 0;
|
|
|
|
|
if "Tfpga" in monitor_flags and monitor_hk:
|
|
|
|
|
hk = monitor_hk[-1]
|
2026-06-03 12:56:04 +00:00
|
|
|
Tfpga = degC(hk[4], **current.NTC[4])
|
2018-07-17 20:17:12 +00:00
|
|
|
global monitor_Tfpga, monitor_Tsleep
|
2025-03-27 15:25:05 +00:00
|
|
|
print(f"T_fpga {Tfpga:.1f} °C"
|
|
|
|
|
f" ({monitor_Tfpga_temp_sleep:.1f}/{monitor_Tfpga_temp_shutdown:.1f}"
|
|
|
|
|
f":{monitor_Tfpga}/{monitor_Tsleep})",
|
|
|
|
|
file=sys.stderr)
|
2018-07-17 20:17:12 +00:00
|
|
|
if Tfpga > monitor_Tfpga_temp_sleep:
|
|
|
|
|
if "Tsleep" in monitor_flags:
|
|
|
|
|
monitor_Tfpga += 1
|
|
|
|
|
if monitor_Tfpga > 3:
|
|
|
|
|
monitor_Tsleep += 1
|
|
|
|
|
if monitor_Tsleep > 3:
|
|
|
|
|
altera_reset()
|
|
|
|
|
sleep(monitor_Tsleep_duration)
|
|
|
|
|
reboot()
|
|
|
|
|
monitor_Tfpga = 0
|
|
|
|
|
if Tfpga > monitor_Tfpga_temp_shutdown:
|
|
|
|
|
monitor_Tfpga += 1
|
|
|
|
|
if monitor_Tfpga > 3:
|
|
|
|
|
shutdown()
|
2017-06-01 20:39:49 +00:00
|
|
|
else:
|
|
|
|
|
monitor_Tfpga = 0
|
|
|
|
|
|
2017-06-10 18:56:28 +00:00
|
|
|
monitor_pressure[:] = []
|
|
|
|
|
monitor_hk[:] = []
|
2017-06-01 20:39:49 +00:00
|
|
|
|
2020-02-08 18:10:50 +00:00
|
|
|
hk_good = tuple(range(0,16,2))
|
|
|
|
|
hk_index = 0
|
|
|
|
|
|
2025-03-18 12:17:24 +00:00
|
|
|
def stream_hk(f, t, cmds, i2c):
|
2020-02-08 18:10:50 +00:00
|
|
|
global hk_index
|
2025-02-04 15:07:02 +00:00
|
|
|
tf = time()
|
|
|
|
|
if tf >= t + 1:
|
|
|
|
|
tt = int(math.floor(tf))
|
|
|
|
|
ttt = tt % 60
|
2025-03-18 12:17:24 +00:00
|
|
|
if i2c and ttt & 1:
|
2025-02-03 15:05:15 +00:00
|
|
|
spidev.sync_transfer(cmd=read_i2c_cmd, rsize=0)
|
2025-02-04 15:07:02 +00:00
|
|
|
if tt % 10:
|
2025-02-03 15:05:15 +00:00
|
|
|
return tt
|
|
|
|
|
ttt //= 10
|
2020-02-08 18:10:50 +00:00
|
|
|
hk_index = ttt
|
|
|
|
|
if ttt<len(cmds):
|
|
|
|
|
cmd = cmds[ttt]
|
|
|
|
|
else:
|
|
|
|
|
cmd = read_hk_cmd
|
|
|
|
|
hk = read_hk(cmd=cmd)
|
|
|
|
|
if tuple(h[0] for h in hk) == hk_good:
|
2017-06-10 18:56:28 +00:00
|
|
|
#sys.stderr.write("T = %5.1f°C, Ibias = %.1fnA, Vprim = %.2fV\n" % (
|
|
|
|
|
# degC(hk[4][1]), hk[7][1]*0.077, hk[3][1]*6.6/4096))
|
2017-05-28 23:04:11 +00:00
|
|
|
hk = tuple(h[1] for h in hk)
|
2017-06-10 18:56:28 +00:00
|
|
|
monitor_hk.append(hk)
|
|
|
|
|
monitor()
|
2025-02-04 15:07:02 +00:00
|
|
|
f.write("H %.2f %d %d %d %d %d %d %d %d\n" % ((tf,) + hk))
|
2017-05-28 23:04:11 +00:00
|
|
|
else:
|
2025-02-06 21:44:47 +00:00
|
|
|
f.write(f"XH {tf:.2f} {repr(hk)}\n")
|
2025-02-03 15:05:15 +00:00
|
|
|
if current.coretemp:
|
2021-09-27 16:10:06 +00:00
|
|
|
try:
|
2025-02-04 15:07:02 +00:00
|
|
|
f.write(f"Y {int(open(current.coretemp).read())/1000:.1f}\n")
|
2021-09-27 16:10:06 +00:00
|
|
|
except:
|
|
|
|
|
pass
|
2017-06-10 18:56:28 +00:00
|
|
|
f.flush()
|
2025-02-03 15:05:15 +00:00
|
|
|
return tt
|
2017-05-24 20:16:25 +00:00
|
|
|
return t
|
2017-05-25 21:47:44 +00:00
|
|
|
|
|
|
|
|
read_fifo_stat_cmd = readrecordcmd(0x8005,1)
|
|
|
|
|
read_event_packet_cmd = readrecordcmd(0x8016, 14)[:-4] + read_fifo_stat_cmd
|
|
|
|
|
read_sample_packet_cmd = readrecordcmd(0x8017, 6)[:-4] + read_fifo_stat_cmd
|
2025-02-03 15:05:15 +00:00
|
|
|
read_mux_fifo_packet_head_cmd = readrecordcmd(0x8015, 1)
|
|
|
|
|
read_mux_fifo_packet_cmd = readrecordcmd(0x8015, 133)[:-4] + read_fifo_stat_cmd
|
2025-02-06 22:16:52 +00:00
|
|
|
|
|
|
|
|
def print_bate1_packet(f, pp):
|
|
|
|
|
monitor_pressure.append(pp)
|
2025-03-12 15:37:39 +00:00
|
|
|
f.write("P1 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n" % tuple(pp[2:8]))
|
2025-02-06 22:16:52 +00:00
|
|
|
|
|
|
|
|
def print_bate2_packet(f, pp):
|
2025-03-12 15:37:39 +00:00
|
|
|
f.write("P2 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n" % tuple(pp[2:8]))
|
2025-02-06 22:16:52 +00:00
|
|
|
|
|
|
|
|
def print_counter_packet(f, pp):
|
|
|
|
|
n = NL1 + 9
|
|
|
|
|
pp[1:n+1] = map(ftou16, pp[1:n+1])
|
|
|
|
|
pp[n+1] += pp[n+2] << 16
|
|
|
|
|
print("C64 3", *pp[1:n+2], file=f)
|
|
|
|
|
|
|
|
|
|
def print_counter1_packet(f, pp):
|
|
|
|
|
pp[-3] += pp[-2] << 16
|
|
|
|
|
print("C64 1", *pp[1:-2], file=f)
|
|
|
|
|
|
|
|
|
|
def print_i2c_packet(f, pp):
|
|
|
|
|
print("ID", *pp[:-1], file=f)
|
|
|
|
|
|
2025-02-04 14:37:05 +00:00
|
|
|
mux_packets = {
|
2025-03-12 15:37:39 +00:00
|
|
|
0xba7e: (8, print_bate1_packet),
|
|
|
|
|
0xbafe: (8, print_bate2_packet),
|
2025-02-06 22:16:52 +00:00
|
|
|
0xc364: (20, print_counter_packet),
|
|
|
|
|
0xc164: (20, print_counter1_packet),
|
|
|
|
|
0x12c5: (133, print_i2c_packet),
|
2025-02-04 14:37:05 +00:00
|
|
|
}
|
2017-05-25 21:47:44 +00:00
|
|
|
|
2018-07-17 15:35:29 +00:00
|
|
|
def read_fifo_stat(attempt=0):
|
|
|
|
|
status = struct.unpack(">H", spidev.sync_transfer(cmd=read_fifo_stat_cmd, rsize=2))[0]
|
|
|
|
|
if status==0xffff:
|
2018-07-17 20:17:12 +00:00
|
|
|
if attempt < 2 and "reboot" in monitor_flags:
|
2018-07-17 15:35:29 +00:00
|
|
|
reboot()
|
2018-07-17 20:17:12 +00:00
|
|
|
return read_fifo_stat(attempt+1)
|
|
|
|
|
else:
|
|
|
|
|
shutdown()
|
|
|
|
|
return 0
|
2018-07-17 15:35:29 +00:00
|
|
|
return status
|
2017-05-25 21:47:44 +00:00
|
|
|
|
2020-02-22 20:23:50 +00:00
|
|
|
notification = None
|
|
|
|
|
notification_messages = []
|
|
|
|
|
|
2025-03-18 12:17:24 +00:00
|
|
|
def stream_events(f, en, ttys=(), hk=True, pressure=1, counter=True, i2c=False):
|
2017-07-03 17:00:53 +00:00
|
|
|
|
2023-07-06 19:22:02 +00:00
|
|
|
tty_line = [b""]*len(ttys)
|
2025-02-04 14:35:10 +00:00
|
|
|
hk_cmds = [read_hk_cmd]*6
|
2020-02-08 18:10:50 +00:00
|
|
|
if counter:
|
2025-02-04 14:35:10 +00:00
|
|
|
hk_cmds = [read_hk_counter_cmd]*6
|
2020-02-08 18:10:50 +00:00
|
|
|
if pressure:
|
|
|
|
|
if pressure != 2:
|
2025-02-04 14:35:10 +00:00
|
|
|
hk_cmds[1] = read_hk_pressure0_cmd
|
|
|
|
|
if pressure == 1:
|
|
|
|
|
hk_cmds[3] = read_hk_pressure0_cmd
|
|
|
|
|
else:
|
|
|
|
|
hk_cmds[3] = read_hk_pressure1_cmd
|
|
|
|
|
hk_cmds[5] = read_hk_pressure0_cmd
|
|
|
|
|
else:
|
|
|
|
|
hk_cmds[1] = read_hk_pressure1_cmd
|
|
|
|
|
hk_cmds[3] = read_hk_pressure1_cmd
|
|
|
|
|
hk_cmds[5] = read_hk_pressure1_cmd
|
2025-03-18 12:17:24 +00:00
|
|
|
hk_t = stream_hk(f, 0, hk_cmds, i2c)
|
2013-11-08 23:07:46 +00:00
|
|
|
while True:
|
2025-03-18 12:17:24 +00:00
|
|
|
reg(11, en)
|
2025-02-03 15:05:15 +00:00
|
|
|
if hk:
|
2025-03-18 12:17:24 +00:00
|
|
|
hk_t = stream_hk(f, hk_t, hk_cmds, i2c)
|
2020-02-22 20:23:50 +00:00
|
|
|
if notification:
|
|
|
|
|
mes = notification.trigger()
|
|
|
|
|
if mes:
|
|
|
|
|
notification_messages.append(mes)
|
|
|
|
|
return mes
|
2017-07-17 20:11:02 +00:00
|
|
|
if ttys:
|
|
|
|
|
for i, tty in enumerate(ttys):
|
|
|
|
|
tl = tty.read(256)
|
|
|
|
|
if tl:
|
|
|
|
|
tty_line[i] += tl
|
2023-07-06 19:22:02 +00:00
|
|
|
eol = tty_line[i].rfind(b'\n')
|
2017-07-17 20:11:02 +00:00
|
|
|
if eol>=0:
|
2023-07-06 19:22:02 +00:00
|
|
|
f.write("TTY%d: %s\n" % (i, repr(tty_line[i][:eol+1])))
|
2017-07-17 20:11:02 +00:00
|
|
|
tty_line[i] = tty_line[i][eol+1:]
|
2021-07-24 12:30:15 +00:00
|
|
|
if len(tty_line[i])>134:
|
2023-07-28 19:01:51 +00:00
|
|
|
f.write("TTX%d: %s\n" % (i, repr(tty_line[i])))
|
2023-07-06 19:22:02 +00:00
|
|
|
tty_line[i]=b""
|
2025-02-06 22:16:52 +00:00
|
|
|
|
2025-02-03 15:05:15 +00:00
|
|
|
ne = 0
|
2025-03-18 12:17:24 +00:00
|
|
|
fifo_stat = read_fifo_stat()
|
2025-02-03 15:05:15 +00:00
|
|
|
while fifo_stat & 0x4000 and ne<64:
|
2013-11-15 18:38:31 +00:00
|
|
|
ne += 1
|
2013-11-08 23:07:46 +00:00
|
|
|
r = spidev.sync_transfer(cmd=read_event_packet_cmd, rsize=30)
|
|
|
|
|
rr = struct.unpack(">L3H2B9H", r)
|
|
|
|
|
# print >> sys.stderr, "f2stat", hex(f2s), [hex(i) for i in rr]
|
2021-07-30 17:11:19 +00:00
|
|
|
if rr[0] != 0xbeefa128:
|
2017-05-25 21:47:44 +00:00
|
|
|
f.write("XE %s\n" % " ".join(["0x%04x" % x for x in rr]))
|
|
|
|
|
reg(7, 0x140)
|
|
|
|
|
fifo_stat = read_fifo_stat()
|
|
|
|
|
break
|
2025-02-03 15:05:15 +00:00
|
|
|
fifo_stat = rr[-1]
|
2013-11-08 23:07:46 +00:00
|
|
|
f.write("EI %d 0x%08x 0x%02x %d" % (rr[5], (rr[2]<<16)|rr[1], rr[4], rr[3]))
|
|
|
|
|
j=6
|
|
|
|
|
for i in (1,2,4,8):
|
|
|
|
|
if rr[1] & i:
|
2013-11-15 18:38:31 +00:00
|
|
|
ATB=F2ATB((rr[j+1]<<16)|rr[j])
|
|
|
|
|
f.write(" %d %d %d" % ATB)
|
2013-11-08 23:07:46 +00:00
|
|
|
j+=2
|
|
|
|
|
else:
|
|
|
|
|
f.write(" 0 0 0")
|
|
|
|
|
f.write("\n")
|
2017-05-25 21:47:44 +00:00
|
|
|
|
2020-02-08 18:10:50 +00:00
|
|
|
if fifo_stat & 0x2000:
|
2025-02-04 14:37:05 +00:00
|
|
|
ph = spidev.sync_transfer(cmd=read_mux_fifo_packet_head_cmd, rsize=2)
|
|
|
|
|
pp = struct.unpack(">H", ph)
|
2025-02-03 15:05:15 +00:00
|
|
|
if pp[0] not in mux_packets:
|
|
|
|
|
f.write(f"XM 0x{pp[0]:04x}\n")
|
|
|
|
|
reg(7, 0x120)
|
|
|
|
|
fifo_stat = read_fifo_stat()
|
|
|
|
|
else:
|
2025-02-06 22:16:52 +00:00
|
|
|
ps, print_func = mux_packets[pp[0]]
|
2025-02-04 14:37:05 +00:00
|
|
|
cmd = read_mux_fifo_packet_cmd[-2*(ps+1):]
|
|
|
|
|
p = spidev.sync_transfer(cmd=cmd, rsize=2*ps)
|
|
|
|
|
pp = list(pp)
|
|
|
|
|
pp.extend(struct.unpack(f">{ps}H", p))
|
2025-02-03 15:05:15 +00:00
|
|
|
fifo_stat = pp[-1]
|
2025-02-06 22:16:52 +00:00
|
|
|
print_func(f, pp)
|
2017-05-25 21:47:44 +00:00
|
|
|
|
|
|
|
|
ns = 0
|
2025-02-03 15:05:15 +00:00
|
|
|
while fifo_stat & 0x8000 and not fifo_stat & 0x4000 and ns<64:
|
2017-05-24 20:16:25 +00:00
|
|
|
s = spidev.sync_transfer(cmd=read_sample_packet_cmd, rsize=14)
|
|
|
|
|
ss = struct.unpack(">4HLH", s)
|
2017-05-25 21:47:44 +00:00
|
|
|
if ss[0] != 0x5a61:
|
|
|
|
|
f.write("XS %s\n" % " ".join(["0x%04x" % x for x in ss]))
|
|
|
|
|
reg(7, 0x180)
|
|
|
|
|
fifo_stat = read_fifo_stat()
|
|
|
|
|
break
|
2025-02-03 15:05:15 +00:00
|
|
|
fifo_stat = ss[-1]
|
2017-05-25 21:47:44 +00:00
|
|
|
ns += 1
|
|
|
|
|
f.write("S %d %d %d %d %d\n" % (
|
|
|
|
|
ss[4],
|
|
|
|
|
ss[1]>>4,
|
|
|
|
|
((ss[1]&15)<<8)|(ss[2]>>8),
|
|
|
|
|
((ss[2]&255)<<4)|(ss[3]>>12),
|
|
|
|
|
ss[3]&0xfff))
|
|
|
|
|
|
2018-07-17 15:35:29 +00:00
|
|
|
if not (fifo_stat & 0xc000):
|
2025-02-03 15:05:15 +00:00
|
|
|
t = time()
|
|
|
|
|
if not ne or 0.9 < t % 2.0 < 1:
|
|
|
|
|
sleep(0.1 - t % 0.1)
|
|
|
|
|
elif ne < 64:
|
2018-07-17 15:35:29 +00:00
|
|
|
sleep(0.01)
|
2017-05-25 21:47:44 +00:00
|
|
|
|
2025-03-18 12:17:24 +00:00
|
|
|
def stream_file(fn):
|
|
|
|
|
conf = current
|
2013-11-08 23:07:46 +00:00
|
|
|
f = open(fn, "a")
|
2025-03-18 12:17:24 +00:00
|
|
|
for i,fn in enumerate(conf.stream["ttys"]):
|
|
|
|
|
if not isinstance(fn, str):
|
|
|
|
|
continue
|
2017-07-03 17:00:53 +00:00
|
|
|
import serial, termios
|
2025-03-18 12:17:24 +00:00
|
|
|
fn = fn.split(",")
|
|
|
|
|
baud = 4800
|
|
|
|
|
tty = 1
|
|
|
|
|
if len(fn) >= 2:
|
|
|
|
|
baud = int(fn[1])
|
|
|
|
|
if len(fn) >= 3:
|
|
|
|
|
tty = int(fn[2])
|
|
|
|
|
s = serial.Serial(fn[0], baud, timeout=0)
|
|
|
|
|
if tty >= 0:
|
|
|
|
|
sel_RxD(tty)
|
|
|
|
|
conf.stream["ttys"][i] = s
|
2013-11-08 23:07:46 +00:00
|
|
|
reg(7, 0x1f0)
|
2025-03-18 12:17:24 +00:00
|
|
|
en = reg(8) | EN_EVENTS | EN_CLOCK
|
|
|
|
|
enable(True, en)
|
2025-03-27 15:25:05 +00:00
|
|
|
print(repr(conf.stream), file=sys.stderr)
|
2025-03-18 12:17:24 +00:00
|
|
|
print(f"enable bits are {en:#04x}", file=sys.stderr)
|
2013-11-08 23:07:46 +00:00
|
|
|
while True:
|
|
|
|
|
try:
|
2025-03-18 12:17:24 +00:00
|
|
|
mes = stream_events(f, en=en, **conf.stream)
|
2020-02-22 20:23:50 +00:00
|
|
|
if mes:
|
|
|
|
|
f.close()
|
|
|
|
|
sys.stderr.write("interrupted by notification: %s\n" % repr(mes))
|
|
|
|
|
break
|
2021-07-30 17:11:19 +00:00
|
|
|
except IOError as e:
|
2013-11-08 23:07:46 +00:00
|
|
|
sys.stderr.write(repr(e)+"\n")
|
|
|
|
|
reg(7, 0x1f0)
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
f.close()
|
|
|
|
|
break
|