add #26 double reset to DFU, only work with nrf52840 (won't work with nrf52832)
This commit is contained in:
parent
4924e6787f
commit
d8fb8bdbe1
@ -32,6 +32,7 @@ Get the code with following command:
|
|||||||
|
|
||||||
There are 2 pins **DFU & FRST** that bootloader will check upon reset/power
|
There are 2 pins **DFU & FRST** that bootloader will check upon reset/power
|
||||||
|
|
||||||
|
- `Double Reset` Reset twice within 500 ms will enter DFU with UF2 and CDC support (only works with nRF52840)
|
||||||
- `DFU = Low and FRST = High` Enter DFU with UF2 and CDC support
|
- `DFU = Low and FRST = High` Enter DFU with UF2 and CDC support
|
||||||
- `DFU = Low and FRST = Low` Enter DFU with OTA, can be upgraded with mobile application such as Nordic nrfConnect/Toolbox
|
- `DFU = Low and FRST = Low` Enter DFU with OTA, can be upgraded with mobile application such as Nordic nrfConnect/Toolbox
|
||||||
- `DFU = High and FRST = Low` Factory Reset mode, erase firmware application and its data
|
- `DFU = High and FRST = Low` Factory Reset mode, erase firmware application and its data
|
||||||
|
@ -14,7 +14,10 @@ MEMORY
|
|||||||
FLASH (rx) : ORIGIN = 0x74000, LENGTH = 0xA000 /* 40 KB */
|
FLASH (rx) : ORIGIN = 0x74000, LENGTH = 0xA000 /* 40 KB */
|
||||||
|
|
||||||
/** RAM Region for bootloader. */
|
/** RAM Region for bootloader. */
|
||||||
RAM (rwx) : ORIGIN = 0x20003000, LENGTH = 0x20007F80-0x20003000
|
RAM (rwx) : ORIGIN = 0x20003000, LENGTH = 0x20007F7C-0x20003000
|
||||||
|
|
||||||
|
/* Location for double reset detection, no init */
|
||||||
|
DBL_RESET (rwx) : ORIGIN = 0x20007F7C, LENGTH = 0x04
|
||||||
|
|
||||||
/** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
|
/** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
|
||||||
* from application to bootloader when using buttonluss DFU OTA.
|
* from application to bootloader when using buttonluss DFU OTA.
|
||||||
@ -67,6 +70,11 @@ SECTIONS
|
|||||||
KEEP(*(.uicrMbrParamsPageAddress))
|
KEEP(*(.uicrMbrParamsPageAddress))
|
||||||
} > UICR_MBR_PARAM_PAGE
|
} > UICR_MBR_PARAM_PAGE
|
||||||
|
|
||||||
|
.dbl_reset(NOLOAD) :
|
||||||
|
{
|
||||||
|
|
||||||
|
} > DBL_RESET
|
||||||
|
|
||||||
/* No init RAM section in bootloader. Used for bond information exchange. */
|
/* No init RAM section in bootloader. Used for bond information exchange. */
|
||||||
.noinit(NOLOAD) :
|
.noinit(NOLOAD) :
|
||||||
{
|
{
|
||||||
|
@ -17,11 +17,15 @@ MEMORY
|
|||||||
/* Avoid conflict with NOINIT for OTA bond sharing */
|
/* Avoid conflict with NOINIT for OTA bond sharing */
|
||||||
RAM (rwx) : ORIGIN = 0x20008000, LENGTH = 0x20040000-0x20008000
|
RAM (rwx) : ORIGIN = 0x20008000, LENGTH = 0x20040000-0x20008000
|
||||||
|
|
||||||
|
/* Location for double reset detection, no init */
|
||||||
|
DBL_RESET (rwx) : ORIGIN = 0x20007F7C, LENGTH = 0x04
|
||||||
|
|
||||||
/** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
|
/** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
|
||||||
* from application to bootloader when using buttonluss DFU OTA.
|
* from application to bootloader when using buttonluss DFU OTA.
|
||||||
*/
|
*/
|
||||||
NOINIT (rwx) : ORIGIN = 0x20007F80, LENGTH = 0x80
|
NOINIT (rwx) : ORIGIN = 0x20007F80, LENGTH = 0x80
|
||||||
|
|
||||||
|
|
||||||
/** Location of bootloader setting in flash. */
|
/** Location of bootloader setting in flash. */
|
||||||
BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x000FF000, LENGTH = 0x1000
|
BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x000FF000, LENGTH = 0x1000
|
||||||
|
|
||||||
@ -68,11 +72,17 @@ SECTIONS
|
|||||||
KEEP(*(.uicrMbrParamsPageAddress))
|
KEEP(*(.uicrMbrParamsPageAddress))
|
||||||
} > UICR_MBR_PARAM_PAGE
|
} > UICR_MBR_PARAM_PAGE
|
||||||
|
|
||||||
|
.dbl_reset(NOLOAD) :
|
||||||
|
{
|
||||||
|
|
||||||
|
} > DBL_RESET
|
||||||
|
|
||||||
/* No init RAM section in bootloader. Used for bond information exchange. */
|
/* No init RAM section in bootloader. Used for bond information exchange. */
|
||||||
.noinit(NOLOAD) :
|
.noinit(NOLOAD) :
|
||||||
{
|
{
|
||||||
|
|
||||||
} > NOINIT
|
} > NOINIT
|
||||||
|
|
||||||
/* other placements follow here... */
|
/* other placements follow here... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
47
src/main.c
47
src/main.c
@ -98,6 +98,10 @@ void usb_teardown(void);
|
|||||||
#define DFU_MAGIC_SERIAL_ONLY_RESET 0x4e
|
#define DFU_MAGIC_SERIAL_ONLY_RESET 0x4e
|
||||||
#define DFU_MAGIC_UF2_RESET 0x57
|
#define DFU_MAGIC_UF2_RESET 0x57
|
||||||
|
|
||||||
|
#define DFU_DBL_RESET_MAGIC 0x5A1AD5 // SALADS
|
||||||
|
#define DFU_DBL_RESET_DELAY 500
|
||||||
|
#define DFU_DBL_RESET_MEM 0x20007F7C
|
||||||
|
|
||||||
#define BOOTLOADER_VERSION_REGISTER NRF_TIMER2->CC[0]
|
#define BOOTLOADER_VERSION_REGISTER NRF_TIMER2->CC[0]
|
||||||
#define DFU_SERIAL_STARTUP_INTERVAL 1000
|
#define DFU_SERIAL_STARTUP_INTERVAL 1000
|
||||||
|
|
||||||
@ -119,6 +123,8 @@ STATIC_ASSERT( APPDATA_ADDR_START == 0x6D000);
|
|||||||
void adafruit_factory_reset(void);
|
void adafruit_factory_reset(void);
|
||||||
static uint32_t softdev_init(bool init_softdevice);
|
static uint32_t softdev_init(bool init_softdevice);
|
||||||
|
|
||||||
|
uint32_t* dbl_reset_mem = ((uint32_t*) DFU_DBL_RESET_MEM );
|
||||||
|
|
||||||
// true if ble, false if serial
|
// true if ble, false if serial
|
||||||
bool _ota_dfu = false;
|
bool _ota_dfu = false;
|
||||||
bool _ota_connected = false;
|
bool _ota_connected = false;
|
||||||
@ -146,7 +152,8 @@ int main(void)
|
|||||||
bool serial_only_dfu = (NRF_POWER->GPREGRET == DFU_MAGIC_SERIAL_ONLY_RESET);
|
bool serial_only_dfu = (NRF_POWER->GPREGRET == DFU_MAGIC_SERIAL_ONLY_RESET);
|
||||||
|
|
||||||
// start either serial, uf2 or ble
|
// 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 || (NRF_POWER->GPREGRET == DFU_MAGIC_UF2_RESET) ||
|
||||||
|
(((*dbl_reset_mem) == DFU_DBL_RESET_MAGIC) && (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk));
|
||||||
|
|
||||||
// Clear GPREGRET if it is our values
|
// Clear GPREGRET if it is our values
|
||||||
if (dfu_start) NRF_POWER->GPREGRET = 0;
|
if (dfu_start) NRF_POWER->GPREGRET = 0;
|
||||||
@ -174,7 +181,34 @@ int main(void)
|
|||||||
// DFU + FRESET are pressed --> OTA
|
// DFU + FRESET are pressed --> OTA
|
||||||
_ota_dfu = _ota_dfu || ( button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) ;
|
_ota_dfu = _ota_dfu || ( button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) ;
|
||||||
|
|
||||||
if ( dfu_start || !bootloader_app_is_valid(DFU_BANK_0_REGION_START) )
|
|
||||||
|
bool const valid_app = bootloader_app_is_valid(DFU_BANK_0_REGION_START);
|
||||||
|
|
||||||
|
// App mode: register 1st reset and DFU startup (nrf52832)
|
||||||
|
if ( ! (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);
|
||||||
|
#else
|
||||||
|
led_on(LED_RED); // turn on LED to signal user
|
||||||
|
// if RST is pressed during this delay --> if will enter dfu
|
||||||
|
NRFX_DELAY_MS(DFU_DBL_RESET_DELAY);
|
||||||
|
led_off(LED_RED);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
(*dbl_reset_mem) = 0;
|
||||||
|
|
||||||
|
if ( dfu_start || !valid_app )
|
||||||
{
|
{
|
||||||
if ( _ota_dfu )
|
if ( _ota_dfu )
|
||||||
{
|
{
|
||||||
@ -204,15 +238,6 @@ int main(void)
|
|||||||
usb_teardown();
|
usb_teardown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef NRF52832_XXAA
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Adafruit Modification
|
|
||||||
* Even DFU is not active, we still force an 1000 ms dfu serial mode when startup
|
|
||||||
* to support auto programming from Arduino IDE */
|
|
||||||
bootloader_dfu_start(false, DFU_SERIAL_STARTUP_INTERVAL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Adafruit Factory reset
|
// Adafruit Factory reset
|
||||||
if ( !button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) )
|
if ( !button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) )
|
||||||
|
Loading…
Reference in New Issue
Block a user