Compare commits

...
26 Commits
Author SHA1 Message Date
Ha Thach c67f0bcf0f Merge pull request #374 from piotrmalek/master
Improve bootloader version parsing from GIT_VERSION
2026-05-21 13:23:49 +07:00
hathach dc42c2a7c0 update cmake version as well 2026-05-21 11:49:01 +07:00
hathach 4b0fc1c504 Merge branch 'master' into fork/piotrmalek/master 2026-05-21 11:38:10 +07:00
Ha Thach 00dba18703 Merge pull request #390 from jesuslg123/auto-reboot-on-usb-disconnected
Exit bootloader and jump to app when USB is disconnected
2026-05-21 11:35:24 +07:00
hathachandClaude Opus 4.7 2f272950fc dfu_transport_serial: normalize new lines to CRLF
PR introduced LF on the new #include and the activity_mark call inside an
otherwise-CRLF file, leaving it mixed-EOL. Convert those lines back to CRLF
to match the rest of the file.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:38:07 +07:00
hathach 64f1b70922 usb tud_mount_cb() to set m_usb_was_mounted 2026-05-20 18:07:12 +07:00
Ha Thach b3ac920e82 Merge pull request #396 from adafruit/skip-app-valid-for-debugger-flash
validate app presence more robustly, allow debugger flashing e.g witjlink without flashing the setting page
2026-05-15 11:22:42 +07:00
hathach 67105f8db3 validate app presence more robustly, allow debugger flashing e.g with jlink without flashing the setting page 2026-05-15 10:56:06 +07:00
Ha Thach 48a149ffcb Merge pull request #393 from adafruit/add-agents-md
update AGENTS.md
2026-03-19 10:43:34 +07:00
hathach ac086326fe restrict GitHub Actions to master branch and add workflow_dispatch trigger 2026-03-19 10:34:52 +07:00
hathach 545fc0534d update AGENTS.md 2026-03-19 10:32:02 +07:00
jesuslg123 1f17efd611 Revert unwanted change 2026-03-08 22:35:48 +01:00
jesuslg123 96c57447c6 Ignore files 2026-03-08 21:20:18 +01:00
jesuslg123 57ce8b2e93 When in bootloader mode and USB is disconnected the system now jumpt to app state to avoid leave the device stuck on bootloader 2026-03-08 21:20:03 +01:00
Ha Thach 8023c1e6a0 Merge pull request #384 from ejtagle/master
Use ACL to protect MBR and Bootloader against accidental FLASH overwrites by the user application
2026-02-25 10:12:54 +07:00
Ha Thach a32baf561b Merge pull request #387 from mestrode/master
Seeed Xiao BLE boards: enable 2nd LED
2026-02-23 16:02:18 +07:00
mestrode dd816e511a Seeed Xiao BLE boards: enable 2nd LED 2026-02-16 17:32:07 +01:00
Eduardo José Tagle 2d889d35d5 Merge branch 'adafruit:master' into master 2026-02-04 12:07:14 -03:00
hathach c2ae4183aa minor 2026-02-03 20:38:21 +07:00
hathach 48cfda2a29 check page size alignment for address as well 2026-02-03 19:01:45 +07:00
hathach 8c45bf843c - always enable flash protect
- clean up code
- add illustrated memory layout for quick ref
2026-02-03 18:47:04 +07:00
hathach c3282f4c0a Merge branch 'master' into fork/piotrmalek/master
# Conflicts:
#	Makefile
2026-02-03 14:46:18 +07:00
Eduardo José Tagle 3714bb727d Merge branch 'adafruit:master' into master 2026-02-02 20:10:09 -03:00
Eduardo José Tagle c61f330c1d Merge branch 'master' of https://github.com/ejtagle/Adafruit_nRF52_Bootloader 2026-02-02 14:28:35 -03:00
Eduardo José Tagle 1307fe7f57 Enable FLASH overwrite protection from user applications for MBR and bootloader 2026-02-02 14:28:12 -03:00
Piotr Małek 951a93abb4 Improve bootloader version parsing from GIT_VERSION 2026-01-14 11:32:04 +01:00
14 changed files with 338 additions and 62 deletions

