Compare commits

..

6 commits

Author SHA1 Message Date
Stephan I. Böttcher
1e8ea97f27 turbo.py: resp(), clear checksum 2024-10-06 17:42:12 +02:00
Stephan I. Böttcher
8467e79852 bate.c: clear uart_cks after line_preamble 2024-10-06 17:41:33 +02:00
Stephan I. Böttcher
7270c83dfc cmd.py: fix -R 2024-10-06 17:07:15 +02:00
Stephan I. Böttcher
4453851d1d turbo.py: emit_adc_pretty() 2024-10-06 15:38:42 +02:00
Stephan I. Böttcher
ea5ddb16b9 turbo.py: add config parsers 2024-10-06 10:20:00 +02:00
Stephan I. Böttcher
7c302b74ed cmd.py: fix ADC_MODE 2024-10-06 10:19:13 +02:00
3 changed files with 292 additions and 16 deletions

View file

@ -545,8 +545,10 @@ int main()
if (!rfen_status()) { if (!rfen_status()) {
if (config.power & POWER_RF) if (config.power & POWER_RF)
rfen(1); rfen(1);
if (config.power & POWER_LINE) if (config.power & POWER_LINE) {
send_str(config.line_preable); send_str(config.line_preable);
uart_cks = 0;
}
} }
if (config.power & POWER_LED) if (config.power & POWER_LED)
led(1); led(1);

View file

