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_µ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
|
||||
|
|
|
|||
|
|
@ -35,10 +35,20 @@ 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+20 || $2+20 < T0)) {
|
||||
if (NE && ($2 > T0+7 || $2+7 < T0)) {
|
||||
N = NE
|
||||
TE0 = T0
|
||||
save = $0
|
||||
|
|
@ -65,14 +75,7 @@ function isCC() {
|
|||
i = NDCh * $3 + $4
|
||||
ELINES[i] = $0
|
||||
NE++
|
||||
if (N) {
|
||||
if (TE0 < 0x00ffffff && TLAST > 0xff000000) {
|
||||
EPOCH += 0x100000000
|
||||
TLAST = TE0
|
||||
} else if (TE0 > TLAST) {
|
||||
TLAST = TE0
|
||||
}
|
||||
}
|
||||
if (N) doEPOCH(TE0)
|
||||
return N
|
||||
}
|
||||
|
||||
|
|
@ -126,6 +129,8 @@ function isSETH() {
|
|||
}
|
||||
ETRIG0 = 0
|
||||
ETRIG1 = 0
|
||||
iTRIG0 = -1
|
||||
iTRIG1 = 48
|
||||
for (i in cTRIG) {
|
||||
if (EE[i] > ETRIG0) {
|
||||
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}
|
||||
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
|
||||
|
|
@ -159,7 +174,7 @@ class DORN_CONFIG:
|
|||
HK4_AHBGO = [[
|
||||
("Tbgo₁", (degC, {})),
|
||||
("Tbgo₂", (degC, {})),
|
||||
("Vbias", -1/0.047),
|
||||
("Vbias1", -1/0.047),
|
||||
("Tbgo₃", (degC, {})),
|
||||
("Ibias₁", 10470/470 * 51/1051 * 100),
|
||||
("Ibias₂", 10470/470 * 51/1051 * 100),
|
||||
|
|
@ -171,9 +186,37 @@ 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, what="print", data=None):
|
||||
def hk(sl=0, what="print", data=None):
|
||||
if not data:
|
||||
ecmd("alt/stream/off")
|
||||
_ifc.menable()
|
||||
|
|
@ -207,6 +250,7 @@ def hk(sl, 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)
|
||||
|
|
@ -228,11 +272,12 @@ def hk(sl, 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] += V[H[2][0]] * H[2][1]
|
||||
data[a][c] += VV[H[2][0]] * H[2][1]
|
||||
else:
|
||||
data[a][c] += H[2]
|
||||
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
|
||||
|
||||
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):
|
||||
|
|
@ -184,13 +211,15 @@ class leia_stepper:
|
|||
b = struct.pack(self.STATF, *bb)
|
||||
return b
|
||||
|
||||
def read_conf(self, unpack=True):
|
||||
def read_conf(self, stat=False, 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)
|
||||
|
|
@ -241,6 +270,14 @@ 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,
|
||||
|
|
@ -266,7 +303,7 @@ class leia_stepper:
|
|||
if what == self.ADC_V["period"]:
|
||||
val = int(val/self.T0TICK + 0.5) # ms
|
||||
else:
|
||||
raise ValueError("fload not supported for this whatsit")
|
||||
raise ValueError("float 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")
|
||||
|
|
@ -281,13 +318,7 @@ class leia_stepper:
|
|||
raise self.Stepper_Error(f"{c}, {val}, {what} → {r}")
|
||||
return r & 0xff
|
||||
|
||||
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)
|
||||
def dac(self, volt=None, dac=None, ramp=True, ms=None):
|
||||
if ms is not None:
|
||||
t = self.adc(what="period")*self.T0TICK
|
||||
p = int(t * 64/ ms + 0.5)
|
||||
|
|
@ -298,20 +329,28 @@ 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 *= self.Vcc/Vref
|
||||
a *= Vref/self.Vcc
|
||||
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, "uncal"),
|
||||
3: ("Iprim", 1.0, "A"),
|
||||
8: ("NTC1", Temp, "°C"),
|
||||
9: ("NTC2", Temp, "°C"),
|
||||
10: ("NTC3", Temp, "°C"),
|
||||
|
|
@ -323,6 +362,7 @@ class leia_stepper:
|
|||
|
||||
Vcc = 3.3
|
||||
T0TICK = 0.0925925925925926
|
||||
T1TICK = T0TICK/4
|
||||
|
||||
def read_adcs(self, chs=tuple(range(16)), update_vcc=True):
|
||||
r = []
|
||||
|
|
@ -372,3 +412,217 @@ 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)
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ 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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue