harp-tech / protocol

Description of the Harp protocol.
https://harp-tech.org/protocol/BinaryProtocol-8bit.html
MIT License
3 stars 5 forks source link

Consider standardizing trigger for `Bootloader` mode #18

Open bruno-f-cruz opened 6 months ago

bruno-f-cruz commented 6 months ago

Since we are moving in a direction where the protocol will likely be implemented in different devices/architectures, it would be interesting to discuss a way to send these devices into bootloader mode using the Harp Protocol.

My initial proposal would be to use Bit2 of Address 11 (R_RESET_DEV) as a standard to achieve this. This Bit should always be read as 0, and can be set to send the respective device into Bootloader mode.

Alternatively, if we do not want to use this bit, we could think of a different strategy, for instance, setting, simultaneously Bit 0 and 1 of the same register (RST_DEF and RST_EE) could trigger this behavior.

Poofjunior commented 6 months ago

+1 to this. Or more generally than bootloader mode, just a mode where the device aborts its program and is placed in a state where it can accept firmware updates.

Poofjunior commented 6 months ago

Whoop--this is basically restating Bruno's suggestions.

To add more details to this, I suggest we coopt a bit in the R_RESET_DEV register. image

It looks like bits[5:4] are currently unused. My proposed specification would be:

RST_FLASH[Bit 4], FLASH[Bit 4] or BOOTLOADER[Bit 4]: if set, the device enters an implementation-specific bootloader mode where it can be flashed with new firmware. After a firmware update, the PC may or may not need to reconnect to the device. After flashing and reconnecting, the behavior is equivalent to setting the RST_DEF bit. This bit reads as 0.

Alternative methods for signaling the same behavior could include:

Benefits

The value-add is having a reserved (by nature of being part of the protocol) semi-standardized way to reflash devices. With multiple devices running concurrently in rigs, it would be valuable to put all of the devices in a defined state that includes the state of the firmware. Currently, reflashing devices involves having the physical device on-hand to put the device into a state where it accepts new code.

bruno-f-cruz commented 4 months ago

@Poofjunior @filcarv Please add the details of the current/desirable implementation for sending the device into bootloader mode. Thanks!

Poofjunior commented 4 months ago

Firmware Implementation

For putting the device itself into a state where it can accept new firmware, we simply invoke reset_usb_boot().

Uploading Firmware

Invoking reset_usb_boot() with the default option causes the device to expose two interfaces to the PC: (1) a usb mass storage device and (2) a particular usb endpoint on the device that enables reading/writing flash.

Using the first interface is just a matter of moving files from one location to the mounted mass storage device. (See Pico Datasheet 3.2.1 for an example.)

Using the second interface is a bit more complicated, but it has been abstracted up if you just invoke picotoo, a cross-platform command line utility maintained by the Pi Foundation. At that point, you just invoke a one-liner to upload new code.

Notes:

With the above proposal, it is still possible to upload "buggy" firmware and put the device into an unresponsive state. This isn't a dealbreaker because we can always re-upload firmware with a hardware override where we power-cycle the physical device with GPIO line in a particular state. (All devices I have made to date expose this GPIO line through a button that you can push. The Pico dev board also exposes this as the "BOOTSEL" button.)