mirror of
https://github.com/oltaco/Adafruit_nRF52_Bootloader_OTAFIX.git
synced 2026-10-24 12:54:08 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc487794b3 | ||
|
|
4f74d41871 | ||
|
|
77c7b7f6dc | ||
|
|
488c6c4463 | ||
|
|
f1b4740579 | ||
|
|
0098324683 | ||
|
|
26bafdcf24 | ||
|
|
5e6690e296 | ||
|
|
78d0c3ae27 | ||
|
|
3895ffbda6 | ||
|
|
a4b5aa4ad1 | ||
|
|
84e843ac86 | ||
|
|
0299cfedb5 | ||
|
|
b404dabe15 | ||
|
|
d88ab7427a | ||
|
|
d481de3e00 | ||
|
|
1a5df60739 | ||
|
|
cb916d3087 | ||
|
|
0670265be0 | ||
|
|
6f7dc38d3c | ||
|
|
91f16ade72 | ||
|
|
81da515ae6 | ||
|
|
3aaef724b2 | ||
|
|
ba5d783c20 | ||
|
|
755cfa95e4 | ||
|
|
b37c078213 | ||
|
|
ba5977d679 | ||
|
|
4ba802d127 | ||
|
|
f9125593b2 | ||
|
|
8ba551c07e |
No files matched your search
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
+1
-1
Submodule lib/tinyusb updated: 4e6aa0d81d...7cdeed54e0.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+100
-7
@@ -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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user