Compare commits

..

No commits in common. "70cefb78d34a276953b12580a22245433954ed7e" and "d5e4d19165d37cfd13ccbc85664b9e8261e9d19e" have entirely different histories.

15 changed files with 25 additions and 401 deletions

View file

@ -228,10 +228,8 @@ FATNAME_flash_TANOS=TANOS
FATNAME_flash_CHAOS=CHAOS
FATNAME_flash_µM=IRENAuM
FATNAME_flash_NMAHEPAM=NMAHEPAM
FATNAME_flash_LEIA=LEIA
FATNAME=$(FATNAME_$(FLASH))
FATSIZE_flash_tarena=1M
FATSIZE_flash_pirena=1M
FATSIZE_flash_darena=1M
FATSIZE_flash_erena=1M

View file

@ -35,20 +35,10 @@ function isEE() {
return 1
}
function doEPOCH(t) {
if (t < 0x00ffffff && TLAST > 0xff000000) {
EPOCH += 0x100000000
TLAST = t
} else if (t > TLAST) {
TLAST = t
}
return t+EPOCH
}
function isCC() {
N = 0
if (!/^EDB? /) return 0
if (NE && ($2 > T0+7 || $2+7 < T0)) {
if (NE && ($2 > T0+20 || $2+20 < T0)) {
N = NE
TE0 = T0
save = $0
@ -75,7 +65,14 @@ function isCC() {
i = NDCh * $3 + $4
ELINES[i] = $0
NE++
if (N) doEPOCH(TE0)
if (N) {
if (TE0 < 0x00ffffff && TLAST > 0xff000000) {
EPOCH += 0x100000000
TLAST = TE0
} else if (TE0 > TLAST) {
TLAST = TE0
}
}
return N
}
@ -129,8 +126,6 @@ function isSETH() {
}
ETRIG0 = 0
ETRIG1 = 0
iTRIG0 = -1
iTRIG1 = 48
for (i in cTRIG) {
if (EE[i] > ETRIG0) {
ETRIG0 = EE[i]

2
avr

@ -1 +1 @@
Subproject commit 7ebd848bd2e58dc30c966ebf915f7ce6ff8e77df
Subproject commit 50f46b8494bbba65ccbec124f4fd4d9c0c4b72a3

53
dorn.py
View file

@ -47,24 +47,9 @@ def HK7_SETH_fmt(s, i, n, d):
return f"""{i}. {n}
na = {repr(d[:4])}
Text = {d[6]:.1f} °C,
Ibias = {d[4]:.1f} nA,
Ibias = {d[4]:.1f} nA.
Ibias = {d[7]:.1f} nA, Vbias = {d[5]:.1f} V.
"""
def HK3_LEIA_fmt(s, i, n, d):
return f"""{i}. {n}
Tadc = {d[0]:6.2f} °C,
Vadc = {d[1]:6.3f} V,
VbiasD = {d[7]:6.2f} V,
Vbias2 = {d[6]:6.1f} V,
Vpp = {d[3]:6.3f} V, Vnn = {d[2]:6.3f} V,
Vcc = {d[5]:6.3f} V, Vss = {d[4]:6.3f} V.
"""
def HK4_LEIA_fmt(s, i, n, d):
return f"""{i}. {n}
Ibias1 = {d[3]:.1f} nA, Ibias2 = {d[2]:.1f} nA, IbiasD = {d[0]:.1f} nA,
VbiasG = {d[1]:.1f} V, Vbias1 = {d[4]:.1f} V,
Tpa0 = {d[5]:6.2f} °C, Tpa1= {d[6]:6.2f} °C, Tpa2 = {d[7]:6.2f} °C.
"""
class DORN_CONFIG:
# stis_ana_core 2×24 ch
@ -174,7 +159,7 @@ class DORN_CONFIG:
HK4_AHBGO = [[
("Tbgo₁", (degC, {})),
("Tbgo₂", (degC, {})),
("Vbias1", -1/0.047),
("Vbias", -1/0.047),
("Tbgo₃", (degC, {})),
("Ibias₁", 10470/470 * 51/1051 * 100),
("Ibias₂", 10470/470 * 51/1051 * 100),
@ -186,37 +171,9 @@ class DORN_CONFIG:
# ! change the class attribute .HK
self.HK[4] = ("HK PA", self.HK4_AHBGO, HK4_AHBGO_fmt)
HK3_LEIA = [[
("Tadc", (degC, {})),
("Vadc", 2.0),
("Vnn", 2.5, ("Vpp", -1.5)),
("Vpp", 2.0),
("Vss", 2.5, ("Vcc", -1.5)),
("Vcc", 2.0),
("Vbias2", -1/0.022 * 66.6/75.2),
("VbiasD", -14.),
]]
HK4_LEIA = [[
("IbiasD", 100., -1.4),
("VbiasG", 46.3, ("Vref", -45.3)),
("Ibias2", 10470/470 * 51/1051 * 100, -65.0),
("Ibias1", 10470/470 * 51/1051 * 100, -52.0),
("Vbias1", -1/0.047 * 44.7/48.5),
("Tpa0", (degC, {})),
("Tpa1", (degC, {})),
("Tpa2", (degC, {})),
]]
def leia(self):
self.VREF = (3.342,)
self.slices=(0,)
self.HK[3] = ("HK_AD", self.HK3_LEIA, HK3_LEIA_fmt)
self.HK[4] = ("HK_PA", self.HK4_LEIA, HK4_LEIA_fmt)
CONFIG = DORN_CONFIG()
def hk(sl=0, what="print", data=None):
def hk(sl, what="print", data=None):
if not data:
ecmd("alt/stream/off")
_ifc.menable()
@ -250,7 +207,6 @@ def hk(sl=0, what="print", data=None):
return sl, data
Vref = CONFIG.Vref(sl)/4096
ddata = []
VV = {"Vref": CONFIG.Vref(sl)}
for a in range(8):
V = {}
ddata.append(V)
@ -272,12 +228,11 @@ def hk(sl=0, what="print", data=None):
else:
data[a][c] *= Vref*H[1]
V[H[0]] = data[a][c]
VV.update(V)
for c in range(8):
H = HK[c]
if len(H) > 2:
if isinstance(H[2], tuple):
data[a][c] += VV[H[2][0]] * H[2][1]
data[a][c] += V[H[2][0]] * H[2][1]
else:
data[a][c] += H[2]
V[H[0]] = data[a][c]

View file

@ -1,8 +0,0 @@
@clock/short
@v S=sec%12
@s/if hk_mes>1: v hk_count=1
@s/if !S: nm/cou/re/cl/fl; s/exit
@s/if S&1: s/exit
@s/if S&2: pres/inj; s/exit
@s/if S&4: v hk_count=1; s/exit
@s/if S&8: dorn/fifo/strobe/inj 0x10; s/exit

View file

@ -1,12 +0,0 @@
@v/cache iter
@s/for 24: s/exe 'DORNCC.RC' 0, i, 0x10000
@dorn/l3 [0,4,0] -4404
@dorn/l3 [0,4,1] 10830
@dorn/l3 [0,4,2] -23912
@dorn/l3 [0,4,3] 0x7fff (overflow: 45271)
@dorn/fifo/enable/inj 0xdb1
@dorn/enable/samples/inj 0
@v $T = 0
@dorn/enable/t1/inj $T
@dorn/enable/t2/inj $T / 0x10000 + $T * 0x100
@dorn/enable/t3/inj $T / 0x100

View file

@ -1,30 +0,0 @@
@v $C = 24*$1 + $2
@s/if !Z[$C]: v Z[$C]=8
@dorn/thr [$1,$2] Z[$C]
@s/if !$3: v $3 = 0x10000
@v $A[0] = -1203
@v $A[1] = -1203
@v $A[2] = -1203
@v $A[3] = -1186
@v $A[4] = -39
@v $A[5] = 1709
@v $A[6] = 2000
@v $A[7] = 1125
@v $X = 0
@s/for 7: v $Y=$A[7-i]*$3/0x10000; v $X=$X-$Y; dorn/a [$1,$2,7-i] $Y
@dorn/a [$1,$2,0] $X
@v $A[0] = 0
@v $A[1] = 0
@v $A[2] = 0
@v $A[3] = 0
@v $A[4] = 2000
@v $A[5] = 970
@v $A[6] = -1082
@v $A[7] = -1888
@v $X = 0
@s/for 7: v $Y=$A[i]*$3/0x10000; v $X=$X-$Y; dorn/b [$1,$2,i] $Y
@dorn/b [$1,$2,7] $X
@dorn/l3 [$1,$2,0] -3686
@dorn/l3 [$1,$2,1] 16027
@dorn/l3 [$1,$2,2] 12898
@dorn/l3 [$1,$2,3] 24618

View file

@ -1,10 +0,0 @@
@sleep 1
@var/set verb=3
@var/set script_cron_prio = 3
@var/set dac=0
@s/if product==0xee0a: altera/file "NMLEIAV1.RBF"
@s/if errno>=500: s/exit
@s/if product==0xee0c: altera/file "NMLEIAV2.RBF"
@s/if errno>=500: s/exit
@e/eval "s/exe 'SN%d.RC'", serial
@s/exe "DORN.RC"

Binary file not shown.

Binary file not shown.

View file

@ -1,7 +0,0 @@
FAT12 2MByte Filesystem for NMAHEPAM
INIT.RC script loaded at startup
NMAHEPAM.RBF Altera FPGA bitfile, Cyclone 10CL025
CRON.RC cron script, to to HK every Minute
SN14.RC unit config
I2C.RC SETH magnetometer and accelerometer config

View file

@ -1,2 +0,0 @@
@v bate_hash = 0x3921
pres/read/verify

Binary file not shown.

View file

@ -1,33 +1,6 @@
import sys, armlib, struct, math, time
class bitnames(dict):
def str(self, b):
r = []
for k, m in self.items():
m = self.bits(m)
if (b & m) == m:
r.append(k)
b &= ~m
if not b:
break
if len(r)==1:
r = r[0]
return r
def bits(self, r, mask=False):
if isinstance(r, int):
return r
if isinstance(r, str):
return self.bits(self[r])
if isinstance(r, dict):
return sum([self.bits(rr) for rr in r if mask or r[rr]])
return sum(map(self.bits, r))
def mask_val(self, **aa):
return self.bits(aa, mask=True), self.bits(aa)
class leia_stepper:
class Stepper_Error(armlib.irena_ifc.IrenaError):
@ -211,15 +184,13 @@ class leia_stepper:
b = struct.pack(self.STATF, *bb)
return b
def read_conf(self, stat=False, unpack=True):
def read_conf(self, unpack=True):
b = []
while True:
r = self.cmd('x', len(b), Error=True, sleep=0.001)
if r & 0xff0000:
break
b.append(r & 0xff)
if not stat and len(b) >= self.CONFF.size:
break
b = bytes(b)
if unpack and b[:2]==self.CONFM and b[2] in self.CONFV:
return self.confdict(b)
@ -270,14 +241,6 @@ class leia_stepper:
n = i+1
return b[:n]
def write_eeprom(self, a=0, b=None):
if b is not None:
self.write_conf(b)
self.cmd('zW', 4*a, verbose=True)
while self.cmd('x', 83, verbose=True, Error=True) & 0xff00ff:
time.sleep(0.1)
return self.cmd('?', verbose=True)
ADC_V = {
"data": 0,
"mux": 1,
@ -303,7 +266,7 @@ class leia_stepper:
if what == self.ADC_V["period"]:
val = int(val/self.T0TICK + 0.5) # ms
else:
raise ValueError("float not supported for this whatsit")
raise ValueError("fload not supported for this whatsit")
if enable is not None:
if what and enable and val is not None:
raise ValueError("cannot enable and read a whatsit")
@ -318,7 +281,13 @@ class leia_stepper:
raise self.Stepper_Error(f"{c}, {val}, {what}{r}")
return r & 0xff
def dac(self, volt=None, dac=None, ramp=True, ms=None):
def dac(self, volt=0.0, dac=None, ramp=True, ms=None):
if dac is None:
dac = int(volt/2.5*0x10000)
if dac < 0 or dac >= 0x10000:
raise ValueError(f"DAC voltage out of range {volt}, {dac}")
if not ramp:
self.cmd('P', 0)
if ms is not None:
t = self.adc(what="period")*self.T0TICK
p = int(t * 64/ ms + 0.5)
@ -329,28 +298,20 @@ class leia_stepper:
self.cmd('P', p)
if self._verbose >= 1:
print(f"DAC ramp speed {t*64/p:.1f} ms/step", file=sys.stderr)
if dac is None:
if volt is None:
return self.cmd('d')
dac = int(volt/2.5*0x10000)
if dac < 0 or dac >= 0x10000:
raise ValueError(f"DAC voltage out of range {volt}, {dac}")
if not ramp:
self.cmd('P', 0)
old = self.cmd('D', dac)
if self._verbose >= 1:
print(f"DAC set to 0x{dac:04x}, old value: 0x{old:04x}",
file=sys.stderr)
def Temp(self, a, Vref, **aa):
a *= Vref/self.Vcc
a *= self.Vcc/Vref
return armlib.NTC(a, β=3940)
def AVR_Temp(self, a, Vref, **aa):
return a/64 * 2.5/Vref - 273
ADC_MUX = {
3: ("Iprim", 1.0, "A"),
3: ("Iprim", 1.0, "uncal"),
8: ("NTC1", Temp, "°C"),
9: ("NTC2", Temp, "°C"),
10: ("NTC3", Temp, "°C"),
@ -362,7 +323,6 @@ class leia_stepper:
Vcc = 3.3
T0TICK = 0.0925925925925926
T1TICK = T0TICK/4
def read_adcs(self, chs=tuple(range(16)), update_vcc=True):
r = []
@ -412,217 +372,3 @@ class leia_stepper:
pass
print(" done.\n", self.ifc.cmd("spi/reset/ssel"), file=sys.stderr)
print("commit: ", self.id(), file=sys.stderr)
E_reset = {
None: 0,
"assert": 0x2000,
"home": 0x8000,
}
E_what = {
None: 0,
"reset": 0x10000,
"enable": 0x10100,
"led": 0x10200,
"sleep": 0x10300,
}
E_port = bitnames({
"ALL": 0x78,
"RESET": 0x08,
"ENABLE": 0x10,
"LEDON": 0x20,
"SLEEP": 0x40,
"NONE": 0x00,
})
E_mode = {
None: 0,
True: 0x51c00,
False: 0x51d00,
"emit": 0x01000,
"reset": 0x03000,
"init": 0x04000,
"home": 0x08000,
"assert": 0x21800,
"deassert":0x21400,
"enable": 0x51c00,
"disable": 0x51d00,
"ledoff": 0x51e00,
"sleep": 0x51f00,
"!enable": "disable",
"!disable": "enable",
"!ledoff": "disable",
"!sleep": "disable",
}
def enable(self, mode=None, what=None, bits=None, **aa):
"""spi/stepper 'r'"""
a = 0
# eqiv:
# what="reset", bits=("RESET")
# what="reset", RESET=1
# reset=("RESET")
# or any other whatsit
# (In case the port config jumpers were changed)
#
# sleep=True: assert SLEEP (clear bit)
# led=False: deassert LEDON (set bit)
# emit=False: do not change the port bits
# init=True: initialize the stepper
# reset = "assert": assert RESET (clear port bit)
# reset = "home": start stepper with a reset pulse
if len(aa)==1:
k = list(aa.keys())[0]
if mode is None and aa[k] is False:
mode = self.E_mode["!"+k]
aa = None
elif mode is None and aa[k] is True:
mode = k
aa = None
elif what is None:
what = k
aa = aa[k]
if aa is True or aa is False:
aa = None
if aa:
if bits is None:
bits = aa
else:
raise ValueError("too many bits")
if what is None and mode is None:
mode = True
a |= self.E_what[what]
c = 'r'
if bits is not None:
bits = self.E_port.bits(bits)
if a & 0x10000:
c = 'R'
a |= bits & self.E_port.bits("ALL")
else:
raise ValueError("no what")
bits = self.E_port.str(a & 0xff)
if self.E_mode[mode] & a & 0x50f00:
raise ValueError("too many hows")
a |= self.E_mode[mode]
r = self.cmd(c, a & 0xffff)
old = self.E_port.str(r & 0xff)
port = self.E_port.str(r>>8 & self.E_port.bits("ALL"))
return mode, what, bits, old, port
MS = {
1: 0x02,
2: 0x0a,
4: 0x06,
8: 0x0e,
16: 0x04,
32: 0x0c,
-1: 0x00,
-2: 0x08,
}
def ms(self, n=1, ms=None, torque=False):
"""calculate microstepping bits
n: microsteps per step (1|2|4|8|16|32|-1|-2)
n: -1|-2: full torque
torque=True: n=1|2: full torque
"""
if ms is not None:
ms = (ms&1)<<3 | (ms&2)<<1 | (ms&4)>>1
else:
ms = self.MS[-n if torque else n]
return ms
def microstep(self, *a, emit=True, **aa):
"""set microstepping bits
*a, **aa: see: .ms()
"""
c = 'i'
if emit:
c = 'I'
ms = self.ms(*a, **aa)
ms |= (~ms & 0x0e)<<8
return self.cmd(c, ms)
def dir(self, d=None):
"""set/read direction
d = 0|1 (False|True)
higher bits are ignored
"""
if d is None:
return self.cmd('i')
return self.cmd('i', d&1 | (~d&1)<<8)
MIN_SPEED = 21
def speed(self, period=None):
"""set/read stepper cadence
period (int) in T1TICS = 23.148 µs
period (float) in ms
"""
if period is None:
return self.cmd('q')
if isinstance(period, float):
period = int(period/self.T1TICK) - 1
if period < self.MIN_SPEED:
period = self.MIN_SPEED
return self.cmd('Q', period)
LIMITS = bitnames(
ALL = ("LEDS", "FAULTS"),
FAULTS = ("FAULT1", "FAULT2"),
FAULT1 = 0x80,
FAULT2 = 0x20,
LEDS = ("LED1", "LED2"),
LED1 = 0x01,
LED2 = 0x02,
NONE = 0x00,
LOCK = (0x100, "ALL")
)
def limit(self, mask=None, val="ALL", **aa):
if isinstance(mask, dict):
aa = mask
if aa:
mask, val = self.LIMITS.mask_val(**aa)
else:
if mask is None:
b = self.cmd('m')
return self.LIMITS.str(b&0xff), self.LIMITS.str(b>>8)
mask = self.LIMITS.bits(mask)
val = self.LIMITS.bits(val)
if mask >= 0x100:
mask = 0
val &= 0xff
else:
val &= mask
return self.cmd('M', mask & 0xff, val)
def step(self, stepper=None, n=0, dir=None,
reset=False, ms=None, dac=None, limit=None, speed=None):
if limit is not None:
self.limit(limit)
if dac is not None:
self.dac(dac)
if speed is not None:
self.speed(speed)
if ms:
self.microstep(n=ms)
if reset:
self.cmd('r', 0x8000)
if stepper is None:
if dir is not None:
self.dir(dir)
return self.cmd('S', n)
if not n:
return self.cmd('0')
nn = n & ~(n-1)
if n//nn < 0x100:
while not n & 1 and dir < 0xf0:
n >>= 1
dir += 16
return self.cmd("012"[stepper], dir, n)
self.cmd("012"[stepper], dir)
return self.cmd('S', n)

View file

@ -88,7 +88,6 @@ if __name__=="__main__":
dorn.CONFIG.ahbgo()
armlib.set_prompt("AHBGO")
if o=="--leia":
dorn.CONFIG.leia()
armlib.set_prompt("LEIA")
import leia_stepper
st = leia_stepper.leia_stepper(ifc)