From 755cfa95e4278c87df106656d9cdb6e023076c3a Mon Sep 17 00:00:00 2001 From: Glenn Engel Date: Mon, 15 Feb 2021 07:49:52 -0800 Subject: [PATCH] Add USB connect timeout for app reset to UF2 or Serial via GPREGRET --- README.md | 26 +++++++++++++++++++++----- src/main.c | 5 +++-- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 83e7563..8b66875 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,14 @@ There are two pins, `DFU` and `FRST` that bootloader will check upon reset/power - The `GPREGRET` register can also be set to force the bootloader can enter any of above modes (plus a CDC-only mode for Arduino). `GPREGRET` is set by the application before performing a soft reset. +```c +#include "nrf_nvic.h" +void reset_to_uf2(void) { + NRF_POWER->GPREGRET = 0x57; // 0xA8 OTA, 0x4e Serial + NVIC_SystemReset(); // or sd_nvic_SystemReset(); +} +``` + On the Nordic PCA10056 DK board, `DFU` is connected to **Button1**, and `FRST` is connected to **Button2**. So holding down **Button1** while clicking **RESET** will put the board into USB bootloader mode, with UF2 and CDC support. Holding down **Button2** while clicking **RESET** will put the board into OTA (over-the-air) bootloader mode. @@ -69,7 +77,7 @@ For other boards, please check the board definition for details. ### Making your own UF2 -To create your own UF2 DFU update image, simply use the [Python conversion script](https://github.com/Microsoft/uf2/blob/master/utils/uf2conv.py) on a .bin file or .hex file, specifying the family as **0xADA52840**. If using a .bin file with the conversion script you must specify application address with the -b switch, this address depend on the SoftDevice size/version e.g S140 v6 is 0x26000 +To create your own UF2 DFU update image, simply use the [Python conversion script](https://github.com/Microsoft/uf2/blob/master/utils/uf2conv.py) on a .bin file or .hex file, specifying the family as **0xADA52840**. If using a .bin file with the conversion script you must specify application address with the -b switch, this address depend on the SoftDevice size/version e.g S140 v6 is 0x26000 To create a UF2 image from a .bin file: ``` @@ -105,6 +113,15 @@ You must have have a J-Link available to "unbrick" your device. Prerequisites - ARM GCC + +To install for macos + +```bash +brew tap ArmMbed/homebrew-formulae +brew install arm-none-eabi-gcc +brew link --overwrite arm-none-eabi-gcc # if a prior version was present +``` + - Nordic's [nRF5x Command Line Tools](https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools) - [Python IntelHex](https://pypi.org/project/IntelHex/) @@ -148,7 +165,7 @@ Makefile:90: *** BOARD not defined. Stop If you get the following error ... ``` -$ make BOARD=feather_nrf52840_express all +$ make BOARD=feather_nrf52840_express all Compiling file: main.c /bin/sh: /usr/bin/arm-none-eabi-gcc: No such file or directory make: *** [_build/main.o] Error 127 @@ -160,6 +177,8 @@ the variable `CROSS_COMPILE` as below: $ make CROSS_COMPILE=/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi- BOARD=feather_nrf52832 all ``` +For other compile errors, check the gcc version with `arm-none-eabi-gcc --version` to insure it is at least 9.x. + #### 2. `ModuleNotFoundError: No module named 'intelhex'` Install python-intelhex with @@ -169,9 +188,6 @@ pip install intelhex ``` - - - #### 3. `make: nrfjprog: No such file or directory` Make sure that `nrfjprog` is available from the command-line. This binary is diff --git a/src/main.c b/src/main.c index cf05c1a..b665d6c 100644 --- a/src/main.c +++ b/src/main.c @@ -170,9 +170,10 @@ int main(void) // Serial only mode bool serial_only_dfu = (NRF_POWER->GPREGRET == DFU_MAGIC_SERIAL_ONLY_RESET); + bool uf2_dfu = (NRF_POWER->GPREGRET == DFU_MAGIC_UF2_RESET); // start either serial, uf2 or ble - bool dfu_start = _ota_dfu || serial_only_dfu || (NRF_POWER->GPREGRET == DFU_MAGIC_UF2_RESET) || + bool dfu_start = _ota_dfu || serial_only_dfu || uf2_dfu || (((*dbl_reset_mem) == DFU_DBL_RESET_MAGIC) && (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk)); // Clear GPREGRET if it is our values @@ -251,7 +252,7 @@ int main(void) } // Initiate an update of the firmware. - if (APP_ASKS_FOR_SINGLE_TAP_RESET()) + if (APP_ASKS_FOR_SINGLE_TAP_RESET() || uf2_dfu || serial_only_dfu) { // If USB is not enumerated in 3s (eg. because we're running on battery), we restart into app. APP_ERROR_CHECK( bootloader_dfu_start(_ota_dfu, 3000, true) );