No files matched your search

+6 -1
View File
@@ -1,13 +1,18 @@
name: Build
on:
workflow_dispatch:
pull_request:
push:
repository_dispatch:
branches: [ master ]
release:
types:
- created
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
set-matrix:
runs-on: ubuntu-latest
+1 -1
View File
@@ -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*
+86 -9
View File
@@ -1,25 +1,102 @@
# Agent Instructions
This file provides guidance to AI agents when working with code in this repository.
## Project Overview
CDC/DFU/UF2 bootloader for Nordic nRF52 microcontrollers (nRF52832, nRF52833, nRF52840). Supports DFU over Serial, BLE OTA, and USB mass storage (UF2). Runs on 60+ boards.
## Style
- Follow the repo `.clang-format` when making changes.
Follow the repo `.clang-format` when making changes.
## Build / Verify
- Prefer CMake for testing/verification.
- Always build both boards during verification:
- `feather_nrf52832`
- `feather_nrf52840_express`
Default board: `feather_nrf52840_express`. Always verify changes against both boards:
- `feather_nrf52840_express` (nRF52840)
- `feather_nrf52832` (nRF52832)
### CMake (preferred)
```bash
cmake -S . -B cmake-build-feather_nrf52832 -DBOARD=feather_nrf52832
cmake --build cmake-build-feather_nrf52832
cmake -S . -B cmake-build-feather_nrf52840_express -DBOARD=feather_nrf52840_express
cmake --build cmake-build-feather_nrf52840_express
cmake -S . -B cmake-build-feather_nrf52832 -DBOARD=feather_nrf52832
cmake --build cmake-build-feather_nrf52832
```
### Make (alternate)
```bash
make BOARD=feather_nrf52832 all
make BOARD=feather_nrf52840_express all
make BOARD=feather_nrf52832 all
```
### Flashing
```bash
make BOARD={board} flash # Flash via JLink
make BOARD={board} flash-dfu # Flash via Serial/CDC DFU
make BOARD={board} flash-sd # Flash SoftDevice only
```
### Build all boards
```bash
python3 tools/build_all.py
```
## Architecture
### MCU Variants and SoftDevices
- **nrf52** (nRF52832): UART-only bootloader, default SoftDevice s132 v6.1.1
- **nrf52833**: USB support, default SoftDevice s140 v7.3.0
- **nrf52840**: Full USB + OTA, default SoftDevice s140 v6.1.1
- Boards may override `SD_NAME`/`SD_VERSION` in their `board.mk`
### Key Source Structure
- `src/main.c` — Bootloader entry point, DFU mode detection, LED/button init
- `src/dfu_init.c` — DFU packet validation, CRC/signature verification
- `src/dfu_ble_svc.c` — BLE DFU service
- `src/flash_nrf5x.c` — Flash memory operations
- `src/boards/boards.c` — Board abstraction (LED control, buttons, timing)
- `src/usb/` — USB stack (nRF52833/nRF52840): CDC serial, MSC storage, UF2 handler
- `src/usb/uf2/ghostfat.c` — Virtual FAT filesystem for UF2 drag-and-drop
### Board Definition System
Each board lives in `src/boards/{board_name}/` with:
- `board.h` — Pin definitions, LED/button assignments, USB VID/PID, UF2 metadata
- `board.mk` — Makefile variable `MCU_SUB_VARIANT` (nrf52, nrf52833, or nrf52840)
- `board.cmake` — CMake variable `MCU_VARIANT`
- `pinconfig.c` — CF2 bootloader configuration (flash/RAM size, UF2 family ID)
### Memory Layout (linker scripts in `linker/`)
- Bootloader occupies ~38KB near end of flash (e.g., 0xF4000–0xFD800 on nRF52840)
- No heap (`__HEAP_SIZE=0`), static allocation only
- Special sections: double-reset detection word, bond info for OTA, MBR params, bootloader settings
### Submodules (`lib/`)
- `tinyusb` — USB device stack
- `nrfx` — Nordic HAL drivers
- `uf2` — UF2 format tools
- `tinycrypt` — Crypto (only when `SIGNED_FW=1`)
- `sdk/`, `sdk11/` — Nordic SDK libraries
- `softdevice/` — Precompiled Bluetooth stack binaries
### Compile-Time Feature Flags
- `SIGNED_FW` — Require signed firmware (disables UF2 unless `FORCE_UF2=1`)
- `DUALBANK_FW` — Dual-bank updates
- `DEFAULT_TO_OTA_DFU` — Default to BLE OTA instead of serial DFU
- `DEBUG` — Enable RTT debugging, larger bootloader region
## PR Review Checklist
- **VID/PID assignment**: When a PR adds or modifies a board, verify `USB_DESC_VID`/`USB_DESC_UF2_PID` in `board.h`. New boards should use unique values. The Adafruit VID `0x239A` is reserved for Adafruit-allocated boards; third-party boards must use their own VID. Some legacy boards intentionally share a VID/PID with a reference board (see `// Shared VID/PID with ...` comments) — these are pending cleanup, not a template for new boards.
## CI
GitHub Actions (`.github/workflows/githubci.yml`) builds all boards in parallel using a matrix generated from `src/boards/` directory names. On release, artifacts (zip, hex, uf2) are uploaded as release assets.
## Required Toolchain
- `arm-none-eabi-gcc` (tested with 12.3.1)
- Python 3 with: `adafruit-nrfutil`, `intelhex`
- `nrfjprog` (for JLink flashing)
+16 -7
View File
@@ -316,13 +316,22 @@ endif()
execute_process(COMMAND git describe --dirty --always --tags OUTPUT_VARIABLE GIT_VERSION)
string(STRIP ${GIT_VERSION} GIT_VERSION)
string(REPLACE "-" ";" RELEASE_VERSION ${GIT_VERSION})
list(GET RELEASE_VERSION 0 RELEASE_VERSION)
string(REPLACE "." ";" RELEASE_VERSION ${RELEASE_VERSION})
list(GET RELEASE_VERSION 0 RELEASE_VERSION_MAJOR)
list(GET RELEASE_VERSION 1 RELEASE_VERSION_MINOR)
list(GET RELEASE_VERSION 2 RELEASE_VERSION_PATCH)
math(EXPR MK_BOOTLOADER_VERSION "(${RELEASE_VERSION_MAJOR} << 16) + (${RELEASE_VERSION_MINOR} << 8) + ${RELEASE_VERSION_PATCH}")
# Extract semantic version numbers (MAJOR.MINOR.PATCH) from GIT_VERSION.
# Supports tags like:
# v1.2.3
# 1.2.3
# 1.2.3-147-gd71abcd
# If the version string does not match MAJOR.MINOR.PATCH, defaults to 0.0.0.
if(GIT_VERSION MATCHES "^v?([0-9]+)\\.([0-9]+)\\.([0-9]+)")
set(RELEASE_VERSION_MAJOR ${CMAKE_MATCH_1})
set(RELEASE_VERSION_MINOR ${CMAKE_MATCH_2})
set(RELEASE_VERSION_PATCH ${CMAKE_MATCH_3})
else()
set(RELEASE_VERSION_MAJOR 0)
set(RELEASE_VERSION_MINOR 0)
set(RELEASE_VERSION_PATCH 0)
endif()
math(EXPR MK_BOOTLOADER_VERSION "((${RELEASE_VERSION_MAJOR} << 16) | (${RELEASE_VERSION_MINOR} << 8) | ${RELEASE_VERSION_PATCH})")
cmake_print_variables(GIT_VERSION MK_BOOTLOADER_VERSION)
+20 -3
View File
@@ -262,7 +262,7 @@ IPATH += \
src/cmsis/include \
src/usb \
$(TUSB_PATH)
ifeq ($(SIGNED_FW), 1)
IPATH += \
$(TCRYPT_PATH)/include
@@ -376,8 +376,25 @@ ifeq ($(DEFAULT_TO_OTA_DFU), 1)
CFLAGS += -DDEFAULT_TO_OTA_DFU
endif
_VER = $(subst ., ,$(word 1, $(subst -, ,$(GIT_VERSION))))
CFLAGS += -DMK_BOOTLOADER_VERSION='($(word 1,$(_VER)) << 16) + ($(word 2,$(_VER)) << 8) + $(word 3,$(_VER))'
# Extract semantic version numbers (MAJOR.MINOR.PATCH) from GIT_VERSION.
# Supports tags like:
# v1.2.3
# 1.2.3
# 1.2.3-147-gd71abcd
# If the version string does not match MAJOR.MINOR.PATCH, defaults to 0.0.0.
_VER3 := $(shell echo "$(GIT_VERSION)" | sed -E 's/^v?([0-9]+)\.([0-9]+)\.([0-9]+).*/\1 \2 \3/; t; s/.*/0 0 0/')
# Split extracted version into individual numeric components
_VER_MAJ := $(word 1,$(_VER3))
_VER_MIN := $(word 2,$(_VER3))
_VER_PAT := $(word 3,$(_VER3))
# Pack MAJOR.MINOR.PATCH into a single 32-bit integer:
# [31:16] MAJOR
# [15:8] MINOR
# [7:0] PATCH
# This value is stored in the bootloader version register and must be a valid C integer constant.
CFLAGS += -DMK_BOOTLOADER_VERSION='((($(_VER_MAJ)<<16)|($(_VER_MIN)<<8)|($(_VER_PAT))))'
# Debug option use RTT for printf
ifeq ($(DEBUG), 1)
@@ -51,9 +51,31 @@ typedef enum
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 );
volatile bool dfu_startup_packet_received = false;
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;
}
void bootloader_mark_usb_mounted(void)
{
m_usb_was_mounted = true;
}
/**@brief Function for handling callbacks from pstorage module.
*
@@ -82,22 +104,17 @@ static void pstorage_callback_handler(pstorage_handle_t * p_handle,
static void dfu_startup_timer_handler(void * p_context)
{
#ifdef NRF_USBD
if (m_cancel_timeout_on_usb && tud_mounted())
// If host enumerated the device, keep waiting — m_usb_was_mounted was set
// by tud_mount_cb() and the unplug path in wait_for_events() will handle exit.
if (m_cancel_timeout_on_usb && m_usb_was_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);
}
// No update activity is received within timeout, exit DFU mode
bootloader_timeout_startup_dfu();
}
/**@brief Function for waiting for events.
@@ -133,6 +150,14 @@ static void wait_for_events(void)
tud_task();
tud_cdc_write_flush();
}
// Exit startup DFU once USB was actually unplugged (VBUS gone), not on a
// host-side re-enumeration or temporary unmount.
if (m_cancel_timeout_on_usb && m_usb_was_mounted &&
!(NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_VBUSDETECT_Msk))
{
bootloader_timeout_startup_dfu();
}
#endif
if ((m_update_status == BOOTLOADER_COMPLETE) ||
@@ -149,23 +174,22 @@ static void wait_for_events(void)
bool bootloader_app_is_valid(void)
{
bool success = false;
uint32_t const app_addr = DFU_BANK_0_REGION_START;
bootloader_settings_t const *p_bootloader_settings;
bootloader_util_settings_get(&p_bootloader_settings);
uint32_t const sp_addr = *((uint32_t*)app_addr);
uint32_t const reset_addr = *((uint32_t*)(app_addr + 4));
enum { EMPTY_FLASH = 0xFFFFFFFFUL };
// Application is invalid if first 2 words are all 0xFFFFFFF
if ( *((uint32_t *)app_addr ) == EMPTY_FLASH &&
*((uint32_t *)(app_addr+4)) == EMPTY_FLASH )
if (sp_addr == EMPTY_FLASH && reset_addr == EMPTY_FLASH)
{
return false;
}
// The application in CODE region 1 is flagged as valid during update.
if ( p_bootloader_settings->bank_0 == BANK_VALID_APP )
bootloader_settings_t const * p_bootloader_settings;
bootloader_util_settings_get(&p_bootloader_settings);
// Primary path: a prior DFU flagged bank 0 as valid.
if (p_bootloader_settings->bank_0 == BANK_VALID_APP)
{
uint16_t image_crc = 0;
@@ -177,10 +201,26 @@ bool bootloader_app_is_valid(void)
NULL);
}
success = (image_crc == p_bootloader_settings->bank_0_crc);
return (image_crc == p_bootloader_settings->bank_0_crc);
}
return success;
// Fallback for debugger-flashed apps: settings page is erased (bank_0 = 0xFFFF)
// but an app may still have been written to bank 0 directly. Accept it if its
// Cortex-M vector table is plausible: initial SP within RAM, reset vector
// within app flash region with the Thumb bit set. The SP upper bound is
// inclusive because the empty-descending stack initializes one past RAM end.
if (p_bootloader_settings->bank_0 == 0xFFFF)
{
uint32_t const ram_start = 0x20000000UL;
uint32_t const ram_end = ram_start + (NRF_FICR->INFO.RAM << 10u);
bool const sp_valid = (sp_addr >= ram_start) && (sp_addr <= ram_end) && ((sp_addr & 3U) == 0);
bool const reset_in_app = (reset_addr & 1U) &&
(reset_addr >= app_addr) &&
(reset_addr < BOOTLOADER_REGION_START);
return sp_valid && reset_in_app;
}
return false;
}
@@ -358,6 +398,8 @@ uint32_t bootloader_dfu_start(bool ota, uint32_t timeout_ms, bool cancel_timeout
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();
@@ -373,8 +415,6 @@ uint32_t bootloader_dfu_start(bool ota, uint32_t timeout_ms, bool cancel_timeout
// - 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);
}
@@ -74,6 +74,20 @@ void bootloader_settings_get(bootloader_settings_t * const p_settings);
*/
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 Mark that the USB DFU session was enumerated by a host.
*
* @details Called from tud_mount_cb(). Enables the USB-unplug exit path in
* wait_for_events(), which exits startup DFU once VBUS is removed.
*/
void bootloader_mark_usb_mounted(void);
/**@brief Function getting state of SoftDevice update in progress.
* After a successfull SoftDevice transfer the system restarts in orderto disable SoftDevice
* and complete the update.
@@ -11,9 +11,12 @@
*/
#include "bootloader_util.h"
#include <stdint.h>
#include <string.h>
#include "dfu_types.h"
#include "nrf_peripherals.h"
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
/**
* @brief Function for aborting current application/bootloader jump to to other app/bootloader.
@@ -164,8 +167,76 @@ static inline void bootloader_util_reset(uint32_t start_addr)
#error Compiler not supported.
#endif
// protect flash region from write access
static uint32_t bootloader_util_flash_protect(uint32_t address, uint32_t size) {
if ((size & (CODE_PAGE_SIZE - 1)) || (address & (CODE_PAGE_SIZE - 1)) || (address > BOOTLOADER_SETTINGS_ADDRESS)) {
return NRF_ERROR_INVALID_PARAM;
}
void bootloader_util_app_start(uint32_t start_addr)
{
bootloader_util_reset(start_addr);
#if defined(ACL_PRESENT)
// Protect using ACL.
static uint32_t acl_instance = 0;
volatile ACL_ACL_Type *p_acl;
const uint32_t mask = (ACL_ACL_PERM_WRITE_Disable << ACL_ACL_PERM_WRITE_Pos);
do {
if (acl_instance >= ACL_REGIONS_COUNT) {
return NRF_ERROR_NO_MEM;
}
p_acl = &NRF_ACL->ACL[acl_instance];
p_acl->ADDR = address;
p_acl->SIZE = size;
p_acl->PERM = mask;
acl_instance++;
} while (p_acl->ADDR != address || p_acl->SIZE != size ||
p_acl->PERM != mask); // Check whether the acl_instance has been used before.
#elif defined(BPROT_PRESENT)
// Protect using BPROT. BPROT does not support read protection.
uint32_t pagenum_start = address / CODE_PAGE_SIZE;
uint32_t pagenum_end = pagenum_start + ((size - 1) / CODE_PAGE_SIZE);
for (uint32_t i = pagenum_start; i <= pagenum_end; i++) {
uint32_t config_index = i / 32;
uint32_t mask = (1 << (i - config_index * 32));
switch (config_index) {
case 0:
NRF_BPROT->CONFIG0 = mask;
break;
case 1:
NRF_BPROT->CONFIG1 = mask;
break;
#if BPROT_REGIONS_NUM > 64
case 2:
NRF_BPROT->CONFIG2 = mask;
break;
case 3:
NRF_BPROT->CONFIG3 = mask;
break;
#endif
}
}
#endif
return NRF_SUCCESS;
}
void bootloader_util_app_start(uint32_t start_addr) {
// Protect MBR against user writes
bootloader_util_flash_protect(0, MBR_SIZE);
// Size of the bootloader flash area to protect (Bootloader + MBR params + Bootloader settings)
const uint32_t area_size = BOOTLOADER_SETTINGS_ADDRESS + CODE_PAGE_SIZE - BOOTLOADER_REGION_START;
// Protect bootloader code and params pages against user writes
bootloader_util_flash_protect(BOOTLOADER_REGION_START, area_size);
// Jump to user application
bootloader_util_reset(start_addr);
}
@@ -12,6 +12,7 @@
#include "dfu_transport.h"
#include <stddef.h>
#include "bootloader.h"
#include "dfu.h"
#include <dfu_types.h>
#include "app_error.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())
{
@@ -20,6 +20,37 @@
* @brief Device Firmware Update module type and definitions.
*/
/*
* Flash layout (nrf52840, see linker/nrf52840.ld):
*
* -------------------------
* | Bootloader Settings |
* | 4 KB |
* |-------------------------| 0xFF000 BOOTLOADER_SETTINGS_ADDRESS
* | MBR Params Page |
* | 4 KB |
* |-------------------------| 0xFE000
* | Bootloader Config |
* | 2 KB |
* |-------------------------| 0xFD800
* | Bootloader |
* | 38 KB |
* |-------------------------| 0xF4000 BOOTLOADER_REGION_START
* | App Data Reserved |
* | 40 KB |
* |-------------------------| 0xEA000
* | Application |
* | Single/ Dual Bank |
* | |
* |-------------------------| CODE_REGION_1_START
* | SoftDevice |
* | 0x26000 (optional) |
* |-------------------------| 0x01000
* | MBR |
* | 4 KB |
* ------------------------- 0x00000
*/
#ifndef DFU_TYPES_H__
#define DFU_TYPES_H__
+4 -4
View File
@@ -28,10 +28,10 @@
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
// The board has 3 leds, but changing the number here causes OTA issues.
#define LEDS_NUMBER 1
#define LED_PRIMARY_PIN PINNUM(0, 26)
#define LED_STATE_ON 0
#define LEDS_NUMBER 2
#define LED_PRIMARY_PIN PINNUM(0, 26) // red
#define LED_SECONDARY_PIN PINNUM(0, 6) // blue
#define LED_STATE_ON 0
#define NEOPIXELS_NUMBER 0
+4 -4
View File
@@ -28,10 +28,10 @@
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
// The board has 3 leds, but changing the number here causes OTA issues.
#define LEDS_NUMBER 1
#define LED_PRIMARY_PIN PINNUM(0, 26)
#define LED_STATE_ON 0
#define LEDS_NUMBER 2
#define LED_PRIMARY_PIN PINNUM(0, 26) // red
#define LED_SECONDARY_PIN PINNUM(0, 6) // blue
#define LED_STATE_ON 0
#define NEOPIXELS_NUMBER 0
+11 -1
View File
@@ -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;
+2
View File
@@ -33,6 +33,7 @@
#include "uf2/uf2.h"
#include "boards.h"
#include "bootloader.h"
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
@@ -115,6 +116,7 @@ void usb_teardown(void) {
//--------------------------------------------------------------------+
void tud_mount_cb(void) {
led_state(STATE_USB_MOUNTED);
bootloader_mark_usb_mounted();
}
void tud_umount_cb(void) {