diff --git a/rosys/hardware/__init__.py b/rosys/hardware/__init__.py index f960dd50..6715f5ef 100644 --- a/rosys/hardware/__init__.py +++ b/rosys/hardware/__init__.py @@ -4,7 +4,6 @@ from .bumper import Bumper, BumperHardware, BumperSimulation from .can import CanHardware from .communication import Communication, SerialCommunication, WebCommunication -from .esp_pins import EspPins from .estop import EStop, EStopHardware, EStopSimulation from .expander import ExpanderHardware from .gnss import Gnss, GnssHardware, GnssMeasurement, GnssSimulation @@ -29,7 +28,6 @@ 'EStop', 'EStopHardware', 'EStopSimulation', - 'EspPins', 'ExpanderHardware', 'Gnss', 'GnssHardware', diff --git a/rosys/hardware/esp_pins.py b/rosys/hardware/esp_pins.py index 863ced96..d6b15d73 100644 --- a/rosys/hardware/esp_pins.py +++ b/rosys/hardware/esp_pins.py @@ -72,9 +72,20 @@ async def update_all(self) -> None: for pin in self._pins.values(): await self.update_pin(pin) + async def get_pin_level(self, pin_id: int) -> bool: + await self.update_pin(self._pins[pin_id]) + return self._pins[pin_id].level + async def set_pin_level(self, pin: GpioPin, level: bool) -> None: await self.robot_brain.send(f'{self.name}.set_pin_level({pin.gpio}, {1 if level else 0})') + async def get_strapping_pins(self) -> list[bool]: + """Get the state of the strapping pins. + + See https://github.com/zauberzeug/lizard/issues/75 and https://github.com/zauberzeug/lizard/pull/95. + """ + return [await self.get_pin_level(number) for number in [0, 2, 12]] + def developer_ui(self) -> None: with ui.column(): with ui.row().classes('w-full'): diff --git a/rosys/hardware/lizard_firmware.py b/rosys/hardware/lizard_firmware.py index 5ebfd868..9ec6108b 100644 --- a/rosys/hardware/lizard_firmware.py +++ b/rosys/hardware/lizard_firmware.py @@ -115,6 +115,9 @@ def download(self) -> None: async def flash_core(self) -> None: assert isinstance(self.robot_brain.communication, SerialCommunication) rosys.notify(f'Flashing Lizard firmware {self.local_version} to Core...') + if any(await self.robot_brain.esp_pins_p0.get_strapping_pins()): + rosys.notify('Flashing Core failed. Check strapping pins.', 'negative') + return self.robot_brain.communication.disconnect() await rosys.sleep(0.3) output = await rosys.run.sh(['sudo', './flash.py', *self.flash_params], timeout=None, working_dir=self.PATH) @@ -125,6 +128,9 @@ async def flash_core(self) -> None: async def flash_p0(self, timeout: float = 120) -> None: rosys.notify(f'Flashing Lizard firmware {self.core_version} to P0...') + if any(await self.robot_brain.esp_pins_p0.get_strapping_pins()): + rosys.notify('Flashing P0 failed. Check strapping pins.', 'negative') + return await self.robot_brain.send('p0.flash()') start = rosys.time() deadline = start + timeout diff --git a/rosys/hardware/robot_brain.py b/rosys/hardware/robot_brain.py index 536ec71d..abfb426b 100644 --- a/rosys/hardware/robot_brain.py +++ b/rosys/hardware/robot_brain.py @@ -6,6 +6,7 @@ from .. import rosys from ..event import Event from .communication import Communication +from .esp_pins import EspPins from .lizard_firmware import LizardFirmware CLOCK_OFFSET_HISTORY_LENGTH = 100 @@ -41,6 +42,9 @@ def __init__(self, communication: Communication, *, enable_esp_on_startup: bool if enable_esp_on_startup: rosys.on_startup(self.enable_esp) + self.esp_pins_core = EspPins(name='core', robot_brain=self) + self.esp_pins_p0 = EspPins(name='p0', robot_brain=self) + @property def clock_offset(self) -> float | None: return self._clock_offset @@ -103,10 +107,21 @@ def update_visibility() -> None: with ui.menu() as menu: ui.menu_item('Download', on_click=self.lizard_firmware.download) \ .tooltip('Download the latest Lizard firmware from GitHub') + + async def check_strapping_pins_core(): + ui.notify(await self.esp_pins_core.get_strapping_pins()) + ui.menu_item('Check Core Strapping Pins', on_click=check_strapping_pins_core) \ + .tooltip('Check if the Core strapping pins are in the correct state for flashing.') ui.menu_item('Flash Core', on_click=self.lizard_firmware.flash_core) \ .tooltip('Flash the downloaded Lizard firmware to the Core microcontroller') + + async def check_strapping_pins_p0(): + ui.notify(await self.esp_pins_p0.get_strapping_pins()) + ui.menu_item('Check P0 Strapping Pins', on_click=check_strapping_pins_p0) \ + .tooltip('Check if the P0 strapping pins are in the correct state for flashing.') ui.menu_item('Flash P0', on_click=self.lizard_firmware.flash_p0) \ .tooltip('Flash the downloaded Lizard firmware to the P0 microcontroller') + ui.menu_item('Enable', on_click=self.enable_esp) \ .tooltip('Enable the microcontroller module (will later be done automatically)') ui.menu_item('Configure', on_click=self.configure) \