mirror of
https://github.com/oltaco/Adafruit_nRF52_Bootloader_OTAFIX.git
synced 2026-10-23 06:33:03 +00:00
When in bootloader mode and USB is disconnected the system now jumpt to app state to avoid leave the device stuck on bootloader
This commit is contained in:
1 parent
8023c1e6a0
commit
57ce8b2e93
5 files changed
+109
-66
No files matched your search
+1
-1
@@ -56,6 +56,7 @@ dkms.conf
|
||||
|
||||
segger/Output
|
||||
_build/
|
||||
cmake-build-*/
|
||||
bin/
|
||||
*.emSession
|
||||
*.jlink
|
||||
@@ -68,4 +69,3 @@ Makefile.user
|
||||
|
||||
# Exclude all SoftDevice S340 files
|
||||
lib/softdevice/s340*
|
||||
|
||||
@@ -48,12 +48,29 @@ typedef enum
|
||||
BOOTLOADER_RESET_TO_SELF, /**< Bootloader status field for indicating that a reset has been requested and current update process should be aborted and the bootloader must be reentered. */
|
||||
} bootloader_status_t;
|
||||
|
||||
static pstorage_handle_t m_bootsettings_handle; /**< Pstorage handle to use for registration and identifying the bootloader module on subsequent calls to the pstorage module for load and store of bootloader setting in flash. */
|
||||
static bootloader_status_t m_update_status; /**< Current update status for the bootloader module to ensure correct behaviour when updating settings and when update completes. */
|
||||
static bool m_cancel_timeout_on_usb; /**< If set the timeout is cancelled when USB is enumerated. Otherwise, the timeout is only cancelled when DFU update is started. */
|
||||
|
||||
APP_TIMER_DEF( _dfu_startup_timer );
|
||||
volatile bool dfu_startup_packet_received = false;
|
||||
static pstorage_handle_t m_bootsettings_handle; /**< Pstorage handle to use for registration and identifying the bootloader module on subsequent calls to the pstorage module for load and store of bootloader setting in flash. */
|
||||
static bootloader_status_t m_update_status; /**< Current update status for the bootloader module to ensure correct behaviour when updating settings and when update completes. */
|
||||
static bool m_cancel_timeout_on_usb; /**< If set the timeout is cancelled when USB is enumerated. Otherwise, the timeout is only cancelled when DFU update is started. */
|
||||
static bool m_usb_was_mounted; /**< Tracks whether the USB DFU session was ever enumerated so we can exit when cable is later removed. */
|
||||
static bool m_startup_dfu_has_activity; /**< Tracks whether any valid serial or UF2 update traffic has started. */
|
||||
|
||||
APP_TIMER_DEF( _dfu_startup_timer );
|
||||
|
||||
static void bootloader_timeout_startup_dfu(void)
|
||||
{
|
||||
if (!m_startup_dfu_has_activity)
|
||||
{
|
||||
dfu_update_status_t update_status;
|
||||
update_status.status_code = DFU_TIMEOUT;
|
||||
|
||||
bootloader_dfu_update_process(update_status);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_dfu_activity_mark(void)
|
||||
{
|
||||
m_startup_dfu_has_activity = true;
|
||||
}
|
||||
|
||||
/**@brief Function for handling callbacks from pstorage module.
|
||||
*
|
||||
@@ -79,26 +96,20 @@ static void pstorage_callback_handler(pstorage_handle_t * p_handle,
|
||||
/* Terminate the forced DFU mode on startup if no packets is received
|
||||
* by put an terminal handler to scheduler
|
||||
*/
|
||||
static void dfu_startup_timer_handler(void * p_context)
|
||||
{
|
||||
#ifdef NRF_USBD
|
||||
if (m_cancel_timeout_on_usb && tud_mounted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// nRF52832 forced DFU on startup
|
||||
// No packets are received within timeout, exit DFU mode
|
||||
// dfu_startup_packet_received is set by process_dfu_packet() in dfu_transport_serial.c
|
||||
if (!dfu_startup_packet_received)
|
||||
{
|
||||
dfu_update_status_t update_status;
|
||||
update_status.status_code = DFU_TIMEOUT;
|
||||
|
||||
bootloader_dfu_update_process(update_status);
|
||||
}
|
||||
}
|
||||
static void dfu_startup_timer_handler(void * p_context)
|
||||
{
|
||||
#ifdef NRF_USBD
|
||||
if (m_cancel_timeout_on_usb && tud_mounted())
|
||||
{
|
||||
m_usb_was_mounted = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// nRF52832 forced DFU on startup
|
||||
// No update activity is received within timeout, exit DFU mode
|
||||
bootloader_timeout_startup_dfu();
|
||||
}
|
||||
|
||||
/**@brief Function for waiting for events.
|
||||
*
|
||||
@@ -126,14 +137,29 @@ static void wait_for_events(void)
|
||||
// Event received. Process it from the scheduler.
|
||||
app_sched_execute();
|
||||
|
||||
#ifdef NRF_USBD
|
||||
// skip if usb is not inited ( e.g OTA / finializing sd/bootloader )
|
||||
if ( tusb_inited() )
|
||||
{
|
||||
tud_task();
|
||||
tud_cdc_write_flush();
|
||||
}
|
||||
#endif
|
||||
#ifdef NRF_USBD
|
||||
// skip if usb is not inited ( e.g OTA / finializing sd/bootloader )
|
||||
if ( tusb_inited() )
|
||||
{
|
||||
tud_task();
|
||||
tud_cdc_write_flush();
|
||||
}
|
||||
|
||||
if (m_cancel_timeout_on_usb)
|
||||
{
|
||||
if (tusb_inited() && tud_mounted())
|
||||
{
|
||||
m_usb_was_mounted = true;
|
||||
}
|
||||
else if (m_usb_was_mounted &&
|
||||
!(NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_VBUSDETECT_Msk))
|
||||
{
|
||||
// Only exit startup DFU after USB was actually unplugged, not on a host-side
|
||||
// re-enumeration or temporary unmount.
|
||||
bootloader_timeout_startup_dfu();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((m_update_status == BOOTLOADER_COMPLETE) ||
|
||||
(m_update_status == BOOTLOADER_TIMEOUT) ||
|
||||
@@ -353,15 +379,17 @@ uint32_t bootloader_init(void)
|
||||
}
|
||||
|
||||
|
||||
uint32_t bootloader_dfu_start(bool ota, uint32_t timeout_ms, bool cancel_timeout_on_usb)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_cancel_timeout_on_usb = cancel_timeout_on_usb && !ota;
|
||||
|
||||
// Clear swap if banked update is used.
|
||||
err_code = dfu_init();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
uint32_t bootloader_dfu_start(bool ota, uint32_t timeout_ms, bool cancel_timeout_on_usb)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_cancel_timeout_on_usb = cancel_timeout_on_usb && !ota;
|
||||
m_usb_was_mounted = false;
|
||||
m_startup_dfu_has_activity = false;
|
||||
|
||||
// Clear swap if banked update is used.
|
||||
err_code = dfu_init();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
if ( ota )
|
||||
{
|
||||
@@ -369,15 +397,13 @@ uint32_t bootloader_dfu_start(bool ota, uint32_t timeout_ms, bool cancel_timeout
|
||||
}else
|
||||
{
|
||||
// DFU mode with timeout can be
|
||||
// - Forced startup DFU for nRF52832 or
|
||||
// - Makecode single tap reset but no enumerated (battery power)
|
||||
if ( timeout_ms )
|
||||
{
|
||||
dfu_startup_packet_received = false;
|
||||
|
||||
app_timer_create(&_dfu_startup_timer, APP_TIMER_MODE_SINGLE_SHOT, dfu_startup_timer_handler);
|
||||
app_timer_start(_dfu_startup_timer, APP_TIMER_TICKS(timeout_ms), NULL);
|
||||
}
|
||||
// - Forced startup DFU for nRF52832 or
|
||||
// - Makecode single tap reset but no enumerated (battery power)
|
||||
if ( timeout_ms )
|
||||
{
|
||||
app_timer_create(&_dfu_startup_timer, APP_TIMER_MODE_SINGLE_SHOT, dfu_startup_timer_handler);
|
||||
app_timer_start(_dfu_startup_timer, APP_TIMER_TICKS(timeout_ms), NULL);
|
||||
}
|
||||
|
||||
err_code = dfu_transport_serial_update_start();
|
||||
}
|
||||
|
||||
@@ -68,11 +68,18 @@ void bootloader_app_start(void);
|
||||
*/
|
||||
void bootloader_settings_get(bootloader_settings_t * const p_settings);
|
||||
|
||||
/**@brief Function for processing DFU status update.
|
||||
*
|
||||
* @param[in] update_status DFU update status.
|
||||
*/
|
||||
void bootloader_dfu_update_process(dfu_update_status_t update_status);
|
||||
/**@brief Function for processing DFU status update.
|
||||
*
|
||||
* @param[in] update_status DFU update status.
|
||||
*/
|
||||
void bootloader_dfu_update_process(dfu_update_status_t update_status);
|
||||
|
||||
/**@brief Mark that startup DFU has received valid update activity.
|
||||
*
|
||||
* @details This suppresses the startup timeout or USB unplug fallback that is only
|
||||
* meant for the "entered bootloader, but never started an update" case.
|
||||
*/
|
||||
void bootloader_dfu_activity_mark(void);
|
||||
|
||||
/**@brief Function getting state of SoftDevice update in progress.
|
||||
* After a successfull SoftDevice transfer the system restarts in orderto disable SoftDevice
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dfu_transport.h"
|
||||
#include <stddef.h>
|
||||
#include "dfu.h"
|
||||
#include <dfu_types.h>
|
||||
#include "dfu_transport.h"
|
||||
#include <stddef.h>
|
||||
#include "bootloader.h"
|
||||
#include "dfu.h"
|
||||
#include <dfu_types.h>
|
||||
#include "app_error.h"
|
||||
#include "app_util.h"
|
||||
#include "hci_transport.h"
|
||||
@@ -197,9 +198,8 @@ static void process_dfu_packet(void * p_event_data, uint16_t event_size)
|
||||
uint32_t index;
|
||||
dfu_update_packet_t * packet;
|
||||
|
||||
// Adafruit modification for startup dfu
|
||||
extern bool dfu_startup_packet_received;
|
||||
dfu_startup_packet_received = true;
|
||||
// Mark that startup DFU has transitioned into a real update flow.
|
||||
bootloader_dfu_activity_mark();
|
||||
|
||||
while (false == DATA_QUEUE_EMPTY())
|
||||
{
|
||||
|
||||
+11
-1
@@ -145,9 +145,19 @@ int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t*
|
||||
uint32_t count = 0;
|
||||
while ( count < bufsize )
|
||||
{
|
||||
int written;
|
||||
|
||||
// Consider non-uf2 block write as successful
|
||||
// only break if write_block is busy with flashing (return 0)
|
||||
if ( 0 == write_block(lba, buffer, &_wr_state) ) break;
|
||||
written = write_block(lba, buffer, &_wr_state);
|
||||
if ( written > 0 )
|
||||
{
|
||||
bootloader_dfu_activity_mark();
|
||||
}
|
||||
else if ( written == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
lba++;
|
||||
buffer += 512;
|
||||
|
||||
Reference in new issue
Block a user