Skip to content

Commit 6e3ece7

Browse files
committed
fix wrong bank calculation, add features in read/writereg
1 parent 347aca4 commit 6e3ece7

2 files changed

Lines changed: 94 additions & 3 deletions

File tree

pylab_ml/common/data.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,16 @@ def complement(value, bits):
6565
bvalue = formatstring.format(value)
6666
return int(''.join({'0': '1', '1': '0'}[x] for x in bvalue), 2)
6767

68+
def complement2(value, bits):
69+
"""2's complement representation from a value with number of bits."""
70+
if value >= 2**(bits-1):
71+
raise ValueError(f"complement2 value must be < {2**(bits-1)}")
72+
result = value if value >=0 else complement(-value, bits)+1
73+
return result & (2**bits -1)
6874

6975
def crc4(data): # width
7076
"""
71-
Calculate 4-bit crc from a data with widht bits.
77+
Calculate 4-bit crc from a data with width bits.
7278
7379
polynomial = X4+X+1
7480

pylab_ml/misc/registermaster.py

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
"""
2222

2323
import re
24+
import fnmatch
25+
import ast
26+
from typing import Iterable, List, Union
2427
import sys
2528
import os
2629
import pandas as pd
@@ -1303,12 +1306,15 @@ def init(self):
13031306
pass
13041307
object.__setattr__(self, "mapping", {})
13051308
object.__setattr__(self, "_len_slices", None)
1309+
object.__setattr__(self, "banks", {})
13061310
self.register = self.__dict__.copy() # create attribute register with all registernames
13071311
for reg in self.__dict__:
13081312
if reg != "register" and not hasattr(self.register[reg], "_Register__has_reset"):
13091313
self.register.pop(reg, None)
13101314
elif reg != "register":
13111315
bank = self.register[reg]._bank
1316+
if bank is not None and (bank not in self.banks or self.banks[bank] < self.register[reg].addr):
1317+
self.banks[bank] = self.register[reg].addr
13121318
if bank is not None and bank != "":
13131319
self.mapping[bank] = self.register[reg]._len_slices()
13141320
self.mqtt_list = list(self.register) + self.mqtt_all
@@ -1340,6 +1346,11 @@ def _mqtt2json(self, value, attr=None):
13401346
return value
13411347
return "nomqtt"
13421348

1349+
def _register_to_list(patterns: Union[str, Iterable[str]]) ->List[str]:
1350+
if isinstance(patterns, str):
1351+
return[patterns]
1352+
return list(patterns)
1353+
13431354
def close(self):
13441355
pass
13451356

