openlifu.io.LIFUDFU.LIFUDFUManager

class openlifu.io.LIFUDFU.LIFUDFUManager(uart: LIFUUart)[source]

Bases: object

Orchestrates firmware updates for a single LIFU transmitter module.

Usage:

from openlifu.io.LIFUDFU import LIFUDFUManager
mgr = LIFUDFUManager(uart=txdevice.uart)
mgr.update_module(
    module=1,
    package_file="path/to/lifu-transmitter-fw.bin.signed.bin",
    enter_dfu_fn=txdevice.enter_dfu,
)
_wait_for_usb_dfu(vid: int, pid: int, libusb_dll: str | None, timeout_s: float = 30.0, poll_interval_s: float = 1.0) str[source]

Poll for the USB DFU device until it enumerates or timeout_s elapses.

Returns the bootloader version string once the device is found. Raises RuntimeError if the device does not appear within the timeout.

get_bootloader_version_i2c(i2c_addr: int = 114) str[source]

Read bootloader version string from a slave module via I2C passthrough.

get_bootloader_version_usb(vid: int = 1155, pid: int = 57105, libusb_dll: str | None = None) str[source]

Read bootloader version string from module 0 via USB DFU.

program_i2c(package_file: str, i2c_addr: int = 114, progress_callback: Callable | None = None) None[source]

Program a signed package to a slave module via I2C passthrough.

The slave must already be in DFU bootloader mode at i2c_addr.

Sequence (mirrors dfu-i2c-test.py program-package):
  1. Mass-erase the application flash region.

  2. Erase the metadata page explicitly (it is outside the app region and is NOT touched by mass-erase).

  3. Write the firmware payload.

  4. Write the metadata blob.

  5. Send CMD_MANIFEST.

program_usb(package_file: str, vid: int = 1155, pid: int = 57105, libusb_dll: str | None = None, progress_callback: Callable | None = None) None[source]

Program a signed package to module 0 via USB DFU.

The module must already be in DFU bootloader mode.

update_module(module: int, package_file: str, enter_dfu_fn: Callable, vid: int = 1155, pid: int = 57105, libusb_dll: str | None = None, i2c_addr: int = 114, dfu_wait_s: float = 3.0, dfu_enum_timeout_s: float = 30.0, progress_callback: Callable | None = None) None[source]

High-level firmware update for a single module.

Steps:
  1. Call enter_dfu_fn(module=module) to reboot into the bootloader.

  2. Wait dfu_wait_s seconds (initial settling delay).

  3. For module 0: poll for the USB DFU device until it enumerates (up to dfu_enum_timeout_s) then program. For modules 1+: poll the I2C DFU slave via passthrough then program.

  4. Program the signed package.

Module 0 (USB master) uses USB DFU. Modules 1+ use I2C DFU through the master’s OW_I2C_PASSTHRU path, writing to i2c_addr (default 0x72).

Parameters:
  • module – Physical module index (0 = USB master).

  • package_file – Path to the signed firmware package.

  • enter_dfu_fn – Callable that triggers DFU mode, e.g. txdevice.enter_dfu.

  • vid – USB VID for module 0 USB DFU.

  • pid – USB PID for module 0 USB DFU.

  • libusb_dll – Optional path to libusb-1.0.dll (Windows).

  • i2c_addr – I2C DFU slave address for modules 1+.

  • dfu_wait_s – Initial settling delay after DFU-enter (default 3 s).

  • dfu_enum_timeout_s – Total time to wait for the bootloader to appear (default 30 s). Includes dfu_wait_s.

  • progress_callback – Optional (written, total, label) callable.

Raises:

RuntimeError – If DFU entry cannot be verified or programming fails.