adafruit / uf2-samdx1

MSC bootloader (based on UF2) for SAMD21
Other
214 stars 187 forks source link

Usage on a board with no reset button #174

Open izzy84075 opened 3 years ago

izzy84075 commented 3 years ago

I have a handful of battery-powered custom boards, and my intention is to not have a reset button. I'm hoping to be able to distribute UF2 files instead of the project source, just to make sure everything ends up with the same code.

I have code to trigger the bootloader after holding down the button I do have for ~30 seconds. However, if you /accidentally/ trigger this, there seems to be no way to exit the bootloader without disconnecting the battery or writing a program to the board.

Is there some way to trigger a reset/application start after, say, 30 seconds of no USB connection, or by plugging it into a computer and then disconnecting?

dhalbert commented 3 years ago

You could modify the existing bootloader to keep a timer running and reboot to the application program if there was no activity after a while. https://github.com/adafruit/Adafruit_nRF52_Bootloader did this, though it was removed inhttps://github.com/adafruit/Adafruit_nRF52_Bootloader/pull/166. The nRF bootloader also start the application program if USB has not ben enumerated after 3 seconds: https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/6126d1192ef2fde7bff2eaa2df68c22639230cb7/src/main.c#L266

There is no timeout built in to this SAMD bootloader, but similar timeouts could be added.

izzy84075 commented 3 years ago

Digging around some, I think the "reset if no USB enumeration" functionality almost exists already.

In the case of the USE_SINGLE_RESET configuration, resetHorizon gets set in check_start_application() , and then timerTick gets called while waiting for USB_Ok to enumerate, and if timerHigh passes resetHorizon, it resets into the app.

If it does enumerate, it gets cleaned up here to prevent it resetting until programming is complete.

I'm fairly certain this is also the reset method used by MSC programming, as seen here.

So I think I can do this with ~2 lines of code, just to set resetHorizon to a default value on startup, and then to ensure it gets cleaned up regardless of USE_SINGLE_RESET after enumeration.

I believe this is a very different implementation from how the nrf52 bootloader had it, as it looks like that one could timeout even after enumeration and reset, causing host computer errors. This is only intended to reset in the case of there never being a host computer connected.

Would this be something possibly useful to add a configuration option for in a PR? It can easily default to the existing behaviour of not initializing resetHorizon/initializing it to 0 to prevent it automatically resetting out of the bootloader, and only add the timeout behaviour when explicitly configured to do so in the board configuration.

nunomiguelferreira commented 2 years ago

If it is still possible I would like really this behaviour to be enabled, since at the moment it is possible for the boards to be stuck in bootloader mode forever.

A timeout of 60 seconds or so, would vastly increase reliability of the bootloader.

dhalbert commented 2 years ago

We have no plans to add this, but would be happy to entertain a pull request as an optional feature enabled by a compile-time flag.

nunomiguelferreira commented 2 years ago

@izzy84075 Don't know if you made any progress with this, but would love to have the possibility to do so!

Also a separate branch with the compile time flag would be nice, if its easy to do (at the momentm wouldn't know how to do it).

dhalbert commented 2 years ago

A separate branch is not necessary: there are plenty of options controlled by flags in the main branch.

xyzzy42 commented 2 years ago

I did this for our device. I used the watchdog timer and fed it based on USB or UART progress. This way it still resets if USB is connected and then stops working.

Abdul-Origo commented 11 months ago

Hi Izzy, You mentioned you have a code the bootloader if you hold reset for 30 seconds. May I please have that. Would really appreciate it

xyzzy42 commented 11 months ago

I haven't looked at samd21 for over a year and don't have the code handy anymore. I made a PR for this repo for something else, but it just sat and sat for months, so I didn't see any point in making another to add this feature.