Compare commits

...

32 commits

Author SHA1 Message Date
Stephan I. Böttcher
05b0206105 Merge branch 'master' of forge.bexus.org:Stephan/irena-arm 2025-02-24 15:37:06 +01:00
stephan
fef4a9db28 flash_NMAHEPAM: cron with dorn HK and I²C
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9276 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-24 14:36:00 +00:00
stephan
dbf3725f04 nmahepam: aenable(), /hk1
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9275 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-24 14:34:01 +00:00
stephan
fba73eb689 dorn.py: φ⁴ banana and other fixes
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9274 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-24 14:33:00 +00:00
stephan
7c711fd1d8 AHEPAM: φ⁴ banana
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9273 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-24 14:32:02 +00:00
stephan
d623ed3885 ahepam/Makefile: %.hist use onboard E
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9272 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-24 14:31:17 +00:00
stephan
dc0e4e4a27 nmahepam_channels: add column dorn
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9271 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-24 14:30:18 +00:00
stephan
455a33a397 arm: parse_expression_square(…, optional) enhancements
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9270 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-23 23:18:16 +00:00
stephan
cec68e93b9 arm: i2c command
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9269 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-23 21:03:51 +00:00
stephan
9809041577 arm: add command dorn/
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9268 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-23 00:11:56 +00:00
stephan
2e96ff3d73 AHEMAP.awk: fixes
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9266 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-22 10:48:03 +00:00
stephan
704a7c2c78 move nmahepam_channesl.md
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9259 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-17 14:48:04 +00:00
stephan
2fc61dc128 AHEPAM.awk: nmahepam analysis
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9258 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-17 14:37:41 +00:00
stephan
e7c0fd4156 ahepamfile: option for channels per slice
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9253 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-14 21:32:24 +00:00
stephan
6bd5cd06ae NMAHEPAM/CRON: read dorn HK
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9252 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-14 21:31:03 +00:00
stephan
8d7284fc75 dorn write_l2(): fix ch address bit location.
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9251 bc5caf13-1734-44f8-af43-603852e9ee25
2025-02-14 21:25:38 +00:00
stephan
b293536817 nmahepam: hk() updates
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9233 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-28 14:43:20 +00:00
stephan
62bdcf72b7 nmahepam: bitfile
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9232 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-28 14:40:44 +00:00
ava
36a5767824 ADD list for shaper channels through all connectors
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9230 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-28 13:40:41 +00:00
ava
37e18dd984 nmahepam.py: ADD further channels to hk()
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9211 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-15 12:56:01 +00:00
stephan
f01cc2f807 nmahepam: HK channels 4.)
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9206 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-09 09:47:19 +00:00
ava
825eea0422 Add table of channels: nmahepam_channels.md
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9205 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-08 16:23:10 +00:00
stephan
ecc3dc3742 nmahepam: fixes, mv hk()
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9204 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-07 12:57:14 +00:00
ava
d41bfa309a ADD nmahepam.py as copy of nmrena.py
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9203 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-07 11:17:12 +00:00
stephan
222aad1e90 dorn.py: fixes and CONFIG rename
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9202 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-07 00:16:59 +00:00
stephan
83ac07f0ce IRENA: isCHAOS_SP()
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9201 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-07 00:12:59 +00:00
stephan
a6955e771f mainloop: print revision as hex @ boot
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9200 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-06 22:57:42 +00:00
stephan
a0f7f831cb CHAOS CRON.RC: HK schedule as in FLY
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9199 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-06 22:57:37 +00:00
stephan
9a58fdff52 .gitignore operational files
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9198 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-06 22:50:13 +00:00
stephan
3f285a00b7 dorn.py: separated out of narena.py
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9197 bc5caf13-1734-44f8-af43-603852e9ee25
2025-01-06 22:28:21 +00:00
stephan
55d797b13f rsync from hfsjg via jumphost cosray
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9185 bc5caf13-1734-44f8-af43-603852e9ee25
2024-12-23 16:49:33 +00:00
stephan
4cfc59dbe9 rsync from bern via jumphost cosray
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9184 bc5caf13-1734-44f8-af43-603852e9ee25
2024-12-23 11:35:06 +00:00
26 changed files with 879 additions and 212 deletions

5
.gitignore vendored
View file

@ -4,9 +4,12 @@ irena.bin
irena.hex
irena.rom*
revision.h
*.fat
*.fat*
__pycache__
revision.h+
*~
*.s
oops.txt
irenarc.py
irenafile
*/data

View file

@ -146,7 +146,7 @@ sources = irena mainloop parser message isr crc \
enc28j60 net udp \
expression variables display \
adc rtc hk \
plugin pressure gps chaos \
plugin pressure gps chaos dorn i2c \
nomalloc strtol uart base85
$(NAME).rom: lpc2148-rom.ld $(OBJS)

View file

