Compare commits
14 commits
d5e4d19165
...
70cefb78d3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70cefb78d3 | ||
|
|
8539542690 | ||
|
|
bb8884d2ca | ||
|
|
57e99bf199 | ||
|
|
8ed1b837f0 | ||
|
|
4269bd8293 | ||
|
|
c5a8f7fef2 | ||
|
|
10f2815e5d | ||
|
|
dd879c5433 | ||
|
|
9aee6531e0 | ||
|
|
1310ad3e53 | ||
|
|
0c8591a6ef | ||
|
|
8220f10bcb | ||
|
|
122a9fb802 |
15 changed files with 401 additions and 25 deletions
2
Makefile
2
Makefile
|
|
@ -228,8 +228,10 @@ 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,10 +35,20 @@ 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+20 || $2+20 < T0)) {
|
if (NE && ($2 > T0+7 || $2+7 < T0)) {
|
||||||
N = NE
|
N = NE
|
||||||
TE0 = T0
|
TE0 = T0
|
||||||
save = $0
|
save = $0
|
||||||
|
|
@ -65,14 +75,7 @@ function isCC() {
|
||||||
i = NDCh * $3 + $4
|
i = NDCh * $3 + $4
|
||||||
ELINES[i] = $0
|
ELINES[i] = $0
|
||||||
NE++
|
NE++
|
||||||
if (N) {
|
if (N) doEPOCH(TE0)
|
||||||
if (TE0 < 0x00ffffff && TLAST > 0xff000000) {
|
|
||||||
EPOCH += 0x100000000
|
|
||||||
TLAST = TE0
|
|
||||||
} else if (TE0 > TLAST) {
|
|
||||||
TLAST = TE0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return N
|
return N
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,6 +129,8 @@ 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 50f46b8494bbba65ccbec124f4fd4d9c0c4b72a3
|
Subproject commit 7ebd848bd2e58dc30c966ebf915f7ce6ff8e77df
|
||||||
53
dorn.py
53
dorn.py
|
|
@ -47,9 +47,24 @@ 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
|
||||||
|
|
@ -159,7 +174,7 @@ class DORN_CONFIG:
|
||||||
HK4_AHBGO = [[
|
HK4_AHBGO = [[
|
||||||
("Tbgo₁", (degC, {})),
|
("Tbgo₁", (degC, {})),
|
||||||
("Tbgo₂", (degC, {})),
|
("Tbgo₂", (degC, {})),
|
||||||
("Vbias", -1/0.047),
|
("Vbias1", -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),
|
||||||
|
|
@ -171,9 +186,37 @@ 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, what="print", data=None):
|
def hk(sl=0, what="print", data=None):
|
||||||
if not data:
|
if not data:
|
||||||
ecmd("alt/stream/off")
|
ecmd("alt/stream/off")
|
||||||
_ifc.menable()
|
_ifc.menable()
|
||||||
|
|
@ -207,6 +250,7 @@ def hk(sl, 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)
|
||||||
|
|
@ -228,11 +272,12 @@ def hk(sl, 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] += V[H[2][0]] * H[2][1]
|
data[a][c] += VV[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]
|
||||||
|
|
|
||||||
8
flash_LEIA/CRON.RC
Normal file
8
flash_LEIA/CRON.RC
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
@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
|
||||||
12
flash_LEIA/DORN.RC
Normal file
12
flash_LEIA/DORN.RC
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
@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
|
||||||
30
flash_LEIA/DORNCC.RC
Normal file
30
flash_LEIA/DORNCC.RC
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
@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
|
||||||
10
flash_LEIA/INIT.RC
Normal file
10
flash_LEIA/INIT.RC
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
@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"
|
||||||
BIN
flash_LEIA/NMLEIAV1.RBF
Normal file
BIN
flash_LEIA/NMLEIAV1.RBF
Normal file
Binary file not shown.
BIN
flash_LEIA/NMLEIAV2.RBF
Normal file
BIN
flash_LEIA/NMLEIAV2.RBF
Normal file
Binary file not shown.
7
flash_LEIA/README.TXT
Normal file
7
flash_LEIA/README.TXT
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
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
|
||||||
2
flash_LEIA/SN2.RC
Normal file
2
flash_LEIA/SN2.RC
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
@v bate_hash = 0x3921
|
||||||
|
pres/read/verify
|
||||||
BIN
flash_tarena/TARENA.RBF
Normal file
BIN
flash_tarena/TARENA.RBF
Normal file
Binary file not shown.
276
leia_stepper.py
276
leia_stepper.py
|
|
@ -1,6 +1,33 @@
|
||||||
|
|
||||||
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):
|
||||||
|
|
@ -184,13 +211,15 @@ class leia_stepper:
|
||||||
b = struct.pack(self.STATF, *bb)
|
b = struct.pack(self.STATF, *bb)
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def read_conf(self, unpack=True):
|
def read_conf(self, stat=False, 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)
|
||||||
|
|
@ -241,6 +270,14 @@ 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,
|
||||||
|
|
@ -266,7 +303,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("fload not supported for this whatsit")
|
raise ValueError("float 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")
|
||||||
|
|
@ -281,13 +318,7 @@ 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=0.0, dac=None, ramp=True, ms=None):
|
def dac(self, volt=None, 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)
|
||||||
|
|
@ -298,20 +329,28 @@ 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 *= self.Vcc/Vref
|
a *= Vref/self.Vcc
|
||||||
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, "uncal"),
|
3: ("Iprim", 1.0, "A"),
|
||||||
8: ("NTC1", Temp, "°C"),
|
8: ("NTC1", Temp, "°C"),
|
||||||
9: ("NTC2", Temp, "°C"),
|
9: ("NTC2", Temp, "°C"),
|
||||||
10: ("NTC3", Temp, "°C"),
|
10: ("NTC3", Temp, "°C"),
|
||||||
|
|
@ -323,6 +362,7 @@ 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 = []
|
||||||
|
|
@ -372,3 +412,217 @@ 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,6 +88,7 @@ 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