Compare commits
No commits in common. "70cefb78d34a276953b12580a22245433954ed7e" and "d5e4d19165d37cfd13ccbc85664b9e8261e9d19e" have entirely different histories.
70cefb78d3
...
d5e4d19165
15 changed files with 25 additions and 401 deletions
2
Makefile
2
Makefile
|
|
@ -228,10 +228,8 @@ FATNAME_flash_TANOS=TANOS
|
||||||
FATNAME_flash_CHAOS=CHAOS
|
FATNAME_flash_CHAOS=CHAOS
|
||||||
FATNAME_flash_µM=IRENAuM
|
FATNAME_flash_µM=IRENAuM
|
||||||
FATNAME_flash_NMAHEPAM=NMAHEPAM
|
FATNAME_flash_NMAHEPAM=NMAHEPAM
|
||||||
FATNAME_flash_LEIA=LEIA
|
|
||||||
FATNAME=$(FATNAME_$(FLASH))
|
FATNAME=$(FATNAME_$(FLASH))
|
||||||
|
|
||||||
FATSIZE_flash_tarena=1M
|
|
||||||
FATSIZE_flash_pirena=1M
|
FATSIZE_flash_pirena=1M
|
||||||
FATSIZE_flash_darena=1M
|
FATSIZE_flash_darena=1M
|
||||||
FATSIZE_flash_erena=1M
|
FATSIZE_flash_erena=1M
|
||||||
|
|
|
||||||
|
|
@ -35,20 +35,10 @@ function isEE() {
|
||||||
return 1
|
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() {
|
function isCC() {
|
||||||
N = 0
|
N = 0
|
||||||
if (!/^EDB? /) return 0
|
if (!/^EDB? /) return 0
|
||||||
if (NE && ($2 > T0+7 || $2+7 < T0)) {
|
if (NE && ($2 > T0+20 || $2+20 < T0)) {
|
||||||
N = NE
|
N = NE
|
||||||
TE0 = T0
|
TE0 = T0
|
||||||
save = $0
|
save = $0
|
||||||
|
|
@ -75,7 +65,14 @@ function isCC() {
|
||||||
i = NDCh * $3 + $4
|
i = NDCh * $3 + $4
|
||||||
ELINES[i] = $0
|
ELINES[i] = $0
|
||||||
NE++
|
NE++
|
||||||
if (N) doEPOCH(TE0)
|
if (N) {
|
||||||
|
if (TE0 < 0x00ffffff && TLAST > 0xff000000) {
|
||||||
|
EPOCH += 0x100000000
|
||||||
|
TLAST = TE0
|
||||||
|
} else if (TE0 > TLAST) {
|
||||||
|
TLAST = TE0
|
||||||
|
}
|
||||||
|
}
|
||||||
return N
|
return N
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,8 +126,6 @@ function isSETH() {
|
||||||
}
|
}
|
||||||
ETRIG0 = 0
|
ETRIG0 = 0
|
||||||
ETRIG1 = 0
|
ETRIG1 = 0
|
||||||
iTRIG0 = -1
|
|
||||||
iTRIG1 = 48
|
|
||||||
for (i in cTRIG) {
|
for (i in cTRIG) {
|
||||||
if (EE[i] > ETRIG0) {
|
if (EE[i] > ETRIG0) {
|
||||||
ETRIG0 = EE[i]
|
ETRIG0 = EE[i]
|
||||||
|
|
|
||||||
2
avr
2
avr
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7ebd848bd2e58dc30c966ebf915f7ce6ff8e77df
|
Subproject commit 50f46b8494bbba65ccbec124f4fd4d9c0c4b72a3
|
||||||
53
dorn.py
53
dorn.py
|
|
@ -47,24 +47,9 @@ def HK7_SETH_fmt(s, i, n, d):
|
||||||
return f"""{i}. {n}
|
return f"""{i}. {n}
|
||||||
na = {repr(d[:4])}
|
na = {repr(d[:4])}
|
||||||
Text = {d[6]:.1f} °C,
|
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.
|
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:
|
class DORN_CONFIG:
|
||||||
# stis_ana_core 2×24 ch
|
# stis_ana_core 2×24 ch
|
||||||
|
|
@ -174,7 +159,7 @@ class DORN_CONFIG:
|
||||||
HK4_AHBGO = [[
|
HK4_AHBGO = [[
|
||||||
("Tbgo₁", (degC, {})),
|
("Tbgo₁", (degC, {})),
|
||||||
("Tbgo₂", (degC, {})),
|
("Tbgo₂", (degC, {})),
|
||||||
("Vbias1", -1/0.047),
|
("Vbias", -1/0.047),
|
||||||
("Tbgo₃", (degC, {})),
|
("Tbgo₃", (degC, {})),
|
||||||
("Ibias₁", 10470/470 * 51/1051 * 100),
|
("Ibias₁", 10470/470 * 51/1051 * 100),
|
||||||
("Ibias₂", 10470/470 * 51/1051 * 100),
|
("Ibias₂", 10470/470 * 51/1051 * 100),
|
||||||
|
|
@ -186,37 +171,9 @@ class DORN_CONFIG:
|
||||||
# ! change the class attribute .HK
|
# ! change the class attribute .HK
|
||||||
self.HK[4] = ("HK PA", self.HK4_AHBGO, HK4_AHBGO_fmt)
|
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()
|
CONFIG = DORN_CONFIG()
|
||||||
|
|
||||||
def hk(sl=0, what="print", data=None):
|
def hk(sl, what="print", data=None):
|
||||||
if not data:
|
if not data:
|
||||||
ecmd("alt/stream/off")
|
ecmd("alt/stream/off")
|
||||||
_ifc.menable()
|
_ifc.menable()
|
||||||
|
|
@ -250,7 +207,6 @@ def hk(sl=0, what="print", data=None):
|
||||||
return sl, data
|
return sl, data
|
||||||
Vref = CONFIG.Vref(sl)/4096
|
Vref = CONFIG.Vref(sl)/4096
|
||||||
ddata = []
|
ddata = []
|
||||||
VV = {"Vref": CONFIG.Vref(sl)}
|
|
||||||
for a in range(8):
|
for a in range(8):
|
||||||
V = {}
|
V = {}
|
||||||
ddata.append(V)
|
ddata.append(V)
|
||||||
|
|
@ -272,12 +228,11 @@ def hk(sl=0, what="print", data=None):
|
||||||
else:
|
else:
|
||||||
data[a][c] *= Vref*H[1]
|
data[a][c] *= Vref*H[1]
|
||||||
V[H[0]] = data[a][c]
|
V[H[0]] = data[a][c]
|
||||||
VV.update(V)
|
|
||||||
for c in range(8):
|
for c in range(8):
|
||||||
H = HK[c]
|
H = HK[c]
|
||||||
if len(H) > 2:
|
if len(H) > 2:
|
||||||
if isinstance(H[2], tuple):
|
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:
|
else:
|
||||||
data[a][c] += H[2]
|
data[a][c] += H[2]
|
||||||
V[H[0]] = data[a][c]
|
V[H[0]] = data[a][c]
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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.
|
|
@ -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
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
@v bate_hash = 0x3921
|
|
||||||
pres/read/verify
|
|
||||||
Binary file not shown.
276
leia_stepper.py
276
leia_stepper.py
|
|
@ -1,33 +1,6 @@
|
||||||
|
|
||||||
import sys, armlib, struct, math, time
|
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 leia_stepper:
|
||||||
|
|
||||||
class Stepper_Error(armlib.irena_ifc.IrenaError):
|
class Stepper_Error(armlib.irena_ifc.IrenaError):
|
||||||
|
|
@ -211,15 +184,13 @@ class leia_stepper:
|
||||||
b = struct.pack(self.STATF, *bb)
|
b = struct.pack(self.STATF, *bb)
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def read_conf(self, stat=False, unpack=True):
|
def read_conf(self, unpack=True):
|
||||||
b = []
|
b = []
|
||||||
while True:
|
while True:
|
||||||
r = self.cmd('x', len(b), Error=True, sleep=0.001)
|
r = self.cmd('x', len(b), Error=True, sleep=0.001)
|
||||||
if r & 0xff0000:
|
if r & 0xff0000:
|
||||||
break
|
break
|
||||||
b.append(r & 0xff)
|
b.append(r & 0xff)
|
||||||
if not stat and len(b) >= self.CONFF.size:
|
|
||||||
break
|
|
||||||
b = bytes(b)
|
b = bytes(b)
|
||||||
if unpack and b[:2]==self.CONFM and b[2] in self.CONFV:
|
if unpack and b[:2]==self.CONFM and b[2] in self.CONFV:
|
||||||
return self.confdict(b)
|
return self.confdict(b)
|
||||||
|
|
@ -270,14 +241,6 @@ class leia_stepper:
|
||||||
n = i+1
|
n = i+1
|
||||||
return b[:n]
|
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 = {
|
ADC_V = {
|
||||||
"data": 0,
|
"data": 0,
|
||||||
"mux": 1,
|
"mux": 1,
|
||||||
|
|
@ -303,7 +266,7 @@ class leia_stepper:
|
||||||
if what == self.ADC_V["period"]:
|
if what == self.ADC_V["period"]:
|
||||||
val = int(val/self.T0TICK + 0.5) # ms
|
val = int(val/self.T0TICK + 0.5) # ms
|
||||||
else:
|
else:
|
||||||
raise ValueError("float not supported for this whatsit")
|
raise ValueError("fload not supported for this whatsit")
|
||||||
if enable is not None:
|
if enable is not None:
|
||||||
if what and enable and val is not None:
|
if what and enable and val is not None:
|
||||||
raise ValueError("cannot enable and read a whatsit")
|
raise ValueError("cannot enable and read a whatsit")
|
||||||
|
|
@ -318,7 +281,13 @@ class leia_stepper:
|
||||||
raise self.Stepper_Error(f"{c}, {val}, {what} → {r}")
|
raise self.Stepper_Error(f"{c}, {val}, {what} → {r}")
|
||||||
return r & 0xff
|
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:
|
if ms is not None:
|
||||||
t = self.adc(what="period")*self.T0TICK
|
t = self.adc(what="period")*self.T0TICK
|
||||||
p = int(t * 64/ ms + 0.5)
|
p = int(t * 64/ ms + 0.5)
|
||||||
|
|
@ -329,28 +298,20 @@ class leia_stepper:
|
||||||
self.cmd('P', p)
|
self.cmd('P', p)
|
||||||
if self._verbose >= 1:
|
if self._verbose >= 1:
|
||||||
print(f"DAC ramp speed {t*64/p:.1f} ms/step", file=sys.stderr)
|
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)
|
old = self.cmd('D', dac)
|
||||||
if self._verbose >= 1:
|
if self._verbose >= 1:
|
||||||
print(f"DAC set to 0x{dac:04x}, old value: 0x{old:04x}",
|
print(f"DAC set to 0x{dac:04x}, old value: 0x{old:04x}",
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
|
|
||||||
def Temp(self, a, Vref, **aa):
|
def Temp(self, a, Vref, **aa):
|
||||||
a *= Vref/self.Vcc
|
a *= self.Vcc/Vref
|
||||||
return armlib.NTC(a, β=3940)
|
return armlib.NTC(a, β=3940)
|
||||||
|
|
||||||
def AVR_Temp(self, a, Vref, **aa):
|
def AVR_Temp(self, a, Vref, **aa):
|
||||||
return a/64 * 2.5/Vref - 273
|
return a/64 * 2.5/Vref - 273
|
||||||
|
|
||||||
ADC_MUX = {
|
ADC_MUX = {
|
||||||
3: ("Iprim", 1.0, "A"),
|
3: ("Iprim", 1.0, "uncal"),
|
||||||
8: ("NTC1", Temp, "°C"),
|
8: ("NTC1", Temp, "°C"),
|
||||||
9: ("NTC2", Temp, "°C"),
|
9: ("NTC2", Temp, "°C"),
|
||||||
10: ("NTC3", Temp, "°C"),
|
10: ("NTC3", Temp, "°C"),
|
||||||
|
|
@ -362,7 +323,6 @@ class leia_stepper:
|
||||||
|
|
||||||
Vcc = 3.3
|
Vcc = 3.3
|
||||||
T0TICK = 0.0925925925925926
|
T0TICK = 0.0925925925925926
|
||||||
T1TICK = T0TICK/4
|
|
||||||
|
|
||||||
def read_adcs(self, chs=tuple(range(16)), update_vcc=True):
|
def read_adcs(self, chs=tuple(range(16)), update_vcc=True):
|
||||||
r = []
|
r = []
|
||||||
|
|
@ -412,217 +372,3 @@ class leia_stepper:
|
||||||
pass
|
pass
|
||||||
print(" done.\n", self.ifc.cmd("spi/reset/ssel"), file=sys.stderr)
|
print(" done.\n", self.ifc.cmd("spi/reset/ssel"), file=sys.stderr)
|
||||||
print("commit: ", self.id(), 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)
|
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,6 @@ if __name__=="__main__":
|
||||||
dorn.CONFIG.ahbgo()
|
dorn.CONFIG.ahbgo()
|
||||||
armlib.set_prompt("AHBGO")
|
armlib.set_prompt("AHBGO")
|
||||||
if o=="--leia":
|
if o=="--leia":
|
||||||
dorn.CONFIG.leia()
|
|
||||||
armlib.set_prompt("LEIA")
|
armlib.set_prompt("LEIA")
|
||||||
import leia_stepper
|
import leia_stepper
|
||||||
st = leia_stepper.leia_stepper(ifc)
|
st = leia_stepper.leia_stepper(ifc)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue