diff --git a/bootloaders/zero/main.c b/bootloaders/zero/main.c index a1c76860f55ee78704a82ef80854727a8553475b..6d2dd05f05b6007e6834cc31e3380af1a9d81677 100644 --- a/bootloaders/zero/main.c +++ b/bootloaders/zero/main.c @@ -97,6 +97,32 @@ static void check_start_application(void) led_port->DIRSET.reg = (1<<30); led_port->OUTCLR.reg = (1<<30); +#if defined(BOOT_DOUBLE_TAP_ADDRESS) + if (PM->RCAUSE.bit.POR) + { + /* On power-on initialize double-tap */ + BOOT_DOUBLE_TAP_DATA = 0; + } + else + { + if (BOOT_DOUBLE_TAP_DATA == 0) { + /* First tap */ + BOOT_DOUBLE_TAP_DATA = 1; + + for (uint32_t i=0; i<50000; i++) /* 200ms */ + /* force compiler to not optimize this... */ + __asm__ __volatile__(""); + + /* Timeout happened, continue boot... */ + BOOT_DOUBLE_TAP_DATA = 0; + } else { + /* Second tap, stay in bootloader */ + BOOT_DOUBLE_TAP_DATA = 0; + return; + } + } +#endif + uint32_t app_start_address; /* Load the Reset Handler address of the application */ diff --git a/bootloaders/zero/main.h b/bootloaders/zero/main.h index d1d6941afbf380ab4da6ad9d711380b7ea380358..d5e9a58ac3a39fd2a72d1803578eb07d7c9998f7 100644 --- a/bootloaders/zero/main.h +++ b/bootloaders/zero/main.h @@ -34,6 +34,16 @@ #define CPU_FREQUENCY 8000000 #define APP_START_ADDRESS 0x00002000 + +/* + * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by + * quickly tapping two times on the reset button. + * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not + * be touched from the loaded application. + */ +#define BOOT_DOUBLE_TAP_ADDRESS 0x20007FFC +#define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS)) + #define BOOT_LOAD_PIN PIN_PA21 //Pin 7 //#define BOOT_LOAD_PIN PIN_PA15 //Pin 5 #define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f)) diff --git a/bootloaders/zero/samd21_sam_ba.bin b/bootloaders/zero/samd21_sam_ba.bin index 69ced0a312f83d769f7f62e0fe460551481eadce..acad5894ba98254005c34371e58e2619d936876f 100644 Binary files a/bootloaders/zero/samd21_sam_ba.bin and b/bootloaders/zero/samd21_sam_ba.bin differ diff --git a/bootloaders/zero/samd21j18a_flash.ld b/bootloaders/zero/samd21j18a_flash.ld index 8fa81d10d9100f4ad3185f71fc9c05244e2124e2..c9385c487506ee72906b955161fceaaac9bb2ada 100644 --- a/bootloaders/zero/samd21j18a_flash.ld +++ b/bootloaders/zero/samd21j18a_flash.ld @@ -50,7 +50,7 @@ SEARCH_DIR(.) MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000-0x0004 /* 4 bytes used by bootloader to keep data between resets */ } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ diff --git a/variants/arduino_zero/linker_scripts/gcc/flash_with_bootloader.ld b/variants/arduino_zero/linker_scripts/gcc/flash_with_bootloader.ld index 867bf41bfcd83164547c30bef06e1e00f055b407..083e5606a06ac3c5a573362d2bba805cd80fc9a5 100644 --- a/variants/arduino_zero/linker_scripts/gcc/flash_with_bootloader.ld +++ b/variants/arduino_zero/linker_scripts/gcc/flash_with_bootloader.ld @@ -25,8 +25,8 @@ */ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000-0x0004 /* Last 4B used by bootloader */ } /* Linker script to place sections and symbol values. Should be used together