@ -2,7 +2,7 @@
function isE(d,c) {
if (!/^ED/ || $3!=d || $4!=c) return 0
Ch=d*3+c
Ch = NDCh * d + c
T0 = $2
A = $7/1024
B=$8/1024
@ -14,6 +14,94 @@ function isE(d,c) {
return 1
}
function isEE() {
if (!/^ED/) return 0
d = $3
c = $4
Ch = NDCh * d + c
T0 = $2
A = $7/1024
B=$8/1024
P=$9/0x4000
Ba=$10/0x4000
E=$11/0x20000
EE=A*BANANA(d,c, P)
N = 0
return 1
}
function isCC() {
N = 0
if (!/^ED /) return 0
if (NE && ($2 > T0+20 || $2+20 < T0)) {
N = NE
TE0 = T0
save = $0
delete TT
delete AA
delete PP
delete HH
delete EE
for (i=0; i<NCh; i++) {
if (i in ELINES) {
$0 = ELINES[i]
TT[i] = $2-TE0
AA[i] = $7/1024
PP[i] = $9/0x4000
HH[i] = Phase(PP[i])
EE[i] = $11/0x20000
}
}
NE = 0
delete ELINES
$0 = save
}
if (!NE) T0 = $2
i = NDCh * $3 + $4
ELINES[i] = $0
NE++
if (N) {
if (TE0 < 0x40000000 && TLAST > 0xc0000000) EPOCH += 0x100000000
TLAST = TE0
}
return N
}
function doCC() {
printf "%.0f %d", TE0+EPOCH, N
for (i=0; i<NCh; i++)
printf " %d:%.3f:%.3f:%.2f:%.2f", \
TT[i], PP[i], HH[i], AA[i], EE[i]
printf "\n"
}
function doCCC() {
printf "%.0f %d", TE0+EPOCH, N
for (i=0; i<NCh; i++)
if (i in AA)
printf " %d:%.3f:%.3f:%.2f:%.2f", \
TT[i], PP[i], HH[i], AA[i], EE[i]
else
printf " :"
printf "\n"
}
BEGIN { CCcut = 10 }
function doCC2() {
if (N<2) return
for (i=0; i<NCh; i++)
if (EE[i]>5)
for (j=i+1; j<NCh; j++)
if (EE[j] > CCcut) {
ii = int(i/8)
jj = int(j/8)
printf "%.0f %d %d %d %d %d %d %.3f %.3f %.3f %.3f %.1f %.1f\n", \
TE0+EPOCH, i, j, ii, jj, \
TT[i], TT[j], PP[i], PP[j], HH[i], HH[j], EE[i], EE[j]
}
}
function is2D(d1, c1, d2, c2, delta) {
r = 0
delta++
@ -91,19 +179,56 @@ function isS2(d1,c1,d2,c2) {
SS2 = S2-S20
return N
}
function isS(d,c) {
if (isE(d,c)) ELINE=$0
if (!/^SD/ || $2<T0 || $2>T0+32) return 0
S = $(3+8*c+d)
T = $2
TT = T-T0 + Phase(P)
if (!N) {
T1=TT
S0 = 0
BEGIN {
doScut=10
}
function doS() {
N = 0
if (!/[SE]D /) return N
if (NS && ($2 > TS0+20 || $2 < TS0-20)) {
save = $0
for (d in ELINES) {
for (c in ELINES[d]) {
$0 = ELINES[d][c]
E = $11/0x20000
if (E <= doScut) continue
T0 = $2
A = $7/1024
B = $8/1024
P = $9/0x4000
Ba = $10/0x4000
n0 = 0
S0 = 0
for (i = T0-2; i <= T0+2; i++)
if (i in SLINES[d]) {
$0 = SLINES[d][i]
n0++;
S0 += $(4+c)
}
if (n0)
S0 /= n0
for (i in SLINES[d]) {
$0 = SLINES[d][i]
if ($2 > T0+40 || $2 < T0-20) continue
print d, c, T0, A, P, Phase(P), E, $2-T0, S0, $(4+c), ($(4+c)-S0)/E
}
N++
}
}
delete ELINES
delete SLINES
NS = 0
$0 = save
}
N++
if (N==1 || TT<3.5) S0=((N-1)*S0 + S)/N
SS = S-S0
if (/^ED/) {
ELINES[$3][$4] = $0
return N
}
if (!NS) TS0 = $2
SLINES[$3][$2] = $0
NS++
return N
}
@ -111,6 +236,16 @@ BEGIN {
ph0 = -0.535102
ph1 = 1.83084
ph2 = -0.171461
# 2025-02-14-nmahepam-l2fixed-6
ph0 = -0.51035
ph1 = 1.88779
ph2 = 0
# 2025-02-20-seth-pa1-2
ph0 = -0.505601 # ± 3.072e-05
ph1 = 1.94725 # ± 0.00051
ph2 = -0.139787 # ± 0.0009408
}
function Phase(P) {
@ -128,10 +263,14 @@ function doHIST(Ch, x) {
BEGIN {
NCh=12
for (i=0; i<NCh;i++) name[i] = substr("CBAFEDIHGLKJ",i+1,1)
for (i=0; i<NCh; i++) name[i] = substr("CBAFEDIHGLKJ",i+1,1)
minV=-100
maxV=5000
resV=0.25
# AHEPAM BGO slice 1 only:
NCh = 24
NDCh = 0
for (i=0; i<NCh; i++) name[i] = "1:" i
}
function print_HIST(fn) {
@ -153,28 +292,6 @@ function print_HIST(fn) {
END { if (haveHIST) print_HIST("/dev/stdout") }
BEGIN {
# iterated F-banana
b0 = -0.24534 # +/- 0.0009303 (0.3792%)
b2 = 0.787721 # +/- 0.004091 (0.5194%)
b3 = -0.144295 # +/- 0.02664 (18.46%)
# 2022-03-13-aha-bi207-18 LM
b0 = -0.244794 # +/- 0.001249 (0.5104%)
b2 = 0.77673 # +/- 0.005407 (0.6962%)
b3 = -0.12307 # +/- 0.03541 (28.77%)
# 2022-03-13-aha-bi207-18 K
b0 = -0.245065 # +/- 0.0006364 (0.2597%)
b2 = 0.779905 # +/- 0.002807 (0.3599%)
b3 = -0.113925 # +/- 0.01827 (16.03%)
for (d=0;d<8;d++) for (c=0;c<3;c++) {
B0[d,c] = b0
B2[d,c] = b2
B3[d,c] = b3
}
# B
B0[0,1] = -3709 / 16384
@ -192,9 +309,45 @@ BEGIN {
B0[3,2] = -3802 / 16384
B2[3,2] = 14943 / 16384
B3[3,2] = 4596 / 32768
# iterated F-banana
b0 = -0.24534 # +/- 0.0009303 (0.3792%)
b2 = 0.787721 # +/- 0.004091 (0.5194%)
b3 = -0.144295 # +/- 0.02664 (18.46%)
# 2022-03-13-aha-bi207-18 LM
b0 = -0.244794 # +/- 0.001249 (0.5104%)
b2 = 0.77673 # +/- 0.005407 (0.6962%)
b3 = -0.12307 # +/- 0.03541 (28.77%)
# 2022-03-13-aha-bi207-18 K
b0 = -0.245065 # +/- 0.0006364 (0.2597%)
b2 = 0.779905 # +/- 0.002807 (0.3599%)
b3 = -0.113925 # +/- 0.01827 (16.03%)
b4 = 0
for (d=0;d<8;d++) for (c=0;c<24;c++) {
B0[d,c] = b0
B2[d,c] = b2
B3[d,c] = b3
B4[d,c] = b4
}
# 2025-02-20-seth-pa1-4
# integer fit: -3839 /2¹⁴, 13891 /2¹⁴, 3579 /2¹⁶, 22853 /2¹⁶,
for (d=0;d<8;d++) for (c=0;c<24;c++) {
# full fit
B0[d,c] = -0.234334699085823
B2[d,c] = 0.84786326376432
B3[d,c] = 0.10845413271095
B4[d,c] = 0.696742143682933
}
}
function BANANA(d,c, p) {
p -= B0[d,c]
return 1+p*p*(B2[d,c] + p*B3[d,c])
return 1+p*p*(B2[d,c] + p*(B3[d,c] + p*B4[d,c]))
}

View file

@ -5,6 +5,9 @@ include ../irena/libirena.make
%.AHA: %.dat ahepamfile
./ahepamfile < $< > $@
%.doS: %.AHA
./AHEPAM.awk 'doS(){}' $< > $@
%.AES: %.dat ahepamfile
./ahepamfile < $< | grep '^[ES]' | grep -v 'X' | sort -nk2,2 -k1 > $@
@ -31,7 +34,7 @@ SIGMA=600
resV=1
%.hist: %.AHA
./AHEPAM.awk 'isE($$3,$$4){doHIST(Ch,EE)}' resV=$(resV) $< > $@
./AHEPAM.awk 'isEE(){doHIST(Ch,E)}' resV=$(resV) $< > $@
CUT=P
CUT_P=&&P>-0.398&&P<=-0.105

View file

@ -62,9 +62,9 @@ static inline int dorn_event(unsigned int h1, unsigned int n, int stis)
if (banana & 0x8000) banana |= 0xffff0000;
unsigned int ch = (det >> nn) & 3;
unsigned int lost = det >> (nn+2);
det &= 7;
det &= n-1;
if (stis) {
ch = ch*4 + (det & 3);
ch = (ch<<nn) | det;
det = h1 & 3;
}
printf("\nED %u %u %u %d %u %d %d %d %d %d", clock, det, ch, dtime, lost, a, b, phase, banana, pha);
@ -109,9 +109,9 @@ int main(int argc, const char * const * argv)
case 0xd1e7: x = dorn_event(h1, n_counters, 0); break;
default:
switch (h1 & 0xfffc) {
case 0x5710: x = dorn_hk(h1, 4, 1); break;
case 0x5714: x = dorn_samples(h1, 4, 1); break;
case 0x5718: x = dorn_event(h1, 4, 1); break;
case 0x5710: x = dorn_hk(h1, n_counters, 1); break;
case 0x5714: x = dorn_samples(h1, n_counters, 1); break;
case 0x5718: x = dorn_event(h1, n_counters, 1); break;
default:
if (!x || x>32) {
printf("\nX %04x", h1);

View file

@ -0,0 +1,41 @@
| | A | B | C | D | E | F | G | H
---------------------------------------------------------------------------
0 | shaper | 02 | 05 | 08 | 11 | 15 | 16 | 21 | 22
1 | shaper | 01 | 04 | 07 | 10 | 12 | 17 | 18 | 23
2 | shaper | 00 | 03 | 06 | 09 | 13 | 14 | 19 | 20
3 | monitor | Ibias | Vff | Vnn | Vpp | Vdig | NTC | Vcc | Vss
4 | monitor | EXT,NTC | NTC | Bias | REF,NTC | Bias1 | Bias2 | Vss | Vcc
5 | VrefL | | | | | | | |
6 | Vref | | | | | | | |
7 | mon[A-H] | | | | | | | |
connector | channel (PIN) | shaper | CONN1 | ADC | data | dorn
CONN10 | 1 (13) | 00 | 20 | A0 | [2][0] | 16
CONN10 | 2 (12) | 01 | 60 | A1 | [1][0] | 8
CONN10 | 3 (11) | 02 | 19 | A2 | [0][0] | 0
CONN10 | 4 (10) | 03 | 59 | B0 | [2][1] | 17
CONN10 | 5 (9) | 04 | 18 | B1 | [1][1] | 9
CONN10 | 6 (8) | 05 | 58 | B2 | [0][1] | 1
CONN10 | 7 (7) | 06 | 16 | C0 | [2][2] | 18
CONN10 | 8 (6) | 07 | 56 | C1 | [1][2] | 10
-----------------------------------------------------------------
CONN11 | 1 (13) | 08 | 18 | C2 | [0][2] | 2
CONN11 | 2 (12) | 09 | 55 | D0 | [2][3] | 19
CONN11 | 3 (11) | 10 | 14 | D1 | [1][3] | 11
CONN11 | 4 (10) | 11 | 54 | D2 | [0][3] | 3
CONN11 | 5 (9) | 12 | 52 | E1 | [1][4] | 12
CONN11 | 6 (8) | 13 | 12 | E0 | [2][4] | 20
CONN11 | 7 (7) | 14 | 51 | F0 | [2][5] | 21
CONN11 | 8 (6) | 15 | 11 | E2 | [0][4] | 4
-----------------------------------------------------------------
CONN12 | 1 (13) | 16 | 50 | F2 | [0][5] | 5
CONN12 | 2 (12) | 17 | 10 | F1 | [1][5] | 13
CONN12 | 3 (11) | 18 | 48 | G1 | [1][6] | 14
CONN12 | 4 (10) | 19 | 8 | G0 | [2][6] | 22
CONN12 | 5 (9) | 20 | 47 | H0 | [2][7] | 23
CONN12 | 6 (8) | 21 | 7 | G2 | [0][6] | 6
CONN12 | 7 (7) | 22 | 46 | H2 | [0][7] | 7
CONN12 | 8 (6) | 23 | 6 | H1 | [1][7] | 15

View file

@ -134,7 +134,7 @@ static error_msg_t parse_secondary(struct command *cmd, const struct command_par
if (!e && kw) {
*sec = kw->val;
if (kw->val==2)
e = parse_expression_square(cmd, &psconfig2, 2);
e = parse_expression_square(cmd, &psconfig2, optional_brackets);
}
return e;
}

View file

@ -88,14 +88,14 @@ static int chaos_adc(struct command *cmd, const struct command_par *par)
int c = par->code;
unsigned int what = (unsigned int)par->par;
unsigned int v = what;
error_msg_t e = parse_expression_square(cmd, &v, 3);
error_msg_t e = parse_expression_square(cmd, &v, optional_number|optional_close);
if (e)
return parser_error_message(cmd, e);
unsigned char chs = v;
if (!chs)
chs = 0xff;
unsigned char rep = (v>>8) & 0xf;
if (!parse_expression_square(cmd, &v, 0))
if (!parse_expression_square(cmd, &v, optional_open))
rep = v;
if (what & 0x01000000) {
if (ads8688_results(chs))

105
dorn.c Normal file
View file

@ -0,0 +1,105 @@
#include "dorn.h"
#include "altera.h"
static const struct keywords dorn_fifo_kw[] = {
{"read", {.par= ALT_CMD_AF( 0) }},
{"empty", {.par= ALT_CMD_AF( 4) }},
{"packet", {.par= ALT_CMD_AF( 5) }},
{"full", {.par= ALT_CMD_AF( 6) }},
{"enable", {.par= ALT_CMD_AF( 7) }},
{"hbase", {.par= ALT_CMD_AF( 8) }},
{"strobe", {.par= ALT_CMD_AF(11) }},
{"mwrite", {.par= ALT_CMD_AF(12) }},
{"mdata", {.par= ALT_CMD_AF(13) }},
{"maddr", {.par= ALT_CMD_AF(14) }},
{"mnext", {.par= ALT_CMD_AF(15) }},
KW_END
};
int dorn_fifo(struct command *cmd, const struct command_par *par)
{
return altera_set_register(cmd, par, dorn_fifo_kw, 0,
(unsigned int)par->par, "fifo");
}
static const struct keywords dorn_trigger_kw[] = {
{"t1", {.par= ALT_CMD_AF( 8) }},
{"t2", {.par= ALT_CMD_AF( 9) }},
{"t3", {.par= ALT_CMD_AF(10) }},
{"samples", {.par= ALT_CMD_AF(11) }},
{"atrigger", {.par= ALT_CMD_AF( 8 | alt_cmd_double) }},
{"cwin", {.par= ALT_CMD_AF(12) }},
{"bin0", {.par= ALT_CMD_AF(13) }},
KW_END
};
int dorn_trigger(struct command *cmd, const struct command_par *par)
{
unsigned int a = (unsigned int)par->par;
error_msg_t e = parse_index(cmd, &a, 3, 11, 1);
if (e)
return parser_error_message(cmd, e);
return altera_set_register(cmd, par, dorn_trigger_kw, 0, a, "trigger");
}
static
error_msg_t parse_channel(struct command *cmd, unsigned int *a, int c, int m, int b)
{
error_msg_t e = parse_index(cmd, a, 3, 11, 1);
if (!e)
e = parse_index(cmd, a, 63, c, 2);
if (!e && m)
e = parse_index(cmd, a, m, b, 2);
return e;
}
int dorn_l1(struct command *cmd, const struct command_par *par)
{
unsigned int a = (unsigned int)par->par;
error_msg_t e = parse_channel(cmd, &a, 0, 0, 0);
if (e)
return parser_error_message(cmd, e);
return altera_set_register(cmd, par, 0, alt_cmd_inj, a, "thres");
}
static const
struct keywords dorn_l2_kw[] = {
{"a", {.par= ALT_CMD_AF( 0) }},
{"b", {.par= ALT_CMD_AF( 1) }},
KW_END
};
int dorn_l2(struct command *cmd, const struct command_par *par)
{
unsigned int a = (unsigned int)par->par;
error_msg_t e = parse_channel(cmd, &a, 4, 7, 1);
if (e)
return parser_error_message(cmd, e);
return altera_set_register(cmd, par, dorn_l2_kw, alt_cmd_inj, a, "filter");
}
int dorn_l3(struct command *cmd, const struct command_par *par)
{
unsigned int a = (unsigned int)par->par;
error_msg_t e = parse_channel(cmd, &a, 2, 3, 0);
if (e)
return parser_error_message(cmd, e);
return altera_set_register(cmd, par, 0, alt_cmd_inj, a, "banana");
}
static const struct keywords dorn_commands[] = {
CMD_KW("fifo", dorn_fifo, 255, (void*)(0xa080)),
CMD_KW("enable", dorn_trigger, 255, (void*)(0xa008)),
CMD_KW("thres", dorn_l1, 255, (void*)(0xa040)),
CMD_KW("l1", dorn_l1, 255, (void*)(0xa040)),
CMD_KW("filter", dorn_l2, 255, (void*)(0xa400)),
CMD_KW("l2", dorn_l2, 255, (void*)(0xa400)),
CMD_KW("a", dorn_l2, 255, (void*)(0xa400)),
CMD_KW("b", dorn_l2, 255, (void*)(0xa401)),
CMD_KW("banana", dorn_l3, 255, (void*)(0xa100)),
CMD_KW("l3", dorn_l3, 255, (void*)(0xa100)),
{"", {.par=&parser_unknown_command}}
};
COMMAND(dorn_command, parse_sub_command, 909, dorn_commands);

2
dorn.h Normal file
View file

@ -0,0 +1,2 @@
#include "parser.h"
extern const struct command_par dorn_command;

218
dorn.py
View file

@ -1,46 +1,70 @@
import math
import math, time, sys
AHEPAM_CONFIG = {
dorn_addr: 0x2000,
verbose: True,
slices: (0,1),
n_channels: 24
}
def _connect(ifc):
global _ifc, ecmd
_ifc = ifc
ecmd = ifc.ecmd
def dorn_config(a, v=None, m=None, slice=0):
verb = AHEPAM_CONFIG.verbose
a |= AHEPAM_CONFIG.dorn_addr | (slice<<11)
a &= 0xfff
class DORN_CONFIG:
# stis_ana_core 2×24 ch
dorn_addr = 0x2000
verbose = True
slices = (0,1)
n_channels = 24
l2 = ( # set6
(0, -1203, 0),
(1, -1203, 0),
(2, -1203, 0),
(3, -1186, 0),
(4, -39, 2000),
(5, 1709, 970),
(6, 2000, -1082),
(7, 1125, -1888),
)
def n_adc(self):
return self.n_channels//3
def Vref(self, slice=None):
try:
return self.VREF[slice]
except:
pass
return 3.3
def n_trigs(self):
if self.n_channels > 16:
return self.n_adc()
return self.n_channels
def m_trigs(self):
return (1 << self.n_trigs()) - 1
NTC = [dict(R1=10e3, R25=10e3, B25=3940, res=0x1000)]
CONFIG = DORN_CONFIG()
def dorn_config(a, v=None, mes=None, slice=0):
verb = CONFIG.verbose
a |= CONFIG.dorn_addr | (slice<<11)
if v is None:
if not m:
m = f"dorn[0x{a:03x}]"
return int(ecmd(f"alt/cmd/del[10] 0x{a:03x}", task=m, verb=verb).split()[-1], 0)
if not m:
m = f"dorn[0x{a:03x}] = 0x{v:04x}"
if not mes:
mes = f"dorn[0x{a:03x}]"
return int(ecmd(f"alt/cmd/del[10] 0x{a:03x}", task=mes, verb=verb).split()[-1], 0)
if not mes:
mes = f"dorn[0x{a:03x}] = 0x{v:04x}"
if v is False:
ecmd(f"alt/cmd/inj/del[1] 0x{a:03x}", task=m, verb=verb)
ecmd(f"alt/cmd/inj/del[1] 0x{a:03x}", task=mes, verb=verb)
else:
ecmd(f"alt/cmd/inj/del[1] 0x{a:03x} 0x{v:04x}", task=m, verb=verb)
ecmd(f"alt/cmd/inj/del[1] 0x{a:03x} 0x{v:04x}", task=mes, verb=verb)
def thres(sl, ch, v):
dorn_config(0x040 | ch, v, slice=sl)
def write_l2(sl, ch, i, a, b):
dorn_config(0x400 | (ch<<3) | (i<<1) | 0, a & 0xffff, slice=sl)
dorn_config(0x400 | (ch<<3) | (i<<1) | 1, b & 0xffff, slice=sl)
dorn_config(0x400 | (ch<<4) | (i<<1) | 0, a & 0xffff, slice=sl)
dorn_config(0x400 | (ch<<4) | (i<<1) | 1, b & 0xffff, slice=sl)
l2_set6 = (
(0, -1203, 0),
(1, -1203, 0),
(2, -1203, 0),
(3, -1186, 0),
(4, -39, 2000),
(5, 1709, 970),
(6, 2000, -1082),
(7, 1125, -1888),
)
def calib_l2(cal, l2_set6):
def calib_l2(cal, coeff):
if cal is None:
return coeff
from numpy import array, floor, add, any
@ -64,52 +88,60 @@ def calib_l2(cal, l2_set6):
w = e<0
return [(x, int(ii[0]), int(ii[1])) for x, ii in enumerate(i)]
def l2filter(coeff=l2_set6, cal=None):
for sl in AHEPAM_CONFIG.slices:
for ch in range(AHEPAM_CONFIG.n_channels):
def l2filter(coeff=None, cal=None):
if coeff==None:
coeff = CONFIG.l2
for sl in CONFIG.slices:
for ch in range(CONFIG.n_channels):
c = coeff
if cal and cal[sl] and cal[sl][ch]:
c = calib_l2(cal[sl][ch])
c = calib_l2(cal[sl][ch], c)
for cc in c:
write_l2(sl, ch, *cc)
def write_l3(sl, ch, *p):
scales = (14, 16, 14, 15)
scales = (14, 14, 15, 15)
for i,pp in enumerate(p):
if isinstance(pp, float):
pp = int(pp * 2**scales[i])
dorn_config(0x100 | (ch<<2) | i, pp & 0xffff, slice=sl)
def l3banana(
# iterated F-banana 2022-03-13-aha-bi207-18,
p0 = -4007,
p1 = 0,
p2 = 12737,
p3 = -3698 ):
for sl in AHEPAM_CONFIG.slices:
for ch in range(AHEPAM_CONFIG.n_channels):
write_l3(sl, ch, p0, p1, p2, p3)
# 2025-02-20-seth-pa1-4
p0 = -3839,
p2 = 13891,
p3 = 3579,
p4 = 22853 ):
for sl in CONFIG.slices:
for ch in range(CONFIG.n_channels):
write_l3(sl, ch, p0, p2, p3, p4)
def c16log2(A):
return int(math.ceil(16*math.log(1024*A)/math.log(2)))
def enable_trigger(sl, triggers, det=False, sa=False):
i = 2 if sa else 0 if det else 1
dorn_config(0x008 | i | sl<<4, triggers, slice=sl)
dorn_config(0x008 | i, triggers, slice=sl)
def nsamples(sl, n=None, m=None, **slice):
if n is None:
return dorn_config(0x00b | sl<<4, slice=sl)
return dorn_config(0x00b, slice=sl)
if m is None:
m = 0xfff if n else 0
m = 0xffff if n else 0
enable_trigger(sl, m, sa=True)
dorn_config(0x00b | sl<<4, n, slice=sl)
dorn_config(0x00b, n, slice=sl)
def triggers(sl, atrig=0x3ff, dtrig=0, sam=0, nsa=32):
def triggers(sl, atrig=0xffff, dtrig=0, sam=0, nsa=10):
enable_trigger(sl, dtrig, det=True)
enable_trigger(sl, atrig)
nsamples(sl, nsa, sam)
def atriggers(sl, atrig=0, gtrig=0, csa=False, gsa=False, nsa=10):
dorn_config(0x008, slice=sl, v=atrig & 0xffff, mes="atrig[15:0]")
dorn_config(0x009, slice=sl, v=(atrig>>16)|((gtrig&0xff)<<8), mes="gtrig[7:0],atrig[23:8]")
dorn_config(0x00a, slice=sl, v=gtrig>>8, mes="gtrig[23:8]")
dorn_config(0x00b, slice=sl, v=(gsa<<9)|(csa<<8)|nsa, mes="nsamples")
def hist_bins(sl, bin0=4.0, res=1, cwin=6, xtalk=6):
"""configure dorn_l4 histogramming
bin0: float: A-value of bin 0, int: 16LOG2(A)
@ -119,8 +151,8 @@ xtalk: x-talk ratio cut: reject if S > (S>>xtalk)
"""
if isinstance(bin0, float):
bin0=c16log2(bin0)
dorn_config(0x00c | sl<<4, (xtalk<<8) | cwin)
dorn_config(0x00d | sl<<4, (res<<9) | bin0)
dorn_config(0x00c, (xtalk<<8) | cwin, slice=sl)
dorn_config(0x00d, (res<<9) | bin0, slice=sl)
def base_address(hists=None, counters=None, hmask=None, cmask=None):
if hists is not None:
@ -152,17 +184,17 @@ def fifo_select(hi=False, sl=None, hk=False, ev=False, sa=False, i=None):
if sl is not None:
f <<= 3*sl+1
else:
f *= 18
f *= 0b0010010010010
f |= hi
return f
def fifo_enable(en=False, rfifo=False, sl=None, **aa):
def fifo_enable(en=True, rfifo=True, men=True, sl=None, **aa):
f = fifo_select(sl=sl, **aa)
if sl is None and en:
en = 3
if sl is None and en is True:
en = 0xf
elif sl is not None:
en <<= sl
dorn_config(0x087, (f<<6) | (rfifo<<5) | en)
dorn_config(0x087, (f<<6) | (rfifo<<5) | (men<<4) | en)
STROBES = {
"read_fifos": 0,
@ -205,68 +237,34 @@ def fifo_read(**aa):
else:
dorn_config(0x085, f)
def degC(a, R1=10e3, R25=10e3, B25=3750, res=0x1000):
R=R1*a/(res-(a&(res-1)))
return B25/(math.log(R/R25)+B25/298) - 273
def degCβ(a, R1=10e3, R25=10e3, B25=3940, res=0x1000):
if not a:
a = 1
R = R1 * a / (res - (a & (res-1)))
T = B25/(math.log(R/R25) + B25/298) - 273
return T
#TO DO: Adjust
def nmahepam_hk(sl, what="data", data=none, ND=8, NV=8, Vref=3.3):
if not data:
ecmd("alt/stream/off")
fifo_enable(en=True, sl=sl, hk=True)
fifo_reset(sl=sl, hk=True)
strobe(sl=sl, hk=True)
sleep(0.001)
fifo_read(sl=sl, hk=True)
data=read_fifo()
if (data[0] & 0xfffc) != 0x5710:
raise ValueError("Read HK packet error", data)
if what=="data":
return data
data = [d & 0xfff for d in data]
data = [data[ND*i+1:ND*i+1+NV] for i in range(8)]
if what=="raw":
return data
#NMAHEPAM:data[7][0] *= 2*Vref/4096 # Vcore
data[7][1] = degC(data[7][1]) # Tana
data[7][2] *= 2*Vref/4096 # V+6
data[7][3] *= 2.5*Vref/4096 # V-6
data[7][3] -= 1.5*data[7][2]
data[6][0] *= Vref/4096/0.0206 # Vbias
data[6][1] = degC(data[6][1]) # Tpa
data[6][3] *= 2*Vref/4096 # Vcc
data[6][2] *= 2.5*Vref/4096 # Vss
data[6][2] -= 1.5*data[6][3]
if what=="cooked":
return data
sys.stderr.write("""nmahepam HK:
Vcore = %6.3f V
Tana = %6.2f °C
V+6 = %6.3f V
V-6 = %6.3f V
Vbias = %6.2f V
Tpa = %6.2f °C
Vss = %6.3f V
Vcc = %6.3f V
""" % tuple(data[7]+data[6]))
def degC(a, idx=0):
return degCβ(a, **CONFIG.NTC[idx])
def default_config(thr=0x7ff):
for sl in range(AHEPAM_CONFIG.slices):
for ch in range(AHEPAM_CONFIG.n_channels):
for sl in CONFIG.slices:
for ch in range(CONFIG.n_channels):
thres(sl, ch, thr)
l2filter()
l3banana()
for sl in range(AHEPAM_CONFIG.slices):
hist_bins(sl)
triggers(sl, 0)
for sl in CONFIG.slices:
atriggers(sl)
def print_trigger_config():
tri = [[dorn_config(0x008 + i + (sl<<4)) for i in range(4)] for sl in range(2)]
tri = [[dorn_config(0x008 + i, slice=sl)
for i in range(4)]
for sl in CONFIG.slices]
ff = [dorn_config(0x084+i) for i in range(4)]
tri.append(ff)
e = ff[3]
df = [Areg(0x11+i) for i in range(3)]
df.append(Areg(5))
df = [_ifc.Areg(0x11+i) for i in range(3)]
df.append(_ifc.Areg(5))
tri.append(df)
print(f"""narena trigger config:
trigger detector masks:
@ -286,7 +284,7 @@ fifos enable SA/EV/HK HI {(e>>7)&7:03b} {(e>>10)&7:03b} {(e>>6)&1}
def read_event(sl=None, ev=None):
if ev is None:
fifo_read(sl=sl, ev=True)
ev = read_fifo(2)
ev = ifc._read_fifo(2)
if (ev[0] & 0xfffc) != 0x5718:
raise ValueError(f"EV packet magic mismatch {ev[0]:04x}")
Ba = ev[5]
@ -326,7 +324,7 @@ def read_samples(sl=0, n=None, sa=None):
if not (ff & (8 << (3*sl))):
break;
fifo_read(sl=sl, sa=True)
sa.append(read_fifo(3))
sa.append(ifc._read_fifo(3))
n -= 1
for s in sa:
if (s[0] & 0xfffc) != 0x5714:

View file

@ -113,16 +113,16 @@ static int filter(struct command *cmd, const struct command_par *par)
unsigned int slot = 0;
error_msg_t e = parse_flag(cmd, kws, &kw, 0);
if (!e)
e = parse_expression_square(cmd, &ch, 2);
e = parse_expression_square(cmd, &ch, optional_brackets|optional_close);
if (!e)
e = parse_expression_square(cmd, &slot, 2);
e = parse_expression_square(cmd, &slot, optional_brackets|optional_open);
if (!e && (ch>=2 || slot>=16))
e = &parser_value_error;
if (e)
return parser_error_message(cmd, e);
unsigned int what = kw->val | (ch<<7) | (slot<<3);
char name[16];
snprintf(name, sizeof(name), "%s[%d][%d]", kw->name, ch, slot);
snprintf(name, sizeof(name), "%s[%d,%d]", kw->name, ch, slot);
return altera_set_register(cmd, par, 0x0, 0, what, name);
}

View file

@ -1,5 +1,11 @@
@s/if !ssp_dma: s/exit
@clock/short
@s/if sec==0: nm/count/clear/float; s/exit
@s/if sec==2: pressure/inject; s/exit
@s/if sec==4: pressure/inject/p2; s/exit
@v S = sec % 10
@s/if S == 0: al/cmd/inj/res 0x30
@s/if S == 0: nm/cou/re/cl/fl; s/exit
@s/if S == 1: chaos/cmd 'W'; chaos/hk; s/exit
@s/if S == 2: var hk_c=1; chaos/adc 0x8ff; s/exit
@s/if S == 3 and hk_mes: var hk_c=hk_mes-1; s/exit
@s/if S == 4: chaos/cmd 'H' H; s/exit
@s/if S == 6: pressure/inject/p1; s/exit
@s/if S == 7: pressure/inject/p2; s/exit

View file

@ -1,3 +1,6 @@
@clock/short
@s/if sec==5: v hk_c=1; s/exit
@s/if sec & 1 and I: al/cmd/inj I; s/exit
@s/if sec==0: nm/cou/re/cl/fl; s/exit
@s/if sec==2 and H: al/cmd/inj H
@s/if sec==4: v hk_c=1; s/exit
@s/if sec==6 and hk_mes>1: v hk_c=hk_mes-1; s/exit

Binary file not shown.

View file

@ -0,0 +1,2 @@
v H = 0x00f0e08b
v I = 0

197
i2c.c Normal file
View file

@ -0,0 +1,197 @@
#include "i2c.h"
#include "altera.h"
#include "expression.h"
// Any non [bracketed] parameters may spill over to higher orde bits
// Not all combinations of /flags are applicable.
// /alt/cmd flags must follow the arguments. The argument then needs to be in []
unsigned int i2c_register = 0x8032;
unsigned int i2c_address, i2c_size;
const struct
keywords i2c_variable_names[] = {
{"i2c_register", {.par=&i2c_register}},
{"i2c_address", {.par=&i2c_address}},
{"i2c_size", {.par=&i2c_size}},
KW_END
};
static const
struct keywords i2c_write_kw[] = {
{"read", {.val= 0x0001 }}, // /restart/read/mag
{"autoincr", {.val= 0x0080 }}, // /reg/auto
{"ifactive", {.val= 0x0400 }},
{"ifack", {.val= 0x0800 }},
{"resume", {.val= 0x1000 }},
{"save", {.val= 0x1000 }},
{"send", {.val= 0x4000 }},
{"magnetometer", {.val= 0x003c }},
{"accelerometer", {.val= 0x0032 }},
{"discard", {.val= 0x2000 }},
{"last", {.val= 0x0200 }},
{"continue", {.val= 0 }}, // /read/cont (clear /last)
KW_END
};
// i2c_write() writes an action word into the I²C batch memory
//
// /start a send start and address (8-bit)
// /start/read a send start with read bit and address (8-bit)
// /restart/read a send restart, i.e., require the previous start to be acked
// /stop send stop
// /unstuck send an unstuck sequence
// /write d write anything, send a data byte
// /read n read n+1 data bytes and flag the last one
// /read/cont n read n+1 data bytes, do not flag the last one
// /reg r send a register addr, /save the addr as data
// /reg/auto r send a register addr with MSB set
//
// Flags:
//
// /read set LSB of the data, use with /restart
// /auto set the MSB of the data byte, use with /reg
// /ifact require the I²C unit to be active (acked /start)
// /ifack require the last byte being acked
// /resume continue after being blocked by /ifa…
// /save save the data byte, to be sent with the next odd read. Use with /reg
// /send send this command frame to the fifo, use with anything
// /discard do not send the data to the fifo, use with /read
// /last do not use, /read == /write/last, /stop == /start/last
// /cont use as /read/cont, /read/cont == /write, do not flag the last byte for reads
int i2c_write(struct command *cmd, const struct command_par *par)
{
unsigned int c = (unsigned int)(par->par);
error_msg_t e = parse_flags(cmd, i2c_write_kw, &c);
unsigned int cc = (c <<= 16) | i2c_register | 0xc001;
if (!e && (cc & 0x03000000) != 0x03000000)
// /stop and /unstuck do not use an agrument
e = parse_expression_square(cmd, &c, optional_brackets);
if (e)
return parser_error_message(cmd, e);
cc |= c<<16;
i2c_size ++;
return altera_set_register(cmd, par, 0, alt_cmd_inj, cc, "i2c");
}
// i2c_addr() commands the I²C engine.
// Both the data and addr commands are supported.
// It is meant to set the batch address pointer and run the batch
//
// /data read status, reset, A={0,0}
// /addr read status
// /addr [a] write A={0,a}
// /addr a write A={a}
// /addr [a] n write A={n,a}
// /data d write D={d}
// /data [l] h write D={h,l}
// /data [l] write D={0,l}
// /run write A={i2c_size, i2c_address}
// /run [a] write A={i2c_size, a}
// /run n write A={a, i2c_address}
int i2c_addr(struct command *cmd, const struct command_par *par)
{
unsigned int what = (unsigned int)(par->par);
unsigned int a = -1;
unsigned int n = 0;
unsigned int how = 0;
if (what & 2) {
how = alt_cmd_inj;
a = i2c_address;
n = i2c_size;
}
error_msg_t e = parse_expression_square(cmd, &a, optional_empty | optional_close);
if (e)
return parser_error_message(cmd, e);
e = parse_expression_square(cmd, &n, optional_brackets | optional_open);
n <<= 16;
if (a < 0x0100)
n = (n<<8) | (a<<16) | 0x4000;
n |= i2c_register | what & 1;
if (!e)
n |= 0x4000;
switch (n & 0x4001) {
case 0x0001:
a = 0;
case 0x4000:
i2c_address = a;
i2c_size = 0;
break;
case 0x4001:
i2c_size += 1;
}
return altera_set_register(cmd, par, 0, how, n, "i2c");
}
static const
struct keywords i2c_wait_kw[] = {
{"buffer", {.val= 0x1000 }},
{"release", {.val= 0x2000 }},
{"loop", {.val= 0x1000 }},
KW_END
};
// i2c_header() write a packet header or wait item to the I²C batch memory
//
// /head [magic] size start a packet, total size is size+1
// /wait ms wait for ms milliseconds
//
// Flags:
//
// /head/buffer Write the packet data into the buffer
// …/release Release the buffered data to the packetfifo (both)
// /wait/loop Restart the current batch after the wait.
//
// Typical batch:
//
// /addr a set batch start addr, saved in i2c_address
// /wait/release 2 release the dat from the buffer from the previous run
// /head/buffer [m] s Start a new packet in the buffer
// /start … generate the packet data
// … …
// /stop …
// /wait/loop t optional: restart with a certain cadence
//
// /run i2c_size-1 run the batch without loop
// /run run the batch with loop
int i2c_header(struct command *cmd, const struct command_par *par)
{
unsigned int c = (unsigned int)(par->par);
error_msg_t e = parse_flags(cmd, i2c_wait_kw, &c);
unsigned int cc = (c <<= 16) | i2c_register | 0xc001;
if (!e) {
c = 0;
e = parse_expression_square(cmd, &c, optional_empty | optional_close);
cc |= c<<24;
}
if (!e) {
c = 0;
e = parse_expression_square(cmd, &c, optional_any | optional_open);
cc |= c<<16;
}
if (e)
return parser_error_message(cmd, e);
i2c_size ++;
return altera_set_register(cmd, par, 0, alt_cmd_inj, cc, "i2c");
}
static const struct keywords i2c_commands[] = {
CMD_KW("addr", i2c_addr, 255, (void*)(0)),
CMD_KW("run", i2c_addr, 255, (void*)(2)),
CMD_KW("data", i2c_addr, 255, (void*)(1)),
CMD_KW("wait", i2c_header, 255, (void*)(0xc000)),
CMD_KW("header", i2c_header, 255, (void*)(0x8000)),
CMD_KW("start", i2c_write, 255, (void*)(0x0100)),
CMD_KW("restart", i2c_write, 255, (void*)(0x0500)),
CMD_KW("stop", i2c_write, 255, (void*)(0x0300)),
CMD_KW("unstuck", i2c_write, 255, (void*)(0x2300)),
CMD_KW("write", i2c_write, 255, (void*)(0x0000)), // omnipotent
CMD_KW("register", i2c_write, 255, (void*)(0x2000)), // implies /save
CMD_KW("read", i2c_write, 255, (void*)(0x0200)), // implies /last
{"", {.par=&parser_unknown_command}}
};
COMMAND(i2c_command, parse_sub_command, 909, i2c_commands);

3
i2c.h Normal file
View file

@ -0,0 +1,3 @@
#include "parser.h"
extern const struct command_par i2c_command;
extern const struct keywords i2c_variable_names[];

View file

@ -40,6 +40,9 @@ BEGIN {
T_R25 = 10e3
nEa = 60
Time1 = 1.7e9
Time2 = 2e9
if (UNIT) @UNIT()
}
@ -193,6 +196,23 @@ function isCHAOS() {
return 1;
}
function isCHAOS_SP() {
is2D(D1H,D2H)
BGO = A+B
if (BGO > 50) return 0
SSDA = 0
if (isPHA(A1H) > 1) SSDA = A
if (isPHA(A2H) > 1 && A > SSDA) SSDA = A
if (SSDA > 12) return 0
SSDC = 0
if (isPHA(C1H) > 1) SSDC = A
if (isPHA(C2H) > 1 && A > SSDC) SSDC = A
if (SSDC > 12) return 0
CHER = 0
if (isPHA(CHK) > 1) CHER = A
return 1;
}
function CHAOSHK() {
if (!/^HC/ || !/ 0x00ff5454 /) return 0
if ($2<Time) return 0
@ -831,8 +851,8 @@ END {
function isTime() {
if (!/^H /) return 0
Time = $2
if (Time > 2000000000) return 0
if (Time < 1700000000) return 0
if (Time > Time2) return 0
if (Time < Time1) return 0
TS = 0
for (s in TIMESHIFT) {
if (Time>=TIMESHIFT[s][1] && Time<=TIMESHIFT[s][2]) {

View file

@ -39,6 +39,8 @@
#include "spw.h"
#include "led.h"
#include "chaos.h"
#include "dorn.h"
#include "i2c.h"
// collect command submissions from various sources
@ -99,7 +101,7 @@ static int echo_command(struct command *cmd, const struct command_par *par)
what = (unsigned int)par->par;
unsigned int val = what & 0xff;
if (!e)
e = parse_expression_square(cmd, &val, 1);
e = parse_expression_square(cmd, &val, optional_expression);
if (e)
return parser_error_message(cmd, e);
if (val < (what&0xff))
@ -475,15 +477,9 @@ int main_loop_last_code;
struct command_par plugin_commandtable = {parse_plugin_command, 0, 0};
static COMMAND(echo_par, echo_command, 199, 0);
static COMMAND(message_par, echo_message, 100, 0);
static COMMAND(sleep_par, sleep_command, 197, 0);
static COMMAND(clock_par, clock_command, 180, 0);
static COMMAND(uart_par, uart_command, 196, 0);
static const struct keywords main_command_table[] = {
{"echo", {.par=&echo_par}},
{"message", {.par=&message_par}},
CMD_KW("echo", echo_command, 199, 0),
CMD_KW("message", echo_message, 100, 0),
{"file", {.par=&script_command}},
{"script", {.par=&script_command}},
{"flash", {.par=&flash_command}},
@ -493,8 +489,8 @@ static const struct keywords main_command_table[] = {
{"sdcard", {.par=&sdcard_command}},
{"ethernet",{.par=&eth_command}},
{"variable",{.par=&variable_commands}},
{"sleep", {.par=&sleep_par}},
{"clock", {.par=&clock_par}},
CMD_KW("sleep", sleep_command, 197, 0),
CMD_KW("clock", clock_command, 180, 0),
{"spi", {.par=&plugin_command}},
{"flyrena", {.par=&flyrena_command}},
{"sirena", {.par=&sirena_command}},
@ -507,9 +503,11 @@ static const struct keywords main_command_table[] = {
{"nm64", {.par=&nm64_command}},
{"spw", {.par=&spw_command}},
{"led", {.par=&led_command}},
{"uart", {.par=&uart_par}},
CMD_KW("uart", uart_command, 196, 0),
{"usb", {.par=&usb_command}},
{"chaos", {.par=&chaos_command}},
{"dorn", {.par=&dorn_command}},
{"i2c", {.par=&i2c_command}},
CMD_KW("arm", arm_command, 195, 0),
{"", {.par=&plugin_commandtable}},
@ -744,7 +742,7 @@ __attribute__((noreturn))
void main_loop(void)
{
uart_init();
message(0, "\n%s ARM rev %d, prod ffff:%04x, sn %d\n",
message(0, "\n%s ARM rev %08x, prod ffff:%04x, sn %d\n",
irena_name, Revision, 0xee00+ProductId, SerialNumber);
stack_report();
uart_enable_commands();
@ -906,6 +904,7 @@ const struct keywords *variable_names[] = {
nm64_variable_names,
spw_variable_names,
chaos_variable_names,
i2c_variable_names,
0
};

View file

@ -4,11 +4,12 @@
from arena import *
import math
from time import sleep
import arena, scangen
import dorn, arena, scangen
from dorn import *
ifc,_oo = armlib.init_irena(scope = globals(), name = "NARENA", prod = 0xee02)
arena._connect(ifc)
dorn._connect(ifc)
ifc._stream_fifos="hk1/f1/f2/f3"
if ifc.is_a("USB"):
@ -25,21 +26,8 @@ from lasc import SCstart, SCread
def SCplot(sc, CDIV=6, **kk):
osc.LASCplot(None, sc, CDIV=CDIV, **kk)
AHEPAM_CONFIG.update({
"dorn_addr": 0x800,
"n_channels": 12
})
l2_set6 = (
(0, -1203, 0),
(1, -1203, 0),
(2, -1203, 0),
(3, -1186, 0),
(4, -39, 2000),
(5, 1709, 970),
(6, 2000, -1082),
(7, 1125, -1888),
)
dorn.CONFIG.dorn_addr = 0x800
dorn.CONFIG.n_channels = 12
def narena_hk(sl, what="data", data=None, ND=4, NV=8, Vref=3.3):
"""what="data", "raw", "cooked", "print" (default)"""

2
nm64.c
View file

@ -783,7 +783,7 @@ static int hv_dac(struct command *cmd, const struct command_par *par)
error_msg_t e = parse_flags(cmd, kw, &step);
unsigned int idx, uv, uvs;
if (!e)
e = parse_expression_square(cmd, &idx, 2);
e = parse_expression_square(cmd, &idx, optional_brackets);
if (!e && idx>=4)
e = &parser_value_error;
if (!e) {

View file

@ -10,14 +10,13 @@ ls $(date +'nm64/kiel/nm64_kiel_%Y-%m-%dT*Z.dat' -d -1day) $(date +'nm64/kiel/nm
# temporarily disable cron emails
##exec 2>&1
rsync -av --exclude '/*/' etbern4.etph:/home/etbern4/nm64/solo/eda/arm/nm64/data/ /data/falbala/nm64/data/jfj/igy/
rsync -av --exclude '/*/' -e 'ssh -Jnm64@cosray.unibe.ch' igy.hfsjg.unibe.ch:/home/etbern4/nm64/solo/eda/arm/nm64/data/ /data/falbala/nm64/data/jfj/igy/
ls $(date +'nm64/jfj/igy/JFJ_IGY*_%Y-%m-%dT*Z.dat' -d -1day) $(date +'nm64/jfj/igy/JFJ_IGY*_%Y-%m-%dT*Z.dat') | sed 's,.dat$,.nm_raw,' | xargs make 2>&1
#rsync -av --exclude '/*/' -e 'ssh -Jetbern4.etph' etbern2:/home/etbern2/nm64/solo/eda/arm/nm64/data/ /data/falbala/nm64/data/jfj/nm64/
rsync -av --exclude '/*/' etbern2.etph:/home/etbern2/nm64/solo/eda/arm/nm64/data/ /data/falbala/nm64/data/jfj/nm64/
rsync -av --exclude '/*/' -e 'ssh -Jnm64@cosray.unibe.ch' nm64.hfsjg.unibe.ch:/home/etbern2/nm64/solo/eda/arm/nm64/data/ /data/falbala/nm64/data/jfj/nm64/
ls $(date +'nm64/jfj/nm64/JFJ_NM64_%Y-%m-%dT*Z.dat' -d -1day) $(date +'nm64/jfj/nm64/JFJ_NM64_%Y-%m-%dT*Z.dat') | sed 's,.dat$,.nm_raw,' | xargs make 2>&1
rsync -av --exclude '/*/' etbern3.etph:/home/etbern3/nm64/solo/eda/arm/nm64/data/ /data/falbala/nm64/data/bern/
rsync -av --exclude '/*/' -e 'ssh -Jnm64@cosray.unibe.ch' kspc16.unibe.ch:/home/etbern3/nm64/solo/eda/arm/nm64/data/ /data/falbala/nm64/data/bern/
ls $(date +'nm64/bern/nm64_rolf_%Y-%m-%dT*Z.dat' -d -1day) $(date +'nm64/bern/nm64_rolf_%Y-%m-%dT*Z.dat') | sed 's,.dat$,.nm_raw,' | xargs make 2>&1
ls $(date --utc +'nm64/kiel/nm64_kiel_%Y-%m-%dT%H:*Z.nm_raw') | xargs -i bash -c '[ -s "{}" ] || echo empty "{}" >&2'

107
nmahepam.py Executable file
View file

@ -0,0 +1,107 @@
#! /usr/bin/ipython3 --profile=nmahepam
# encoding: UTF-8
import armlib, dorn, sys, math, time
def HK():
Vcc = hk2mvolt("adc_Vpcsa")*0.002
Vss = hk2mvolt("adc_Vmcsa")*(-0.002)
Icc = hk2mvolt("adc_Ipcsa")*0.1
Iss = hk2mvolt("adc_Imcsa")*(-0.1)
Vprim = hk2mvolt("adc_Vprim")*(0.011)
Vbias = hk2mvolt("adc_Vbias")*(-0.05)
Ibias = hk2mvolt("adc_Ibias")*0.0955
r = (Vcc, Vss, Icc, Iss, Vprim, Vbias, Ibias)
print("Vcc:%4.2fV, Vss:%4.2fV, Icc:%6.1fmA, Iss:%6.1fmA, Vprim:%4.1fV, Vbias:%.1fV Ibias:%.1fnA" % r)
return r
def findnmahepam():
findxrena(prod=(0xee0c,))
if connected_p():
set_clock()
messages()
HK()
#TO DO: Adjust
def hk(sl, what="print", data=None):
if not data:
ecmd("alt/stream/off")
menable()
dorn.fifo_enable(en=True, sl=sl, hk=True)
dorn.fifo_reset(sl=sl, hk=True)
dorn.strobe(sl=sl, hk=True)
time.sleep(0.1)
dorn.fifo_read(sl=sl, hk=True)
data=read_fifo()
if data[0] != 0x5710 + sl:
raise ValueError("Read HK packet error", data)
if what=="data":
return data
ND = dorn.CONFIG.n_adc()
NV = ND
data = [d & 0xfff for d in data]
data = [data[ND*i+1:ND*i+1+NV] for i in range(8)]
if what=="raw":
return data
Vref = dorn.CONFIG.Vref(sl)/4096
#NMAHEPAM:data[7][0] *= 2*Vref/4096 # Vcore
data[4][0] = degC(data[4][0], 0) # T_BGO,EXT
data[4][1] = degC(data[4][1], 0) # T_BGO,NTC
data[4][2] *= -Vref/0.047 # V_bias
data[4][3] = degC(data[4][3], 0) # T_BGO,REF
data[4][4] *= Vref * 10470/470 * 51/1051 * 100 # Ibias
data[4][5] *= Vref * 10470/470 * 51/1051 * 100 # Ibias
data[4][7] *= Vref * 2 # VCC
data[4][6] *= Vref * 2.5 # VSS
data[4][6] -= 1.5*data[4][7] # VSS
data[3][0] *= Vref * 10470/470 * 51/1051 * 100 # Ibias
data[3][1] *= Vref * 2 # Vff
data[3][3] *= Vref * 2 # Vpp (V+6V)?
data[3][2] *= Vref * 2.5 # Vnn
data[3][2] -= 1.5*data[3][3] # Vnn
data[3][4] *= Vref * 2 # Vdig (Vadc)
data[3][5] = degC(data[3][5], 0) # NTC ?
data[3][6] *= Vref * 2 # VCC
data[3][7] *= Vref * 2.5 # VSS
data[3][7] -= 1.5*data[3][6] # VSS
if what=="cooked":
return data
r = f"""# nmahepam HK:
0. {data[0]}
1. {data[1]}
2. {data[2]}
3. ADC board
T = {data[3][5]:6.2f} °C
Ibias = {data[3][0]:6.3f} V
Vff = {data[3][1]:6.3f} V , Vnn = {data[3][2]:6.3f} V, Vpp = {data[3][3]:6.3f} V, Vdig = {data[3][4]:6.3f} V
Vcc = {data[3][6]:6.3f} V, Vss = {data[3][7]:6.3f} V
4. PA board
Tbgo = {data[4][0]:6.2f} °C, {data[4][1]:6.2f} °C, {data[4][3]:6.2f} °C
Vbias = {data[4][2]:6.3f} V, Ibias = {data[4][4]:6.1f} nA, {data[4][5]:6.1f} nA
Vcc = {data[4][7]:6.3f} V, Vss = {data[4][6]:6.3f} V
5. {data[5]}
6. {data[6]}
7. {data[7]}
"""
if what=="print":
sys.stderr.write(r)
return r
def aenable(sl=1, hk=True, ev=True, **aa):
cmd("s/cron 'CRON.RC'")
fifo_enable(sl=sl, hk=hk, ev=ev, **aa)
enable()
if __name__=="__main__":
ifc,_oo = armlib.init_irena(scope = globals(), name = "AHEPAM", prod = (0xee0c,))
ifc._stream_fifos = 'hk1/f1/f2/f3'
if ifc.is_a("USB"):
findnmahepam()
from dorn import *
dorn._connect(ifc)

View file

@ -371,26 +371,52 @@ int parser_dump(struct command *cmd, const struct command_par *par)
ERRORMESSAGE(err_noblock, 951, "no usb data block");
// optional = 0: '[' «expr» ']'
// optional = 1: [ '[' «expr» ']' ]
// optional = 2: [ '[' ] «expr» [ ']' ]
// optional = 3: [ [ '[' ] «expr» [ ']' ] ]
error_msg_t parse_expression_square(struct command *cmd, unsigned int *r, int optional)
{
error_msg_t e = expect_char(cmd, '[');
if (e && optional==1)
return 0;
if (e && optional==0)
return e;
static int isopen;
error_msg_t e = 0;
if (!(optional & optional_open && isopen))
e = expect_char(cmd, '[');
isopen = 0;
if (e && !(optional_open & optional_brackets))
if (optional_open & optional_expression)
return 0;
else
return e;
if (!e && optional & optional_in_brackets)
if (parse_char(cmd, ']'))
return 0;
else if (optional & optional_close && parse_char(cmd, ',')) {
isopen = 1;
return 0;
}
error_msg_t ee = parse_expression(cmd, r);
if (!e && !ee)
if (!e && !ee) {
ee = expect_char(cmd, ']');
if (!e || optional==2)
if (ee && optional & optional_close) {
isopen = 1;
ee = expect_char(cmd, ',');
}
}
if (!e || !(optional & optional_expression))
return ee;
return 0;
}
error_msg_t parse_index(struct command *cmd, unsigned int *r, unsigned int m, unsigned int b, int optional)
{
unsigned int a;
error_msg_t e = parse_expression_square(cmd, &a, optional);
if (!e && a > m)
e = &parser_value_error;
if (e)
return e;
a <<= b;
a |= *r & ~(m << b);
*r = a;
return 0;
}
error_msg_t error_printf(unsigned int code, const char *m, ...)
{
static char mes[64];

View file

@ -83,6 +83,18 @@ extern const struct command_par parser_keyword_error;
#define KW_END {"", {0}}
error_msg_t parse_expression_square(struct command *cmd, unsigned int *r, int optional);
error_msg_t parse_index(struct command *cmd, unsigned int *r, unsigned int m, unsigned int b, int optional);
enum {
optional_expression = 1, // The expression is optional
optional_brackets = 2, // The brackets around the expression are optional
optional_in_brackets = 4, // Empty brackets are permitted
optional_open = 8, // Accept a previously opened bracket
optional_close = 16, // May leave the bracket open, with a ','
optional_number = 3, // optional expression, optionally bracketed.
optional_empty = 5, // Optional expression, with brackets, maybe empty
optional_any = 7, // Everything optional
};
static inline void cmd_push(struct command *cmd, struct command *save)
{