Compare commits
32 commits
c81bb3cdb8
...
05b0206105
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05b0206105 | ||
|
|
fef4a9db28 | ||
|
|
dbf3725f04 | ||
|
|
fba73eb689 | ||
|
|
7c711fd1d8 | ||
|
|
d623ed3885 | ||
|
|
dc0e4e4a27 | ||
|
|
455a33a397 | ||
|
|
cec68e93b9 | ||
|
|
9809041577 | ||
|
|
2e96ff3d73 | ||
|
|
704a7c2c78 | ||
|
|
2fc61dc128 | ||
|
|
e7c0fd4156 | ||
|
|
6bd5cd06ae | ||
|
|
8d7284fc75 | ||
|
|
b293536817 | ||
|
|
62bdcf72b7 | ||
|
|
36a5767824 | ||
|
|
37e18dd984 | ||
|
|
f01cc2f807 | ||
|
|
825eea0422 | ||
|
|
ecc3dc3742 | ||
|
|
d41bfa309a | ||
|
|
222aad1e90 | ||
|
|
83ac07f0ce | ||
|
|
a6955e771f | ||
|
|
a0f7f831cb | ||
|
|
9a58fdff52 | ||
|
|
3f285a00b7 | ||
|
|
55d797b13f | ||
|
|
4cfc59dbe9 |
26 changed files with 879 additions and 212 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -4,9 +4,12 @@ irena.bin
|
|||
irena.hex
|
||||
irena.rom*
|
||||
revision.h
|
||||
*.fat
|
||||
*.fat*
|
||||
__pycache__
|
||||
revision.h+
|
||||
*~
|
||||
*.s
|
||||
oops.txt
|
||||
irenarc.py
|
||||
irenafile
|
||||
*/data
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
41
ahepam/nmahepam_channels.md
Normal file
41
ahepam/nmahepam_channels.md
Normal 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
|
||||
|
||||
2
altera.c
2
altera.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
4
chaos.c
4
chaos.c
|
|
@ -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
105
dorn.c
Normal 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
2
dorn.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#include "parser.h"
|
||||
extern const struct command_par dorn_command;
|
||||
218
dorn.py
218
dorn.py
|
|
@ -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:
|
||||
|
|
|
|||
6
erena.c
6
erena.c
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
|
@ -0,0 +1,2 @@
|
|||
v H = 0x00f0e08b
|
||||
v I = 0
|
||||
197
i2c.c
Normal file
197
i2c.c
Normal 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
3
i2c.h
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#include "parser.h"
|
||||
extern const struct command_par i2c_command;
|
||||
extern const struct keywords i2c_variable_names[];
|
||||
|
|
@ -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]) {
|
||||
|
|
|
|||
25
mainloop.c
25
mainloop.c
|
|
@ -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=ð_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
|
||||
};
|
||||
|
|
|
|||
20
narena.py
20
narena.py
|
|
@ -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
2
nm64.c
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
107
nmahepam.py
Executable 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)
|
||||
50
parser.c
50
parser.c
|
|
@ -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];
|
||||
|
|
|
|||
12
parser.h
12
parser.h
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue