diff options
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | gcc/gcc/same54p20a_flash.ld | 9 | ||||
-rw-r--r-- | usb_dfu_main.c | 12 |
3 files changed, 26 insertions, 3 deletions
@@ -28,10 +28,16 @@ This implementation support the following USB DFU capabilities: Set the corresponding attributes in the 'DFUD_IFACE_DESCB' macro definition in the 'usb/class/dfu/device/dfudf_desc.h' file. +To force the DFU bootloader to start there are several possibilities: + +* if the application following the bootloader is invalid (e.g. MSP is not in RAM) +* if a button is pressed (the button defined in *BUTTON_FORCE_DFU*) +* if the magic value "DFU!" (e.g. 0x44465521) is set at the start of the RAM (e.g. by the main application when performing a USB detach) + Compiling ========= -Use the 'Makefile' script to compile the source code using the ARM none EABI GCC cross-cimpilig toolchain: +Use the 'Makefile' script to compile the source code using the ARM none EABI GCC cross-compiling toolchain: ``` cd gcc make diff --git a/gcc/gcc/same54p20a_flash.ld b/gcc/gcc/same54p20a_flash.ld index 08099d2..32ded77 100644 --- a/gcc/gcc/same54p20a_flash.ld +++ b/gcc/gcc/same54p20a_flash.ld @@ -36,7 +36,8 @@ SEARCH_DIR(.) MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 + /* The first word of the RAM is used for the DFU magic */ + ram (rwx) : ORIGIN = 0x20000000 + 4, LENGTH = 0x00040000 - 4 bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 } @@ -47,6 +48,12 @@ STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stac /* Section Definitions */ SECTIONS { + /* Location of the DFU magic. The application must set the magic value "DFU!" (e.g. 0x44465521) at this address to force the DFU bootloader to start (e.g. to perform a DFU detach) */ + .dfu_magic 0x20000000 : + { + KEEP(*(.dfu_magic)) ; + } + .text : { . = ALIGN(4); diff --git a/usb_dfu_main.c b/usb_dfu_main.c index 96032c5..81b02f8 100644 --- a/usb_dfu_main.c +++ b/usb_dfu_main.c @@ -27,6 +27,9 @@ */ static uint32_t* application_start_address; +/** Location of the DFU magic value to force starting DFU */ +static uint32_t dfu_magic __attribute__ ((section (".dfu_magic"))) __attribute__ ((__used__)); + /** Check if the bootloader is valid * \return true if the bootloader is valid and can be run * \remark initializes application_start_address @@ -48,7 +51,14 @@ static bool check_bootloader(void) */ static bool check_force_dfu(void) { - return (0 == gpio_get_pin_level(BUTTON_FORCE_DFU)); // signal is low when button is pressed + if (0x44465521 == dfu_magic) { // check for the magic value which can be set by the main application + dfu_magic = 0; // erase value so we don't stay in the DFU bootloader upon reset + return true; + } + if (0 == gpio_get_pin_level(BUTTON_FORCE_DFU)) { // signal is low when button is pressed + return true; + } + return false; } /** Check if the application is valid |