You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
1.9 KiB
76 lines
1.9 KiB
import time
|
|
|
|
from cereal import log
|
|
from openpilot.system.sensord.sensors.i2c_sensor import Sensor
|
|
|
|
# https://www.mouser.com/datasheet/2/821/Memsic_09102019_Datasheet_Rev.B-1635324.pdf
|
|
|
|
# Register addresses
|
|
REG_ODR = 0x1A
|
|
REG_INTERNAL_0 = 0x1B
|
|
REG_INTERNAL_1 = 0x1C
|
|
|
|
# Control register settings
|
|
CMM_FREQ_EN = (1 << 7)
|
|
AUTO_SR_EN = (1 << 5)
|
|
SET = (1 << 3)
|
|
RESET = (1 << 4)
|
|
|
|
class MMC5603NJ_Magn(Sensor):
|
|
@property
|
|
def device_address(self) -> int:
|
|
return 0x30
|
|
|
|
def init(self):
|
|
self.verify_chip_id(0x39, [0x10, ])
|
|
self.writes((
|
|
(REG_ODR, 0),
|
|
|
|
# Set BW to 0b01 for 1-150 Hz operation
|
|
(REG_INTERNAL_1, 0b01),
|
|
))
|
|
|
|
def _read_data(self, cycle) -> list[float]:
|
|
# start measurement
|
|
self.write(REG_INTERNAL_0, cycle)
|
|
self.wait()
|
|
|
|
# read out XYZ
|
|
scale = 1.0 / 16384.0
|
|
b = self.read(0x00, 9)
|
|
return [
|
|
(self.parse_20bit(b[6], b[1], b[0]) * scale) - 32.0,
|
|
(self.parse_20bit(b[7], b[3], b[2]) * scale) - 32.0,
|
|
(self.parse_20bit(b[8], b[5], b[4]) * scale) - 32.0,
|
|
]
|
|
|
|
def get_event(self, ts: int | None = None) -> log.SensorEventData:
|
|
ts = time.monotonic_ns()
|
|
|
|
# SET - RESET cycle
|
|
xyz = self._read_data(SET)
|
|
reset_xyz = self._read_data(RESET)
|
|
vals = [*xyz, *reset_xyz]
|
|
|
|
event = log.SensorEventData.new_message()
|
|
event.timestamp = ts
|
|
event.version = 1
|
|
event.sensor = 3 # SENSOR_MAGNETOMETER_UNCALIBRATED
|
|
event.type = 14 # SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
|
|
event.source = log.SensorEventData.SensorSource.mmc5603nj
|
|
|
|
m = event.init('magneticUncalibrated')
|
|
m.v = vals
|
|
m.status = int(all(int(v) != -32 for v in vals))
|
|
|
|
return event
|
|
|
|
def shutdown(self) -> None:
|
|
v = self.read(REG_INTERNAL_0, 1)[0]
|
|
self.writes((
|
|
# disable auto-reset of measurements
|
|
(REG_INTERNAL_0, (v & (~(CMM_FREQ_EN | AUTO_SR_EN)))),
|
|
|
|
# disable continuous mode
|
|
(REG_ODR, 0),
|
|
))
|
|
|