Compare commits

...
30 Commits
Author SHA1 Message Date
Ha Thach fc487794b3 Update changelog.md 2021-04-04 15:11:04 +07:00
Ha Thach 4f74d41871 Merge pull request #160 from KK1423/fix-paired-ota
Resolve OTA failure with bond shared from application
2021-04-04 15:09:01 +07:00
Ha Thach 77c7b7f6dc Merge pull request #200 from adafruit/release-0.5.0
update changelog for release
2021-04-04 15:06:31 +07:00
hathach 488c6c4463 update changelog for release
rename board to all lower case
2021-04-04 14:42:12 +07:00
Ha Thach f1b4740579 Merge pull request #196 from lyusupov/BUTTON_DFU_WAKEUP
Improvement/fix of system wake up by BUTTON_DFU GPIO
2021-04-04 14:31:45 +07:00
hathach 0098324683 skip DFU entirely with DFU_MAGIC_SKIP 2021-04-04 12:58:47 +07:00
hathach 26bafdcf24 Merge branch 'BUTTON_DFU_WAKEUP' of https://github.com/lyusupov/Adafruit_nRF52_Bootloader into lyusupov-BUTTON_DFU_WAKEUP 2021-04-02 23:14:02 +07:00
Ha Thach 5e6690e296 Merge pull request #194 from cmdwtf/board-add-sf-nrf52840-micromod
Add board 'sparkfun_nrf52840_micromod'.
2021-03-23 20:41:11 +07:00
Chris Dailey 78d0c3ae27 Update board.h
Adjust `UF2_BOARD_ID` to fit UF2 format.
2021-03-23 09:11:10 -04:00
Ha Thach 3895ffbda6 Merge pull request #197 from adafruit/update-tinyusb-0.9.0
update tinyusb to nclude nrf usb driver race condition fix
2021-03-19 16:27:53 +07:00
hathach a4b5aa4ad1 update tinyusb to include nrf usb driver race fix 2021-03-19 16:22:13 +07:00
hathach 84e843ac86 update tinyusb to 0.9.0 2021-03-16 23:17:32 +07:00
Linar Yusupov 0299cfedb5 Avoid entering into DFU mode upon wake up by BUTTON_DFU GPIO 2021-03-11 13:20:25 +03:00
Chris Dailey b404dabe15 Add sparkfun_nrf52840_micromod to CI 2021-03-09 13:03:07 -05:00
Chris Dailey d88ab7427a Updated sf micromod USB PIDs
As per the PIDs provide by TheHoff, [here](https://forum.sparkfun.com/viewtopic.php?p=223812#p223812)
2021-03-09 12:53:02 -05:00
nitz d481de3e00 Add SparkFun MicroMod nRF52840 to readme. 2021-03-07 01:04:04 -05:00
nitz 1a5df60739 Add board 'sparkfun_nrf52840_micromod'. 2021-03-07 00:56:50 -05:00
Ha Thach cb916d3087 Merge pull request #192 from jamesadevine/apa102
add support for APA102 LEDs
2021-03-04 23:45:34 +07:00
James Devine 0670265be0 Add ifdef guard for apa102 teardown 2021-03-03 12:47:27 +00:00
James Devine 6f7dc38d3c ifdef guard inclusion of nrf_spim 2021-03-02 23:41:45 +00:00
James Devine 91f16ade72 add support for APA102 LEDs 2021-03-02 23:32:01 +00:00
Ha Thach 81da515ae6 upload update uf2 separately in release 2021-02-17 16:19:09 +07:00
Ha Thach 3aaef724b2 release 0.4.1 2021-02-17 15:59:15 +07:00
Ha Thach ba5d783c20 Merge pull request #189 from glenne/master
Add USB connect timeout for app reset to UF2 or Serial via GPREGRET
2021-02-17 15:52:47 +07:00
Glenn Engel 755cfa95e4 Add USB connect timeout for app reset to UF2 or Serial via GPREGRET 2021-02-15 07:49:52 -08:00
Ha Thach b37c078213 Merge pull request #191 from adafruit/fix-ci-190
fix ci arm gcc install path
2021-02-15 14:16:53 +07:00
hathach ba5977d679 fix ci arm gcc install path 2021-02-15 14:07:20 +07:00
Ha Thach 4ba802d127 Merge pull request #186 from lyusupov/REGOUT0
fix against pollution of REGOUT0 reserved bits
2021-02-01 21:36:54 +07:00
Linar Yusupov f9125593b2 fix against pollution of REGOUT0 reserved bits 2021-01-30 12:27:52 +03:00
Karthik Karyamapudi 8ba551c07e Fix ota failure when paired 2020-08-17 17:26:16 -04:00
13 changed files with 310 additions and 79 deletions

No files matched your search

+14 -4
View File
@@ -24,7 +24,7 @@ jobs:
- 'itsybitsy_nrf52840_express'
- 'metro_nrf52840_express'
# Alphabetical order
- 'ADM_B_NRF52840_1'
- 'adm_b_nrf52840_1'
- 'ae_bl652_bo'
- 'aramcon_badge_2019'
- 'arcade_feather_nrf52840_express'
@@ -45,6 +45,7 @@ jobs:
- 'pca10100'
- 'pitaya_go'
- 'raytac_mdbt50q_rx'
- 'sparkfun_nrf52840_micromod'
- 'waveshare_nrf52840_eval'
steps:
@@ -66,7 +67,7 @@ jobs:
# 9.3.1-1.2.1 is xpack modified version which significantly increased compiled size to 6-7KB and cause flash overflow.
# Skip this version for now, we will try again with next official release from ARM
xpm install --global @xpack-dev-tools/arm-none-eabi-gcc@9.3.1-1.1.1
echo `echo $HOME/opt/xPacks/@xpack-dev-tools/arm-none-eabi-gcc/*/.content/bin` >> $GITHUB_PATH
echo `echo $HOME/.local/xPacks/@xpack-dev-tools/arm-none-eabi-gcc/*/.content/bin` >> $GITHUB_PATH
- name: Build
run: |
@@ -78,12 +79,11 @@ jobs:
name: ${{ matrix.board }}
path: _bin/${{ matrix.board }}
- name: Creat Release Asset
- name: Create Release Asset
if: ${{ github.event_name == 'release' }}
run: zip -jr ${{ matrix.board }}_bootloader-${{ github.event.release.tag_name }}.zip _bin/${{ matrix.board }}
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -94,3 +94,13 @@ jobs:
asset_name: ${{ matrix.board }}_bootloader-${{ github.event.release.tag_name }}.zip
asset_content_type: application/zip
- name: Upload Release Asset for Self-Update
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: ${{ github.event_name == 'release' }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: _bin/${{ matrix.board }}/update-${{ matrix.board }}_bootloader-${{ github.event.release.tag_name }}_nosd.uf2
asset_name: update-${{ matrix.board }}_bootloader-${{ github.event.release.tag_name }}_nosd.uf2
asset_content_type: application/x-binary
+22 -5
View File
@@ -20,6 +20,7 @@ This is a CDC/DFU/UF2 bootloader for nRF52 boards.
- Particle Argon
- Particle Boron
- Particle Xenon
- [SparkFun MicroMod nRF52840](https://www.sparkfun.com/products/16984)
UF2 is an easy-to-use bootloader that appears as a flash drive. You can just copy `.uf2`-format
application images to the flash drive to load new firmware. See https://github.com/Microsoft/uf2 and https://github.com/adafruit/uf2-samdx1 for more information.
@@ -57,6 +58,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 +78,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 +114,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 +166,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 +178,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 +189,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
+13
View File
@@ -1,5 +1,18 @@
# Adafruit nRF52 Bootloader Changelog
## 0.5.0 - 2021.04.04
- Update tinyusb to latest to fix the race condition causing cdc out dropping packet. Which cause DFU failed occasionally
- Add support for Dotstar LED (APA102)
- Add sparkfun_nrf52840_micromod board
- Allow skipping DFU entirely when reset or wakeup from deep sleep
- Fix an issue with OTA when using shared bond with application
## 0.4.1 - 2021.02.17
- Add USB connect timeout for app reset to UF2 or Serial via GPREGRET
- Fix pollution of REGOUT0 reserved bits
## 0.4.0 - 2021.01.19
- Decouple bootloader and softdevice i.e bootloader will always work with and/or without softdevice present. This allows application to pack firmware + softdevice into an uf2/serial for DFU.
@@ -148,6 +148,7 @@ static uint32_t service_change_indicate()
err_code = sd_ble_gatts_service_changed(m_conn_handle, DFU_SERVICE_HANDLE, BLE_HANDLE_MAX);
if ((err_code == BLE_ERROR_INVALID_CONN_HANDLE) ||
(err_code == BLE_ERROR_INVALID_ATTR_HANDLE) ||
(err_code == NRF_ERROR_INVALID_STATE) ||
(err_code == NRF_ERROR_BUSY))
{
File renamed without changes.
File renamed without changes.
+100 -7
View File
@@ -27,13 +27,17 @@
#include "app_scheduler.h"
#include "app_timer.h"
#ifdef LED_APA102
#include "nrf_spim.h"
#endif
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
#define SCHED_MAX_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Maximum size of scheduler events. */
#define SCHED_QUEUE_SIZE 30 /**< Maximum number of events in the scheduler queue. */
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
void neopixel_init(void);
void neopixel_write(uint8_t *pixels);
void neopixel_teardown(void);
@@ -71,14 +75,15 @@ void board_init(void)
button_init(BUTTON_FRESET);
NRFX_DELAY_US(100); // wait for the pin state is stable
#if LEDS_NUMBER > 0
// use PMW0 for LED RED
led_pwm_init(LED_PRIMARY, LED_PRIMARY_PIN);
#if LEDS_NUMBER > 1
led_pwm_init(LED_SECONDARY, LED_SECONDARY_PIN);
#endif
#endif
// use neopixel for use enumeration
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
neopixel_init();
#endif
@@ -94,11 +99,13 @@ void board_init(void)
// #define UICR_REGOUT0_VALUE UICR_REGOUT0_VOUT_3V3
// in board.h when using that power configuration.
#ifdef UICR_REGOUT0_VALUE
if (NRF_UICR->REGOUT0 != UICR_REGOUT0_VALUE)
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) !=
(UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos))
{
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
NRF_UICR->REGOUT0 = UICR_REGOUT0_VALUE;
NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~((uint32_t)UICR_REGOUT0_VOUT_Msk)) |
(UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos);
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
@@ -124,9 +131,11 @@ void board_teardown(void)
SysTick->CTRL = 0;
// Disable and reset PWM for LEDs
#if LEDS_NUMBER > 0
led_pwm_teardown();
#endif
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
neopixel_teardown();
#endif
@@ -315,7 +324,7 @@ void led_state(uint32_t state)
} else if (temp_color_active) {
final_color = (uint8_t*)&rgb_color;
}
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN)
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
if (final_color != NULL) {
neopixel_write(final_color);
}
@@ -430,6 +439,90 @@ void neopixel_write (uint8_t *pixels)
}
#endif
#ifdef LED_APA102
#define BYTE_PER_PIXEL 4
// 4 zero bytes are required to initiate update
#define PATTERN_SIZE() ((APA102_NUMBER*BYTE_PER_PIXEL) + 4)
// N/2 * 1 bits are required at the end
static uint8_t pixels_pattern[PATTERN_SIZE() + 4];
// use SPIM1 for dotstar
void neopixel_init(void)
{
NRF_SPIM_Type* spi = NRF_SPIM1;
nrf_spim_disable(spi);
nrf_gpio_pin_set(LED_APA102_CLK);
nrf_gpio_cfg(LED_APA102_CLK,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_CONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_S0S1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_pin_clear(LED_APA102_DATA);
nrf_gpio_cfg_output(LED_APA102_DATA);
nrf_spim_pins_set(spi, LED_APA102_CLK, LED_APA102_DATA, 0xFFFFFFFF);
nrf_spim_frequency_set(spi, NRF_SPIM_FREQ_4M);
nrf_spim_configure(spi, NRF_SPIM_MODE_3, NRF_SPIM_BIT_ORDER_MSB_FIRST);
nrf_spim_orc_set(spi, 0);
nrf_spim_tx_list_disable(spi);
// Enable the spi
nrf_spim_enable(spi);
uint8_t rgb[3] = {0, 0, 0 };
neopixel_write(rgb);
}
void neopixel_teardown(void)
{
uint8_t rgb[3] = {0, 0, 0 };
neopixel_write(rgb);
NRF_SPIM_Type* spi = NRF_SPIM1;
nrf_spim_disable(spi);
}
// write 3 bytes color RGB to built-in neopixel
void neopixel_write (uint8_t *pixels)
{
NRF_SPIM_Type* spi = NRF_SPIM1;
//brightness, blue, green, red
uint8_t bbgr[BYTE_PER_PIXEL] = {0xE0 | LED_APA102_BRIGHTNESS, pixels[0], pixels[1], pixels[2]};
pixels_pattern[0] = 0;
pixels_pattern[1] = 0;
pixels_pattern[2] = 0;
pixels_pattern[3] = 0;
for (uint8_t i = 4; i < PATTERN_SIZE(); i+=4) {
pixels_pattern[i] = bbgr[0];
pixels_pattern[i+1] = bbgr[1];
pixels_pattern[i+2] = bbgr[2];
pixels_pattern[i+3] = bbgr[3];
}
pixels_pattern[PATTERN_SIZE()] = 0xff;
pixels_pattern[PATTERN_SIZE()+1] = 0xff;
pixels_pattern[PATTERN_SIZE()+2] = 0xff;
pixels_pattern[PATTERN_SIZE()+3] = 0xff;
nrf_spim_tx_buffer_set(spi, pixels_pattern, PATTERN_SIZE() + 4);
nrf_spim_event_clear(spi, NRF_SPIM_EVENT_ENDTX);
nrf_spim_task_trigger(spi, NRF_SPIM_TASK_START);
while(!nrf_spim_event_check(spi, NRF_SPIM_EVENT_ENDTX));
}
#endif
#if defined(LED_RGB_RED_PIN) && defined(LED_RGB_GREEN_PIN) && defined(LED_RGB_BLUE_PIN)
#ifdef LED_SECONDARY_PIN
@@ -0,0 +1,66 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ha Thach for Adafruit Industries
* Copyright (c) 2021 Chris Marc Dailey
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _SPARKFUN_NRF52840_MICROMOD_H_
#define _SPARKFUN_NRF52840_MICROMOD_H_
#define _PINNUM(port, pin) ((port)*32 + (pin))
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
#define LEDS_NUMBER 1
#define LED_PRIMARY_PIN _PINNUM(0, 13)
#define LED_STATE_ON 1
/*------------------------------------------------------------------*/
/* BUTTON
*------------------------------------------------------------------*/
#define BUTTONS_NUMBER 2
#define BUTTON_1 _PINNUM(0, 7)
#define BUTTON_2 _PINNUM(0, 10)
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
#define BLEDIS_MANUFACTURER "SparkFun"
#define BLEDIS_MODEL "MicroMod nRF52840"
//--------------------------------------------------------------------+
// USB
//--------------------------------------------------------------------+
#define USB_DESC_VID 0x1B4F
#define USB_DESC_UF2_PID 0x0022
#define USB_DESC_CDC_ONLY_PID 0x0023
//------------- UF2 -------------//
#define UF2_PRODUCT_NAME "SparkFun MicroMod nRF52840"
#define UF2_VOLUME_LABEL "SFMM852BOOT"
#define UF2_BOARD_ID "nRF52840-micromod-v10"
#define UF2_INDEX_URL "https://www.sparkfun.com/products/16984"
#endif /* _SPARKFUN_NRF52840_MICROMOD_H_ */
@@ -0,0 +1 @@
MCU_SUB_VARIANT = nrf52840
@@ -0,0 +1,19 @@
#include "boards.h"
#include "uf2/configkeys.h"
__attribute__((used, section(".bootloaderConfig")))
const uint32_t bootloaderConfig[] =
{
/* CF2 START */
CFG_MAGIC0, CFG_MAGIC1, // magic
5, 100, // used entries, total entries
204, 0x100000, // FLASH_BYTES = 0x100000
205, 0x40000, // RAM_BYTES = 0x40000
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
209, 0xada52840, // UF2_FAMILY = 0xada52840
210, 0x20, // PINS_PORT_SIZE = PA_32
0, 0, 0, 0, 0, 0, 0, 0
/* CF2 END */
};
+73 -62
View File
@@ -97,18 +97,20 @@ void usb_teardown(void);
*/
/* Magic that written to NRF_POWER->GPREGRET by application when it wish to go into DFU
* - DFU_MAGIC_OTA_APPJUM used by BLEDfu service : SD is already init
* - DFU_MAGIC_OTA_RESET entered by soft reset : SD is not init
* - DFU_MAGIC_SERIAL_ONLY_RESET with CDC interface only
* - DFU_MAGIC_UF2_RESET with CDC and MSC interfaces
* - DFU_MAGIC_OTA_APPJUM : used by BLEDfu service, SD is already inited
* - DFU_MAGIC_OTA_RESET : entered by soft reset, SD is not inited yet
* - DFU_MAGIC_SERIAL_ONLY_RESET : with CDC interface only
* - DFU_MAGIC_UF2_RESET : with CDC and MSC interfaces
* - DFU_MAGIC_SKIP : skip DFU entirely including double reset delay
*
* Note: for DFU_MAGIC_OTA_APPJUM Softdevice must not initialized.
* since it is already in application. In all other case of OTA SD must be initialized
*/
#define DFU_MAGIC_OTA_APPJUM BOOTLOADER_DFU_START // 0xB1
#define DFU_MAGIC_OTA_APPJUM BOOTLOADER_DFU_START // 0xB1
#define DFU_MAGIC_OTA_RESET 0xA8
#define DFU_MAGIC_SERIAL_ONLY_RESET 0x4e
#define DFU_MAGIC_UF2_RESET 0x57
#define DFU_MAGIC_SKIP 0x6d
#define DFU_DBL_RESET_MAGIC 0x5A1AD5 // SALADS
#define DFU_DBL_RESET_APP 0x4ee5677e
@@ -170,13 +172,16 @@ 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));
bool const dfu_skip = (NRF_POWER->GPREGRET == DFU_MAGIC_SKIP);
// Clear GPREGRET if it is our values
if (dfu_start) NRF_POWER->GPREGRET = 0;
if (dfu_start || dfu_skip) NRF_POWER->GPREGRET = 0;
// Save bootloader version to pre-defined register, retrieved by application
// TODO move to CF2
@@ -199,79 +204,85 @@ int main(void)
}
/*------------- Determine DFU mode (Serial, OTA, FRESET or normal) -------------*/
// DFU button pressed
dfu_start = dfu_start || button_pressed(BUTTON_DFU);
// DFU + FRESET are pressed --> OTA
_ota_dfu = _ota_dfu || ( button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) ;
bool const valid_app = bootloader_app_is_valid();
bool const just_start_app = valid_app && !dfu_start && (*dbl_reset_mem) == DFU_DBL_RESET_APP;
if (!just_start_app && APP_ASKS_FOR_SINGLE_TAP_RESET())
dfu_start = 1;
// App mode: register 1st reset and DFU startup (nrf52832)
if ( ! (just_start_app || dfu_start || !valid_app) )
if ( !dfu_skip )
{
// Register our first reset for double reset detection
(*dbl_reset_mem) = DFU_DBL_RESET_MAGIC;
// DFU button pressed
dfu_start = dfu_start || (button_pressed(BUTTON_DFU) && !dfu_skip);
// DFU + FRESET are pressed --> OTA
_ota_dfu = _ota_dfu || ( button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) ;
bool const valid_app = bootloader_app_is_valid();
bool const just_start_app = valid_app && !dfu_start && (*dbl_reset_mem) == DFU_DBL_RESET_APP;
if (!just_start_app && APP_ASKS_FOR_SINGLE_TAP_RESET()) dfu_start = 1;
// App mode: register 1st reset and DFU startup (nrf52832)
if ( ! (just_start_app || dfu_start || !valid_app) )
{
// Register our first reset for double reset detection
(*dbl_reset_mem) = DFU_DBL_RESET_MAGIC;
#ifdef NRF52832_XXAA
/* Even DFU is not active, we still force an 1000 ms dfu serial mode when startup
* to support auto programming from Arduino IDE
*
* Note: Supposedly during this time if RST is press, it will count as double reset.
* However Double Reset WONT work with nrf52832 since its SRAM got cleared anyway.
*/
bootloader_dfu_start(false, DFU_SERIAL_STARTUP_INTERVAL, false);
/* Even DFU is not active, we still force an 1000 ms dfu serial mode when startup
* to support auto programming from Arduino IDE
*
* Note: Supposedly during this time if RST is press, it will count as double reset.
* However Double Reset WONT work with nrf52832 since its SRAM got cleared anyway.
*/
bootloader_dfu_start(false, DFU_SERIAL_STARTUP_INTERVAL, false);
#else
// if RST is pressed during this delay --> if will enter dfu
NRFX_DELAY_MS(DFU_DBL_RESET_DELAY);
// if RST is pressed during this delay --> if will enter dfu
NRFX_DELAY_MS(DFU_DBL_RESET_DELAY);
#endif
}
if (APP_ASKS_FOR_SINGLE_TAP_RESET())
(*dbl_reset_mem) = DFU_DBL_RESET_APP;
else
(*dbl_reset_mem) = 0;
if ( dfu_start || !valid_app )
{
if ( _ota_dfu )
{
led_state(STATE_BLE_DISCONNECTED);
softdev_init(!sd_inited);
sd_inited = true;
}
else
{
led_state(STATE_USB_UNMOUNTED);
usb_init(serial_only_dfu);
}
// Initiate an update of the firmware.
if (APP_ASKS_FOR_SINGLE_TAP_RESET())
{
// 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) );
(*dbl_reset_mem) = DFU_DBL_RESET_APP;
}
else
{
// No timeout if bootloader requires user action (double-reset).
APP_ERROR_CHECK( bootloader_dfu_start(_ota_dfu, 0, false) );
(*dbl_reset_mem) = 0;
}
if ( _ota_dfu )
if ( dfu_start || !valid_app )
{
sd_softdevice_disable();
}else
{
usb_teardown();
if ( _ota_dfu )
{
led_state(STATE_BLE_DISCONNECTED);
softdev_init(!sd_inited);
sd_inited = true;
}
else
{
led_state(STATE_USB_UNMOUNTED);
usb_init(serial_only_dfu);
}
// Initiate an update of the firmware.
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) );
}
else
{
// No timeout if bootloader requires user action (double-reset).
APP_ERROR_CHECK( bootloader_dfu_start(_ota_dfu, 0, false) );
}
if ( _ota_dfu )
{
sd_softdevice_disable();
}else
{
usb_teardown();
}
}
}
// Reset Board
// Reset peripherals
board_teardown();
/* Jump to application if valid