@@ -1383,19 +1394,68 @@ def set_bank(self, adr):
13831394
-------
13841395
adr.
13851396
"""
1397+
if self.banks:
1398+
for bank in self.banks.keys():
1399+
if adr <= self.banks[bank]:
1400+
self._bank = bank
1401+
break
13861402
if self.mapping != {}:
13871403
mybank = 0
13881404
for bank in self.mapping:
13891405
mybank = bank if adr >= bank else mybank
1390-
self._bank = mybank
1406+
# self._bank = mybank
13911407
self._len_slices = self.mapping[mybank]
1392-
adr = adr - mybank
1408+
# adr = adr - mybank # TODO: cj 7.2.2026 das ist doch falsch, überprüfen mit HATC!!!!
13931409
else:
13941410
self._bank = None
13951411
self._len_slices = None
13961412
return adr
13971413

1414+
def _call_from_string(self, adr, callstr):
1415+
regs = self._register_to_list()
1416+
call = ast.parse(callstr, mode='eval').body
1417+
args = [ast.literal_eval(a) for a in call.args]
1418+
kwargs = {kw.arg:ast.literal_eval(kw.value) for kw in call.keywords}
1419+
index = 0
1420+
dat = args[0]
1421+
result = 0 if type(dat) == list else []
1422+
for reg in regs:
1423+
if fnmatch.fnmatchcase(reg._name, adr):
1424+
function = getattr(getattr(self, reg._name), call.func.id)
1425+
if type(dat) == list:
1426+
args[0] = dat[index]
1427+
resu = function(*args, **kwargs)
1428+
if type(dat) == list:
1429+
result += resu
1430+
else:
1431+
result.append(resu)
1432+
index += 1
1433+
return result
1434+
13981435
def readreg(self, adr, bank=None, compare=None, onlycheck=True, tolerance=0, mask=None):
1436+
if type(adr) is str:
1437+
if len(adr) == 0:
1438+
mylogger.log_message(LogLevel.Error(), 'readreg: adr is empty')
1439+
return
1440+
elif adr[0].isdigit():
1441+
adr = list(common.arange(adr))
1442+
else:
1443+
return self._call_from_string(adr, f"read({compare}, {onlycheck}, {tolerance}, {mask})")
1444+
if type(adr) is list:
1445+
result = [] if compare is None else 0
1446+
index = 0
1447+
for a in adr:
1448+
comp = compare[index] if type(compare) is list else compare
1449+
resu = self._readreg(a, bank, comp, onlycheck, tolerance, mask)
1450+
if compare is None:
1451+
result.append(resu)
1452+
else:
1453+
result += resu
1454+
index += 1
1455+
return result
1456+
return self._readreg(adr, bank, compare, onlycheck, tolerance, mask)
1457+
1458+
def _readreg(self, adr, bank=None, compare=None, onlycheck=True, tolerance=0, mask=None):
13991459
"""
14001460
Read Register with selected protokoll.
14011461
@@ -1417,13 +1477,16 @@ def readreg(self, adr, bank=None, compare=None, onlycheck=True, tolerance=0, mas
14171477
0 = ok
14181478
1 = error
14191479
"""
1480+
hadr = adr
14201481
if bank is not None:
14211482
self._bank = bank
14221483
else:
14231484
adr = self.set_bank(adr)
14241485
if self._bank is not None and self._bank != "":
14251486
self._protocol.writebase(self._bank)
14261487
value = self._protocol.readreg(adr, compare=compare, tolerance=tolerance, mask=mask)
1488+
mylogger.log_message(LogLevel.Measure(), f"readreg(0x{hadr:02x}) == {hex(value)}")
1489+
self.publish_set(f"readreg({hadr}:02x)", value)
14271490
if self._len_slices is not None:
14281491
value &= 2**self._len_slices - 1
14291492
if compare is not None:
@@ -1439,6 +1502,24 @@ def readreg(self, adr, bank=None, compare=None, onlycheck=True, tolerance=0, mas
14391502
return value
14401503

14411504
def writereg(self, adr, dat, bank=None):
1505+
if type(adr) is str:
1506+
if len(adr) == 0:
1507+
mylogger.log_message(LogLevel.Error(), 'writereg: adr is empty')
1508+
return
1509+
elif adr[0].isdigit():
1510+
adr = list(common.arange(adr))
1511+
else:
1512+
return self._call_from_string(adr, f"write({dat})")
1513+
if type(adr) is list:
1514+
index = 0
1515+
for a in adr:
1516+
d = dat[index] if type(dat) is list else dat
1517+
self._writereg(a, d, bank)
1518+
index += 1
1519+
return
1520+
self._writereg(adr, dat, bank)
1521+
1522+
def _writereg(self, adr, dat, bank=None):
14421523
"""
14431524
Write Register with selected protokoll.
14441525
@@ -1456,13 +1537,17 @@ def writereg(self, adr, dat, bank=None):
14561537
None.
14571538
14581539
"""
1540+
hadr = adr
14591541
if bank is not None:
14601542
self._bank = bank
14611543
else:
14621544
adr = self.set_bank(adr)
14631545
if self._bank is not None and self._bank != "":
14641546
self._protocol.writebase(self._bank)
14651547
self._protocol.writereg(adr, dat)
1548+
msg = f"writereg(0x{hadr:02x}) := {hex(dat)}"
1549+
mylogger.log_message(LogLevel.Measure(), msg)
1550+
self.publish_set(f"writereg({hadr})", dat)
14661551

14671552
def reset(self):
14681553
self._protocol.reset()

0 commit comments

Comments
 (0)