@ -270,7 +270,7 @@ class turbocmd(cmdsocket.cmder):
if len(ll)==3 and ll[1] in "BD": if len(ll)==3 and ll[1] in "BD":
self.symbols[ll[2]] = int(ll[0], 16) & 0xffff self.symbols[ll[2]] = int(ll[0], 16) & 0xffff
ADC_MODE = {"DIFF": 0x51, "NORM": 0xd1} ADC_MODE = {"DIFF": 0xd1, "NORM": 0x51}
ADC_REF = {"VDD": 0x50, "1V": 0x54, "2V": 0x55, "2.5V": 0x56, "4V": 0x57} ADC_REF = {"VDD": 0x50, "1V": 0x54, "2V": 0x55, "2.5V": 0x56, "4V": 0x57}
ADC_INP = {"GND": 0x30, "VDD": 0x31, "TEMP": 0x32, "RFP": 4, "NTC": 6, "BAT": 7} ADC_INP = {"GND": 0x30, "VDD": 0x31, "TEMP": 0x32, "RFP": 4, "NTC": 6, "BAT": 7}
ADC_CONF = { ADC_CONF = {
@ -429,7 +429,7 @@ def main(argv):
if o=="-W": if o=="-W":
last_cmd = cmd.mem last_cmd = cmd.mem
if o=="-R": if o=="-R":
cmd.value(b'R', 0xd8) cmd.value(b'R', '0xd8')
if o=="-D": if o=="-D":
cmd.value(b'D', v) cmd.value(b'D', v)
if o=="-T": if o=="-T":

View file

@ -3,7 +3,7 @@
import sys, time, getopt, serial, fileinput import sys, time, getopt, serial, fileinput
import pressure, ntc, linear_regression, cmdsocket import pressure, ntc, linear_regression, cmdsocket
options, files = getopt.gnu_getopt(sys.argv[1:], "xF:s:o:c", ["tty=", "noise", "clock", "socket=", "output="]) options, files = getopt.gnu_getopt(sys.argv[1:], "xF:s:o:c", ["debug", "tty=", "noise", "clock", "socket=", "output="])
tty = None tty = None
socket = None socket = None
@ -11,8 +11,18 @@ out = None
do_noise = False do_noise = False
do_clock = False do_clock = False
debug = False
def Debug(e, *a):
if debug:
import traceback
sys.stdout.flush()
print("xdebug", a, repr(e), file=sys.stderr)
traceback.print_exception(e, limit=-2, file=sys.stderr)
for o,v in options: for o,v in options:
if o == "--debug":
debug = True
if o in "-F --tty": if o in "-F --tty":
if tty: if tty:
raise ValueError("can only do one tty") raise ValueError("can only do one tty")
@ -61,7 +71,11 @@ def add_checksum(line):
# noise(line, "s") # noise(line, "s")
def noise(line, prefix="x"): def noise(line, prefix="x"):
print(prefix, repr(line), file=out) trunc = ""
if len(line)>40:
line = line[:40]
trunc = ""
print(prefix, repr(line), trunc, file=out)
return False return False
def echo(line, *a): def echo(line, *a):
@ -75,7 +89,7 @@ def echo(line, *a):
def check_sum(line): def check_sum(line):
global checksum global checksum
try: try:
rcs = int(line.strip()[1:], 16) rcs = int(line.split()[0][1:], 16)
except: except:
return noise(line) return noise(line)
if rcs > 0xff: if rcs > 0xff:
@ -143,24 +157,283 @@ def clock(line):
return echo(line) return echo(line)
return echo(line, f"{c} {t:.1f}", *("%.4g" % ss for ss in s[0])) return echo(line, f"{c} {t:.1f}", *("%.4g" % ss for ss in s[0]))
Data = {}
def data(line):
ll = line.split()
try:
c = ll[0]
Data[c] = [int(l, 16) for l in ll[1:]]
emit_data(c)
return echo(line)
except Exception as e:
Debug(e, line)
return noise(line, "h")
def sigrow(line):
try:
c = line[:1]
Data[c] = [int(line[i:i+2], 16) for i in range(1,len(line.strip()),2)]
emit_data(c)
return echo(line)
except Exception as e:
Debug(e, line)
return noise(line, "h")
def emit_data(c):
if c not in emitters:
return
try:
return emitters[c](c, Data[c])
except Exception as e:
Debug(e, c)
def emit_pressure(c, cc):
W = [None]
D = [None]
W.extend(Data[b'W'])
D.extend(Data[b'D'])
if len(W) != 5 or len(D) != 3:
return
try:
T, p = pressure.calibrate(W, D)
except Exception as e:
print(f"pressure.calibrate failed {e}", file=sys.stderr)
print(f"p {p/10:.2f} mbar, {T/10:.2f} °C")
from cmd import turbocmd
millivolts = {
"VDD": 1000,
"1V": 1024,
"2V": 2048,
"2.5V": 2500,
"4V": 4096,
}
ADC_mV = {}
def emit_adc(c, cc):
if len(cc) > 8:
return
for n, a in enumerate(cc):
C = ADC_CONFIG[n]
if C is None:
continue
if C["mode"] == turbocmd.ADC_MODE["DIFF"]:
if a & 0x8000:
a -= 0x10000
elif C["mode"] != turbocmd.ADC_MODE["NORM"]:
continue
REF = None
for k, i in turbocmd.ADC_REF.items():
if C["ref"] == i:
REF = k
mV = millivolts[k]
if REF is None:
continue
A = a * mV / 0x10000
inp = "?"
inn = ""
for k, i in turbocmd.ADC_INP.items():
if C["inp"] == i:
inp = k
if C["mode"] == turbocmd.ADC_MODE["DIFF"]:
if C["inn"] == i:
inn = "-"+k
inp = inp+inn+"/"+REF
ADC_mV[inp] = (A, mV)
emit_adc_pretty()
def emit_adc_pretty():
for k, a in ADC_mV.items():
A, mV = a
units = "V ref"
pretty = ""
kk = k.split("/")
if kk[0] == "TEMP":
try:
T = (A/mV*0x10000 - TEMP_CAL["offset"]) * TEMP_CAL["gain"] - 273.16
pretty = f" Tcpu {T:.2f} °C"
except Exception as e:
Debug(e, k)
if kk[0] == "NTC":
try:
AA, x = ADC_mV["RFP/"+kk[1]]
T = NTC.TntcB(A-AA, AA)
pretty = f" Tntc {T:.2f} °C"
except Exception as e:
Debug(e, k)
if kk[0] == "NTC-RFP":
try:
AA, x = ADC_mV["RFP/2.5V"]
T = NTC.TntcB(A, AA)
pretty = f" Tntc {T:.2f} °C"
except Exception as e:
Debug(e, k)
if kk[0] == "VDD":
pretty = f" Vdd {A/100:.4f} V"
if kk[0] == "BAT":
pretty = f" Vbat {A/1000*11:.4f} V"
if k == "RFP/2.5V":
pretty = f" Vrf {A/500:.4f} V"
if kk[1] == "VDD":
units=" Vdd"
try:
AA, x = ADC_mV["VDD/1V"]
mV = AA*10
pretty += f" {kk[0]} {A*mV/1e6:.4f} V"
except Exception as e:
Debug(e, k)
try:
AA, x = ADC_mV[kk[0]+"/2.5V"]
pretty += f" Vdd {AA/A:.4f} V"
except Exception as e:
Debug(e, k)
print(f"a {k:10} {A/1000:.5f} {units} {mV/1000:.3f} V{pretty}")
def emit_configuration(c, cc):
c = c.lower().decode()
if len(cc) != 32:
return
for r,v in turbocmd.REGS.items():
a = v[0]
b = cc[a]
if v[1] == 2:
b |= cc[a+1] << 8
if len(v) >= 3:
bb = []
for k,i in v[2].items():
if not ~b & i:
bb.append(k)
print(c, r, bb)
continue
if v[1] < 3:
print(c, r, "%02x" % b)
continue
print(c, r, " ".join([f"0x{b:02x}" for b in cc[a:a+v[1]]]))
ADC_CONFIG = [None]*8
def emit_eeprom(c, cc):
if len(cc) < 32:
return
for n in range(8):
bb = [""]*7
aa = {}
for r,v in turbocmd.ADC_CONF.items():
a = 8*n + v[0]
b = cc[a//2]
if v[1]==1:
if a&1:
b >>= 8
b &= 0xff
bb[v[0]] = f"{b}"
aa[r] = b
for k, i in v[2].items():
if b==i:
bb[v[0]] = k
ADC_CONFIG[n] = aa
print("e", n, " ".join(bb))
SIGROW = {
"DEVID": (0, 3),
"SERNO": (3, 10),
"OSCCAL": (0x18, 4),
"TEMPSENS": (0x20, 2),
}
DEVID = {
0x1e922a: "ATtiny427",
0x1e922b: "ATtiny426",
0x1e922c: "ATtiny424",
0x1e9327: "ATtiny827",
0x1e9328: "ATtiny826",
0x1e9329: "ATtiny824",
}
def devid():
cc = Data[b'S'][2::-1]
return sum([b << (8*i) for i,b in enumerate(cc)])
TEMP_CAL = {"gain": 0, "offset": 0}
def emit_sigrow(c, cc):
if len(cc)<34:
return
for r,v in SIGROW.items():
print(f"s {r} {" ".join([f"{i:02x}" for i in cc[v[0]:v[0]+v[1]]])}")
i = devid()
if i in DEVID:
print(f"s DEVICE 0x{i:06x} {DEVID[i]} SN {bytes(cc[3:13])}")
v = SIGROW["TEMPSENS"]
g = cc[v[0]]
o = cc[v[0]+1]
if o & 0x80:
o -= 0x100
o <<= 6
g /= 1 << (6+8)
TEMP_CAL.update({"gain": g, "offset": o})
print(f"s ADC_CAL offset {o} gain {g:.7f}")
FUSES = {
"WDT": (0, {"PERIOD": (0,0xf), "WINDOW": (4,0xf)}),
"BOD": (1, {"SLEEP": (0,3), "ACTIVE": (2,3), "SAMPFREQ": (4,1), "LVL": (5,7)}),
"OSC": (2, {"OSCLOCK": (7,1), "FREQSEL": (0,1)}),
"SYS0": (5, {"EESAVE": (0,1), "RSTPIN": (2,3), "TOUTDIS": (4,1), "CRCSRC": (6,3)}),
"SYS1": (6, {"SUT": (0,7)}),
"APPEND": (7, {}),
"BOOTEND": (8, {}),
}
def emit_fuses(c, cc):
if len(cc) != 9:
return
for r,v in FUSES.items():
b = cc[v[0]]
bb = f"f {v[0]} {r} 0x{b:02x}"
for k,i in v[1].items():
bb += f" {k}={(b >> i[0]) & i[1]}"
print(bb)
emitters = {
b'C': emit_configuration,
b'U': emit_configuration,
b'E': emit_eeprom,
b'S': emit_sigrow,
b'F': emit_fuses,
b'D': emit_pressure,
b'A': emit_adc,
}
def resp(line):
ll = line.split()
if line[1] not in b'!?>':
return noise(line)
echo(line)
checksum = 0
return False
def emit(): def emit():
pass pass
processes = { processes = {
b'A': echo, b'A': data,
b'B': echo, b'B': echo,
b'C': echo, b'C': data,
b'D': echo, b'D': data,
b'E': echo, b'E': data,
b'F': echo, b'F': data,
b'P': echo, b'P': echo,
b'Q': check_sum, b'Q': check_sum,
b'R': echo, b'R': resp,
b'S': echo, b'S': sigrow,
b'T': clock, b'T': clock,
b'U': echo, b'U': data,
b'V': voltages, b'V': voltages,
b'W': echo, b'W': data,
b'X': echo, b'X': echo,
} }
@ -185,12 +458,13 @@ while True:
line_key = line[0:1] line_key = line[0:1]
is_noise = line_key not in processes is_noise = line_key not in processes
if 0 in line: if not is_noise and min(line.strip()) < 32:
is_noise = True is_noise = True
if is_noise: if is_noise:
if do_noise: if do_noise:
noise(line) noise(line)
check_sum = 0
continue continue
if processes[line_key](line): if processes[line_key](line):