diff --git a/hardware/opentrons_hardware/firmware_bindings/binary_constants.py b/hardware/opentrons_hardware/firmware_bindings/binary_constants.py index 0ef4139b56a..869e861995b 100644 --- a/hardware/opentrons_hardware/firmware_bindings/binary_constants.py +++ b/hardware/opentrons_hardware/firmware_bindings/binary_constants.py @@ -32,6 +32,10 @@ class BinaryMessageId(int, Enum): aux_id_response = 0x12 estop_button_present_request = 0x13 + write_eeprom_request = 0x100 + read_eeprom_request = 0x101 + read_eeprom_response = 0x102 + # Light messages prefixed by 0x400 # 0x40x = light strip add_light_action = 0x400 diff --git a/hardware/opentrons_hardware/firmware_bindings/messages/binary_message_definitions.py b/hardware/opentrons_hardware/firmware_bindings/messages/binary_message_definitions.py index 2a6d29fd7f3..22140f8209a 100644 --- a/hardware/opentrons_hardware/firmware_bindings/messages/binary_message_definitions.py +++ b/hardware/opentrons_hardware/firmware_bindings/messages/binary_message_definitions.py @@ -13,6 +13,7 @@ OptionalRevisionField, LightTransitionTypeField, LightAnimationTypeField, + EepromDataField, ) log = logging.getLogger(__name__) @@ -142,7 +143,7 @@ class EngageEstop(utils.BinarySerializable): """Send a request to enable the estop line.""" message_id: utils.UInt16Field = utils.UInt16Field(BinaryMessageId.engage_estop) - lenght: utils.UInt16Field = utils.UInt16Field(0) + length: utils.UInt16Field = utils.UInt16Field(0) @dataclass @@ -150,7 +151,7 @@ class ReleaseEstop(utils.BinarySerializable): """Send a request to disable the estop line.""" message_id: utils.UInt16Field = utils.UInt16Field(BinaryMessageId.release_estop) - lenght: utils.UInt16Field = utils.UInt16Field(0) + length: utils.UInt16Field = utils.UInt16Field(0) @dataclass @@ -158,7 +159,7 @@ class EngageSyncOut(utils.BinarySerializable): """Send a request to enable the sync line.""" message_id: utils.UInt16Field = utils.UInt16Field(BinaryMessageId.engage_nsync_out) - lenght: utils.UInt16Field = utils.UInt16Field(0) + length: utils.UInt16Field = utils.UInt16Field(0) @dataclass @@ -166,7 +167,7 @@ class ReleaseSyncOut(utils.BinarySerializable): """Send a request to disable the sync line.""" message_id: utils.UInt16Field = utils.UInt16Field(BinaryMessageId.release_nsync_out) - lenght: utils.UInt16Field = utils.UInt16Field(0) + length: utils.UInt16Field = utils.UInt16Field(0) @dataclass @@ -266,6 +267,44 @@ class DoorSwitchStateInfo(utils.BinarySerializable): door_open: utils.UInt8Field = utils.UInt8Field(0) +@dataclass +class WriteEEPromRequest(utils.BinarySerializable): + """Write to the EEPROM.""" + + message_id: utils.UInt16Field = utils.UInt16Field( + BinaryMessageId.write_eeprom_request + ) + length: utils.UInt16Field = utils.UInt16Field(12) + data_address: utils.UInt16Field = utils.UInt16Field(0) + data_length: utils.UInt16Field = utils.UInt16Field(0) + data: EepromDataField = EepromDataField(bytes()) + + +@dataclass +class ReadEEPromRequest(utils.BinarySerializable): + """Read from the EEPROM.""" + + message_id: utils.UInt16Field = utils.UInt16Field( + BinaryMessageId.read_eeprom_request + ) + length: utils.UInt16Field = utils.UInt16Field(4) + data_address: utils.UInt16Field = utils.UInt16Field(0) + data_length: utils.UInt16Field = utils.UInt16Field(0) + + +@dataclass +class ReadEEPromResponse(utils.BinarySerializable): + """Read from the EEPROM response.""" + + message_id: utils.UInt16Field = utils.UInt16Field( + BinaryMessageId.read_eeprom_response + ) + length: utils.UInt16Field = utils.UInt16Field(12) + data_address: utils.UInt16Field = utils.UInt16Field(0) + data_length: utils.UInt16Field = utils.UInt16Field(0) + data: EepromDataField = EepromDataField(bytes()) + + @dataclass class AddLightActionRequest(utils.BinarySerializable): """Add an action to the staging light queue. @@ -363,6 +402,9 @@ class GetDeckLightResponse(utils.BinarySerializable): AuxPresentRequest, AuxIDRequest, AuxIDResponse, + WriteEEPromRequest, + ReadEEPromRequest, + ReadEEPromResponse, AddLightActionRequest, ClearLightActionStagingQueue, StartLightAction, diff --git a/hardware/opentrons_hardware/hardware_control/rear_panel_settings.py b/hardware/opentrons_hardware/hardware_control/rear_panel_settings.py index 384aaf3c031..c199b7334ac 100644 --- a/hardware/opentrons_hardware/hardware_control/rear_panel_settings.py +++ b/hardware/opentrons_hardware/hardware_control/rear_panel_settings.py @@ -15,8 +15,12 @@ EstopButtonPresentRequest, EstopButtonDetectionChange, Ack, + WriteEEPromRequest, + ReadEEPromRequest, + ReadEEPromResponse, ) from opentrons_hardware.firmware_bindings import utils +from opentrons_hardware.firmware_bindings.messages.fields import EepromDataField from typing import cast, Optional log = logging.getLogger(__name__) @@ -36,6 +40,47 @@ class RearPinState: door_open: bool = False +async def write_eeprom( + messenger: Optional[BinaryMessenger], data_addr: int, data_len: int, data: bytes +) -> bool: + """Writes up to 8 bytes from the eeprom.""" + if messenger is None: + # the EVT bots don't have switches so just return that the door is closed + return False + if data_addr < 0 or data_addr > 0x4000 or data_len < 0 or data_len > 8: + return False + response = await messenger.send_and_receive( + message=WriteEEPromRequest( + data_address=utils.UInt16Field(data_addr), + data_length=utils.UInt16Field(data_len), + data=EepromDataField(data), + ), + response_type=Ack, + ) + return response is not None + + +async def read_eeprom( + messenger: Optional[BinaryMessenger], data_addr: int, data_len: int +) -> bytes: + """Reads up to 8 bytes from the eeprom.""" + if messenger is None: + # the EVT bots don't have switches so just return that the door is closed + return b"" + if data_addr < 0 or data_addr > 0x4000 or data_len < 0 or data_len > 8: + return b"" + response = await messenger.send_and_receive( + message=ReadEEPromRequest( + data_address=utils.UInt16Field(data_addr), + data_length=utils.UInt16Field(data_len), + ), + response_type=ReadEEPromResponse, + ) + if response is None: + return b"" + return bytes(cast(ReadEEPromResponse, response).data.value) + + async def get_door_state(messenger: Optional[BinaryMessenger]) -> bool: """Returns true if the door is currently open.""" if messenger is None: