ekfsm 1.2.0a7__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ekfsm might be problematic. Click here for more details.
- ekfsm/boards/oem/hitron/hdrc-300s.yaml +1 -1
- ekfsm/cli.py +6 -8
- ekfsm/config.py +14 -6
- ekfsm/core/__init__.py +5 -5
- ekfsm/core/components.py +4 -4
- ekfsm/core/slots.py +6 -13
- ekfsm/core/sysfs.py +183 -13
- ekfsm/core/utils.py +104 -64
- ekfsm/devices/__init__.py +8 -7
- ekfsm/devices/coretemp.py +11 -10
- ekfsm/devices/eeprom.py +52 -39
- ekfsm/devices/ekf_ccu_uc.py +37 -46
- ekfsm/devices/ekf_sur_led.py +6 -2
- ekfsm/devices/generic.py +141 -88
- ekfsm/devices/gpio.py +33 -25
- ekfsm/devices/iio.py +15 -31
- ekfsm/devices/iio_thermal_humidity.py +12 -13
- ekfsm/devices/mux.py +11 -6
- ekfsm/devices/pmbus.py +60 -67
- ekfsm/devices/smbios.py +10 -8
- ekfsm/devices/smbus.py +1 -1
- ekfsm/devices/utils.py +0 -9
- ekfsm/exceptions.py +28 -7
- ekfsm/lock.py +1 -1
- ekfsm/simctrl.py +37 -83
- ekfsm/system.py +44 -70
- ekfsm/utils.py +9 -6
- {ekfsm-1.2.0a7.dist-info → ekfsm-1.3.0.dist-info}/METADATA +8 -5
- ekfsm-1.3.0.dist-info/RECORD +46 -0
- ekfsm-1.2.0a7.dist-info/RECORD +0 -46
- {ekfsm-1.2.0a7.dist-info → ekfsm-1.3.0.dist-info}/WHEEL +0 -0
- {ekfsm-1.2.0a7.dist-info → ekfsm-1.3.0.dist-info}/entry_points.txt +0 -0
ekfsm/devices/coretemp.py
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import glob
|
|
4
|
+
import os
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
import ekfsm.core
|
|
8
|
+
from ekfsm.core.sysfs import sysfs_root
|
|
7
9
|
from ekfsm.devices.generic import Device
|
|
8
10
|
|
|
9
11
|
# Path to the root of the HWMON sysfs filesystem
|
|
10
|
-
HWMON_ROOT =
|
|
12
|
+
HWMON_ROOT = sysfs_root() / Path("class/hwmon")
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
def find_core_temp_dir(hwmon_dir) -> Path:
|
|
@@ -48,16 +50,15 @@ class CoreTemp(Device):
|
|
|
48
50
|
self,
|
|
49
51
|
name: str,
|
|
50
52
|
parent: Device,
|
|
53
|
+
children: list["Device"] | None = None,
|
|
54
|
+
abort: bool = False,
|
|
51
55
|
*args,
|
|
52
56
|
**kwargs,
|
|
53
57
|
):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
self.sysfs_device: SysFSDevice = SysFSDevice(
|
|
57
|
-
find_core_temp_dir(SYSFS_ROOT / Path("class/hwmon"))
|
|
58
|
-
)
|
|
58
|
+
dir = find_core_temp_dir(sysfs_root() / Path("class/hwmon"))
|
|
59
|
+
self.sysfs_device = ekfsm.core.sysfs.SysfsDevice(dir, False)
|
|
59
60
|
|
|
60
|
-
super().__init__(name, parent, None, *args, **kwargs)
|
|
61
|
+
super().__init__(name, parent, None, abort, *args, **kwargs)
|
|
61
62
|
|
|
62
63
|
def cputemp(self):
|
|
63
64
|
"""
|
|
@@ -68,4 +69,4 @@ class CoreTemp(Device):
|
|
|
68
69
|
int
|
|
69
70
|
The CPU temperature in degrees Celsius.
|
|
70
71
|
"""
|
|
71
|
-
return
|
|
72
|
+
return self.sysfs.read_int("temp1_input") / 1000
|
ekfsm/devices/eeprom.py
CHANGED
|
@@ -11,18 +11,18 @@ Routine Listings
|
|
|
11
11
|
|
|
12
12
|
from abc import ABC, abstractmethod
|
|
13
13
|
from datetime import date
|
|
14
|
-
from typing import Any, Callable, Literal, Sequence
|
|
15
14
|
from functools import wraps
|
|
15
|
+
from typing import Any, Callable, Literal, Sequence
|
|
16
|
+
|
|
17
|
+
from hexdump import hexdump
|
|
16
18
|
|
|
17
19
|
from ekfsm.core.components import SysTree
|
|
18
20
|
from ekfsm.core.probe import ProbeableDevice
|
|
21
|
+
from ekfsm.exceptions import DataCorruptionError, DriverError, SysFSError
|
|
22
|
+
from ekfsm.log import ekfsm_logger
|
|
19
23
|
|
|
20
24
|
from .generic import Device
|
|
21
|
-
from .utils import
|
|
22
|
-
from ekfsm.exceptions import DataCorruptionError
|
|
23
|
-
from hexdump import hexdump
|
|
24
|
-
|
|
25
|
-
from ekfsm.log import ekfsm_logger
|
|
25
|
+
from .utils import get_crc16_xmodem
|
|
26
26
|
|
|
27
27
|
logger = ekfsm_logger(__name__)
|
|
28
28
|
|
|
@@ -80,13 +80,19 @@ class EEPROM(Device):
|
|
|
80
80
|
self,
|
|
81
81
|
name: str,
|
|
82
82
|
parent: SysTree | None = None,
|
|
83
|
+
children: list[Device] | None = None,
|
|
84
|
+
abort: bool = False,
|
|
83
85
|
*args,
|
|
84
86
|
**kwargs,
|
|
85
87
|
):
|
|
86
|
-
super().__init__(name, parent, None, *args, **kwargs)
|
|
88
|
+
super().__init__(name, parent, None, abort, *args, **kwargs)
|
|
87
89
|
|
|
88
90
|
self.addr = self.get_i2c_chip_addr()
|
|
89
91
|
self.sysfs_device = self.get_i2c_sysfs_device(self.addr)
|
|
92
|
+
|
|
93
|
+
if not self.sysfs_device.get_driver():
|
|
94
|
+
raise DriverError("No driver attached to device {self.name}")
|
|
95
|
+
|
|
90
96
|
self._update_content()
|
|
91
97
|
|
|
92
98
|
def _update_content(self) -> None:
|
|
@@ -117,20 +123,10 @@ class EEPROM(Device):
|
|
|
117
123
|
|
|
118
124
|
Raises
|
|
119
125
|
------
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
RuntimeError
|
|
123
|
-
If the sysfs device is not found.
|
|
126
|
+
SysFSError
|
|
127
|
+
No sysfs device found for EEPROM or `eeprom` attribute does not exist
|
|
124
128
|
"""
|
|
125
|
-
|
|
126
|
-
if self.sysfs_device:
|
|
127
|
-
cnt = self.sysfs_device.read_attr_bytes("eeprom")
|
|
128
|
-
else:
|
|
129
|
-
raise RuntimeError("No sysfs device for EEPROM")
|
|
130
|
-
except FileNotFoundError:
|
|
131
|
-
raise FileNotFoundError("EEPROM not found")
|
|
132
|
-
|
|
133
|
-
return cnt
|
|
129
|
+
return self.read_sysfs_bytes("eeprom")
|
|
134
130
|
|
|
135
131
|
def write(self, data: bytes, offset: int = 0) -> None:
|
|
136
132
|
"""
|
|
@@ -155,15 +151,27 @@ class EEPROM(Device):
|
|
|
155
151
|
Note
|
|
156
152
|
----
|
|
157
153
|
Operation is checked for data corruption by reading back the written data.
|
|
154
|
+
|
|
155
|
+
Important
|
|
156
|
+
---------
|
|
157
|
+
The offset parameter is only supported if the EEPROM driver is bin_attribute enabled.
|
|
158
|
+
|
|
159
|
+
For almost any other native sysfs attribute, this is NOT the case!
|
|
158
160
|
"""
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
161
|
+
|
|
162
|
+
if self.sysfs_device:
|
|
163
|
+
attr = next(x for x in self.sysfs_device.attributes if x.name == "eeprom")
|
|
164
|
+
logger.info(f"Writing {len(data)} bytes to EEPROM at offset {offset}")
|
|
165
|
+
if attr.is_sysfs_attr() and data is not None:
|
|
166
|
+
mode = "r+" if isinstance(data, str) else "rb+"
|
|
167
|
+
try:
|
|
168
|
+
with open(attr.path, mode) as f:
|
|
169
|
+
f.seek(offset)
|
|
170
|
+
f.write(data)
|
|
171
|
+
except OSError as e:
|
|
172
|
+
raise SysFSError("Error accessing SysFS attribute") from e
|
|
173
|
+
else:
|
|
174
|
+
raise RuntimeError("No sysfs device for EEPROM")
|
|
167
175
|
|
|
168
176
|
self._update_content()
|
|
169
177
|
written = self._content[offset : offset + len(data)]
|
|
@@ -202,6 +210,10 @@ class Validatable_EEPROM(EEPROM, ABC):
|
|
|
202
210
|
|
|
203
211
|
def __init__(
|
|
204
212
|
self,
|
|
213
|
+
name: str,
|
|
214
|
+
parent: SysTree | None = None,
|
|
215
|
+
children: list[Device] | None = None,
|
|
216
|
+
abort: bool = False,
|
|
205
217
|
crc_pos: Literal["start", "end"] = "end",
|
|
206
218
|
crc_length: int = 2,
|
|
207
219
|
*args,
|
|
@@ -210,7 +222,7 @@ class Validatable_EEPROM(EEPROM, ABC):
|
|
|
210
222
|
self._crc_length: int = crc_length
|
|
211
223
|
self._crc_pos: str = crc_pos
|
|
212
224
|
|
|
213
|
-
super().__init__(*args, **kwargs)
|
|
225
|
+
super().__init__(name, parent, children, abort, *args, **kwargs)
|
|
214
226
|
|
|
215
227
|
self._crc_pos_start = len(self._data) if self._crc_pos == "end" else 0
|
|
216
228
|
self._crc_pos_end = self._crc_pos_start + self._crc_length
|
|
@@ -388,13 +400,16 @@ class EKF_EEPROM(Validatable_EEPROM, ProbeableDevice):
|
|
|
388
400
|
|
|
389
401
|
def __init__(
|
|
390
402
|
self,
|
|
403
|
+
name: str,
|
|
404
|
+
parent: SysTree | None = None,
|
|
405
|
+
children: list[Device] | None = None,
|
|
406
|
+
abort: bool = False,
|
|
391
407
|
*args,
|
|
392
408
|
**kwargs,
|
|
393
409
|
) -> None:
|
|
394
|
-
super().__init__(*args, **kwargs)
|
|
410
|
+
super().__init__(name, parent, children, abort, *args, **kwargs)
|
|
395
411
|
|
|
396
412
|
def _update_content(self) -> None:
|
|
397
|
-
|
|
398
413
|
super()._update_content()
|
|
399
414
|
|
|
400
415
|
# EKF EEPROM content is restricted to 128 bytes, so strip the rest!
|
|
@@ -424,7 +439,7 @@ class EKF_EEPROM(Validatable_EEPROM, ProbeableDevice):
|
|
|
424
439
|
The serial number of the root device.
|
|
425
440
|
"""
|
|
426
441
|
area = self._content[self._sernum_index_start : self._sernum_index_end]
|
|
427
|
-
sernum =
|
|
442
|
+
sernum = int.from_bytes(area, byteorder="little")
|
|
428
443
|
return str(sernum)
|
|
429
444
|
|
|
430
445
|
def write_serial(self, serial: int) -> None:
|
|
@@ -461,7 +476,7 @@ class EKF_EEPROM(Validatable_EEPROM, ProbeableDevice):
|
|
|
461
476
|
area = self._content[
|
|
462
477
|
self._customer_serial_index_start : self._customer_serial_index_end
|
|
463
478
|
]
|
|
464
|
-
sernum =
|
|
479
|
+
sernum = int.from_bytes(area, byteorder="little")
|
|
465
480
|
return str(sernum)
|
|
466
481
|
|
|
467
482
|
def write_custom_serial(self, serial: int) -> None:
|
|
@@ -690,8 +705,7 @@ class EKF_EEPROM(Validatable_EEPROM, ProbeableDevice):
|
|
|
690
705
|
date
|
|
691
706
|
The decoded date.
|
|
692
707
|
"""
|
|
693
|
-
|
|
694
|
-
bdate = compute_int_from_bytes(encoded_date)
|
|
708
|
+
bdate = int.from_bytes(encoded_date, byteorder="little")
|
|
695
709
|
|
|
696
710
|
# Extract the day (bit 0-4)
|
|
697
711
|
day = bdate & 0x1F # 0x1F is 00011111 in binary (5 bits)
|
|
@@ -713,7 +727,7 @@ class EKF_EEPROM(Validatable_EEPROM, ProbeableDevice):
|
|
|
713
727
|
) # Handle invalid dates, e.g., 30th Feb
|
|
714
728
|
|
|
715
729
|
@classmethod
|
|
716
|
-
def _encode_date(
|
|
730
|
+
def _encode_date(cls, date: date) -> bytes:
|
|
717
731
|
"""
|
|
718
732
|
Encode a date into a proprietary 2-byte format.
|
|
719
733
|
|
|
@@ -772,7 +786,6 @@ class EKF_CCU_EEPROM(EKF_EEPROM):
|
|
|
772
786
|
super().__init__(*args, **kwargs)
|
|
773
787
|
|
|
774
788
|
def _update_content(self) -> None:
|
|
775
|
-
|
|
776
789
|
super()._update_content()
|
|
777
790
|
|
|
778
791
|
# CCU content is the raw content area of the EEPROM
|
|
@@ -933,7 +946,7 @@ class EKF_CCU_EEPROM(EKF_EEPROM):
|
|
|
933
946
|
area = self._content[
|
|
934
947
|
self._cserial_index_start : self._cserial_index_start + self._cserial_length
|
|
935
948
|
]
|
|
936
|
-
cserial =
|
|
949
|
+
cserial = int.from_bytes(area, byteorder="little")
|
|
937
950
|
return cserial
|
|
938
951
|
|
|
939
952
|
def write_cserial(self, serial: int) -> None:
|
|
@@ -998,7 +1011,7 @@ class EKF_CCU_EEPROM(EKF_EEPROM):
|
|
|
998
1011
|
The unit number of the subsystem.
|
|
999
1012
|
"""
|
|
1000
1013
|
area = self._content[self._unit_index_start]
|
|
1001
|
-
unit =
|
|
1014
|
+
unit = int.from_bytes([area], byteorder="little")
|
|
1002
1015
|
return unit
|
|
1003
1016
|
|
|
1004
1017
|
@validated
|
ekfsm/devices/ekf_ccu_uc.py
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
from smbus2 import SMBus
|
|
1
|
+
import struct
|
|
3
2
|
from enum import Enum
|
|
4
|
-
from typing import Tuple
|
|
3
|
+
from typing import Any, Tuple
|
|
4
|
+
|
|
5
|
+
from smbus2 import SMBus
|
|
6
|
+
|
|
5
7
|
from ekfsm.core.components import SysTree
|
|
8
|
+
|
|
6
9
|
from ..exceptions import AcquisitionError
|
|
7
10
|
from ..lock import Locker
|
|
11
|
+
from .generic import Device
|
|
8
12
|
from .imu import ImuSample
|
|
9
|
-
import struct
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
class CcuCommands(Enum):
|
|
@@ -37,10 +40,13 @@ class EKFCcuUc(Device):
|
|
|
37
40
|
self,
|
|
38
41
|
name: str,
|
|
39
42
|
parent: SysTree | None,
|
|
43
|
+
children: list["Device"] | None = None,
|
|
44
|
+
abort: bool = False,
|
|
45
|
+
debug: Any = None, # XXX: What is this?
|
|
40
46
|
*args,
|
|
41
47
|
**kwargs,
|
|
42
48
|
):
|
|
43
|
-
super().__init__(name, parent, None, *args, **kwargs)
|
|
49
|
+
super().__init__(name, parent, None, abort, *args, **kwargs)
|
|
44
50
|
self._i2c_addr = self.get_i2c_chip_addr()
|
|
45
51
|
self._i2c_bus = self.get_i2c_bus_number()
|
|
46
52
|
self._smbus = SMBus(self._i2c_bus)
|
|
@@ -69,10 +75,7 @@ class EKFCcuUc(Device):
|
|
|
69
75
|
AcquisitionError
|
|
70
76
|
If the temperature cannot be read, for example, because the sensor is not working.
|
|
71
77
|
"""
|
|
72
|
-
return (
|
|
73
|
-
self._get_signed_word_data(CcuCommands.CCU_TEMPERATURE.value, "temperature")
|
|
74
|
-
/ 10.0
|
|
75
|
-
)
|
|
78
|
+
return self._get_signed_word_data(CcuCommands.CCU_TEMPERATURE.value, "temperature") / 10.0
|
|
76
79
|
|
|
77
80
|
def humidity(self) -> float:
|
|
78
81
|
"""
|
|
@@ -89,10 +92,7 @@ class EKFCcuUc(Device):
|
|
|
89
92
|
AcquisitionError
|
|
90
93
|
If the humidity cannot be read, for example, because the sensor is not working.
|
|
91
94
|
"""
|
|
92
|
-
return (
|
|
93
|
-
self._get_signed_word_data(CcuCommands.CCU_HUMIDITY.value, "humidity")
|
|
94
|
-
/ 10.0
|
|
95
|
-
)
|
|
95
|
+
return self._get_signed_word_data(CcuCommands.CCU_HUMIDITY.value, "humidity") / 10.0
|
|
96
96
|
|
|
97
97
|
def vin_voltage(self) -> float:
|
|
98
98
|
"""
|
|
@@ -109,15 +109,14 @@ class EKFCcuUc(Device):
|
|
|
109
109
|
AcquisitionError
|
|
110
110
|
If the voltage cannot be read, for example, because the ADC is not working.
|
|
111
111
|
"""
|
|
112
|
-
return (
|
|
113
|
-
self._get_signed_word_data(CcuCommands.VIN_VOLTAGE.value, "VIN voltage")
|
|
114
|
-
/ 10.0
|
|
115
|
-
)
|
|
112
|
+
return self._get_signed_word_data(CcuCommands.VIN_VOLTAGE.value, "VIN voltage") / 10.0
|
|
116
113
|
|
|
117
114
|
def _get_signed_word_data(self, cmd: int, what: str) -> int:
|
|
118
115
|
v = self._smbus.read_word_data(self._i2c_addr, cmd)
|
|
116
|
+
|
|
119
117
|
if v == 0x8000:
|
|
120
|
-
raise AcquisitionError(f"
|
|
118
|
+
raise AcquisitionError(f"Cannot read {what}")
|
|
119
|
+
|
|
121
120
|
return struct.unpack("<h", struct.pack("<H", v))[0]
|
|
122
121
|
|
|
123
122
|
def fan_status(self, fan: int) -> Tuple[float, float, int]:
|
|
@@ -171,9 +170,7 @@ class EKFCcuUc(Device):
|
|
|
171
170
|
if fan == -1:
|
|
172
171
|
fan = 0xFF
|
|
173
172
|
data = struct.pack("<Bh", fan, int(temp * 10))
|
|
174
|
-
self._smbus.write_block_data(
|
|
175
|
-
self._i2c_addr, CcuCommands.PUSH_TEMPERATURE.value, list(data)
|
|
176
|
-
)
|
|
173
|
+
self._smbus.write_block_data(self._i2c_addr, CcuCommands.PUSH_TEMPERATURE.value, list(data))
|
|
177
174
|
|
|
178
175
|
def imu_sample(self) -> Tuple[ImuSample | None, bool]:
|
|
179
176
|
"""
|
|
@@ -200,15 +197,11 @@ class EKFCcuUc(Device):
|
|
|
200
197
|
True if more samples are available in the FIFO, False otherwise.
|
|
201
198
|
"""
|
|
202
199
|
more_samples = False
|
|
203
|
-
_data = self._smbus.read_block_data(
|
|
204
|
-
self._i2c_addr, CcuCommands.IMU_SAMPLES.value
|
|
205
|
-
)
|
|
200
|
+
_data = self._smbus.read_block_data(self._i2c_addr, CcuCommands.IMU_SAMPLES.value)
|
|
206
201
|
data = bytes(_data)
|
|
207
202
|
if len(data) < 14:
|
|
208
203
|
return None, False # No data available
|
|
209
|
-
diag, fsr, acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z = struct.unpack(
|
|
210
|
-
"<BBhhhhhh", data
|
|
211
|
-
)
|
|
204
|
+
diag, fsr, acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z = struct.unpack("<BBhhhhhh", data)
|
|
212
205
|
imu_data = ImuSample(
|
|
213
206
|
[
|
|
214
207
|
self._scale_imu_accel(acc_x, fsr),
|
|
@@ -274,15 +267,11 @@ class EKFCcuUc(Device):
|
|
|
274
267
|
version: str
|
|
275
268
|
The firmware version.
|
|
276
269
|
"""
|
|
277
|
-
title = bytes(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
)
|
|
281
|
-
).decode("utf-8")
|
|
270
|
+
title = bytes(self._smbus.read_block_data(self._i2c_addr, CcuCommands.IDENTIFY_FIRMWARE_TITLE.value)).decode(
|
|
271
|
+
"utf-8"
|
|
272
|
+
)
|
|
282
273
|
version = bytes(
|
|
283
|
-
self._smbus.read_block_data(
|
|
284
|
-
self._i2c_addr, CcuCommands.IDENTIFY_FIRMWARE_VERSION.value
|
|
285
|
-
)
|
|
274
|
+
self._smbus.read_block_data(self._i2c_addr, CcuCommands.IDENTIFY_FIRMWARE_VERSION.value)
|
|
286
275
|
).decode("utf-8")
|
|
287
276
|
return title, version
|
|
288
277
|
|
|
@@ -318,23 +307,26 @@ class EKFCcuUc(Device):
|
|
|
318
307
|
with Locker(self.name + "-load_firmware").lock():
|
|
319
308
|
offset = 0
|
|
320
309
|
max_chunk_len = 28
|
|
310
|
+
|
|
321
311
|
while len(firmware) > 0:
|
|
322
312
|
chunk, firmware = firmware[:max_chunk_len], firmware[max_chunk_len:]
|
|
323
313
|
self._load_firmware_chunk(offset, len(firmware) == 0, chunk)
|
|
324
314
|
offset += len(chunk)
|
|
315
|
+
|
|
325
316
|
if len(firmware) != 0:
|
|
326
317
|
self._nop()
|
|
318
|
+
|
|
327
319
|
if progress_callback is not None:
|
|
328
320
|
progress_callback(offset)
|
|
329
321
|
|
|
330
322
|
def _load_firmware_chunk(self, offset: int, is_last: bool, data: bytes) -> None:
|
|
331
323
|
if is_last:
|
|
332
324
|
offset |= 0x80000000
|
|
325
|
+
|
|
333
326
|
hdr = struct.pack("<I", offset)
|
|
334
327
|
data = hdr + data
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
)
|
|
328
|
+
|
|
329
|
+
self._smbus.write_block_data(self._i2c_addr, CcuCommands.LOAD_FIRMWARE_CHUNK.value, list(data))
|
|
338
330
|
|
|
339
331
|
def get_parameterset(self) -> str:
|
|
340
332
|
"""
|
|
@@ -392,6 +384,7 @@ class EKFCcuUc(Device):
|
|
|
392
384
|
with Locker(self.name + "-parameterset").lock():
|
|
393
385
|
json = b""
|
|
394
386
|
begin = True
|
|
387
|
+
|
|
395
388
|
while True:
|
|
396
389
|
chunk = self._get_parameterset_chunk(begin)
|
|
397
390
|
if len(chunk) < 32:
|
|
@@ -401,16 +394,13 @@ class EKFCcuUc(Device):
|
|
|
401
394
|
chunk = chunk[:-1]
|
|
402
395
|
json += chunk
|
|
403
396
|
begin = False
|
|
397
|
+
|
|
404
398
|
return json.decode("utf-8")
|
|
405
399
|
|
|
406
400
|
def _get_parameterset_chunk(self, begin: bool) -> bytes:
|
|
407
401
|
data = self._smbus.read_block_data(
|
|
408
402
|
self._i2c_addr,
|
|
409
|
-
(
|
|
410
|
-
CcuCommands.GET_PARAMETERSET_BEGIN.value
|
|
411
|
-
if begin
|
|
412
|
-
else CcuCommands.GET_PARAMETERSET_FOLLOW.value
|
|
413
|
-
),
|
|
403
|
+
(CcuCommands.GET_PARAMETERSET_BEGIN.value if begin else CcuCommands.GET_PARAMETERSET_FOLLOW.value),
|
|
414
404
|
)
|
|
415
405
|
return bytes(data)
|
|
416
406
|
|
|
@@ -455,6 +445,7 @@ class EKFCcuUc(Device):
|
|
|
455
445
|
cfg = _cfg.encode("utf-8")
|
|
456
446
|
offset = 0
|
|
457
447
|
max_chunk_len = 28
|
|
448
|
+
|
|
458
449
|
while len(cfg) > 0:
|
|
459
450
|
chunk, cfg = cfg[:max_chunk_len], cfg[max_chunk_len:]
|
|
460
451
|
self._load_parameterset_chunk(offset, len(cfg) == 0, chunk)
|
|
@@ -464,11 +455,11 @@ class EKFCcuUc(Device):
|
|
|
464
455
|
def _load_parameterset_chunk(self, offset: int, is_last: bool, data: bytes) -> None:
|
|
465
456
|
if is_last:
|
|
466
457
|
offset |= 0x80000000
|
|
458
|
+
|
|
467
459
|
hdr = struct.pack("<I", offset)
|
|
468
460
|
data = hdr + data
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
)
|
|
461
|
+
|
|
462
|
+
self._smbus.write_block_data(self._i2c_addr, CcuCommands.LOAD_PARAMETERSET.value, list(data))
|
|
472
463
|
|
|
473
464
|
def restart(self) -> None:
|
|
474
465
|
"""
|
ekfsm/devices/ekf_sur_led.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
from .gpio import GPIOExpander
|
|
2
1
|
from ekfsm.core.components import SysTree
|
|
2
|
+
from ekfsm.devices.generic import Device
|
|
3
|
+
|
|
4
|
+
from .gpio import GPIOExpander
|
|
3
5
|
|
|
4
6
|
|
|
5
7
|
class EKFSurLed(GPIOExpander):
|
|
@@ -11,10 +13,12 @@ class EKFSurLed(GPIOExpander):
|
|
|
11
13
|
self,
|
|
12
14
|
name: str,
|
|
13
15
|
parent: SysTree | None,
|
|
16
|
+
children: list["Device"] | None = None,
|
|
17
|
+
abort: bool = False,
|
|
14
18
|
*args,
|
|
15
19
|
**kwargs,
|
|
16
20
|
):
|
|
17
|
-
super().__init__(name, parent, None, *args, **kwargs)
|
|
21
|
+
super().__init__(name, parent, None, abort, *args, **kwargs)
|
|
18
22
|
|
|
19
23
|
def __str__(self) -> str:
|
|
20
24
|
return (
|