diff --git a/Makefile b/Makefile index 435a75c6..ad087203 100755 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ WFLAGS = \ -Wno-deprecated-declarations -Wpacked -Wredundant-decls -Wnested-externs \ -Wlong-long -Wunreachable-code -Wcast-align \ -Wno-missing-braces -Wno-overflow -Wno-shadow -Wno-attributes -Wno-packed -Wno-pointer-sign -CFLAGS = $(COMMON_FLAGS) \ +CFLAGS += $(COMMON_FLAGS) \ -x c -c -pipe -nostdlib \ --param max-inline-insns-single=500 \ -fno-strict-aliasing -fdata-sections -ffunction-sections \ @@ -29,9 +29,25 @@ $(WFLAGS) UF2_VERSION_BASE = $(shell git describe --dirty --always --tags) ifeq ($(CHIP_FAMILY), samd21) -LINKER_SCRIPT=scripts/samd21j18a.ld -BOOTLOADER_SIZE=8192 -SELF_LINKER_SCRIPT=scripts/samd21j18a_self.ld + BOOTLOADER_SIZE = 8192 + SRAM_BASE_ADDR = 0x20000000 + ifeq ($(USE_SRAM_BL_FLASH),1) + CFLAGS += -DSRAM_BASE_ADDR=$(SRAM_BASE_ADDR) -DSRAM_BL_SIZE=0x2800 + ifdef CONV_SRAM_BL + CFLAGS += -DUSE_STD_FLASH_BL + UPDATE_BL_OFST = $(BOOTLOADER_SIZE) + SELF_LINKER_SCRIPT = scripts/samd21j17a_self_conv_bl.ld + else + UPDATE_BL_OFST = $(SRAM_BASE_ADDR) + SELF_LINKER_SCRIPT = scripts/samd21j17a_self_sram_bl.ld + endif + LINKER_SCRIPT = scripts/samd21j17a_sram_bl.ld + else + + UPDATE_BL_OFST = $(BOOTLOADER_SIZE) + LINKER_SCRIPT = scripts/samd21j18a.ld + SELF_LINKER_SCRIPT = scripts/samd21j18a_self.ld + endif endif ifeq ($(CHIP_FAMILY), samd51) @@ -174,7 +190,7 @@ $(SELF_EXECUTABLE): $(SELF_OBJECTS) -T$(SELF_LINKER_SCRIPT) \ -Wl,-Map,$(BUILD_PATH)/update-$(NAME).map -o $(BUILD_PATH)/update-$(NAME).elf $(SELF_OBJECTS) arm-none-eabi-objcopy -O binary $(BUILD_PATH)/update-$(NAME).elf $(BUILD_PATH)/update-$(NAME).bin - python3 lib/uf2/utils/uf2conv.py -b $(BOOTLOADER_SIZE) -c -o $@ $(BUILD_PATH)/update-$(NAME).bin + python3 lib/uf2/utils/uf2conv.py -b $(UPDATE_BL_OFST) -c -o $@ $(BUILD_PATH)/update-$(NAME).bin $(BUILD_PATH)/%.o: src/%.c $(wildcard inc/*.h boards/*/*.h) $(BUILD_PATH)/uf2_version.h echo "$<" diff --git a/boards/jeff_probe/board.mk b/boards/jeff_probe/board.mk new file mode 100644 index 00000000..79c2b815 --- /dev/null +++ b/boards/jeff_probe/board.mk @@ -0,0 +1,6 @@ +CHIP_FAMILY = samd21 +CHIP_VARIANT = SAMD21E17A + +USE_SRAM_BL_FLASH = 1 +#CONV_SRAM_BL = 1 +CFLAGS += -DCRYSTALLESS diff --git a/boards/jeff_probe/board_config.h b/boards/jeff_probe/board_config.h new file mode 100644 index 00000000..91e401a9 --- /dev/null +++ b/boards/jeff_probe/board_config.h @@ -0,0 +1,20 @@ +#ifndef BOARD_CONFIG_H +#define BOARD_CONFIG_H + +#define VENDOR_NAME "Flirc" +#define PRODUCT_NAME "Jeff Probe" +#define VOLUME_LABEL "JEFF_BOOT" +#define INDEX_URL "https://flirc.tv/products/flirc-jeffprobe" +#define BOARD_ID "SAMD21E17A-Jeff_Probe" + +#define USB_VID 0x1d50 +#define USB_PID 0x6017 + +#define LED_PIN PIN_PA10 + +#define BOOT_LOAD_PIN PIN_PA27 + +// This is needed because SAMD21E17A only has 128kB of flash +#define FLASH_NUM_ROWS 512 + +#endif diff --git a/inc/uf2.h b/inc/uf2.h index 6d13c786..756e753f 100644 --- a/inc/uf2.h +++ b/inc/uf2.h @@ -153,7 +153,7 @@ #define COLOR_START 0x000040 #define COLOR_USB 0x004000 #define COLOR_UART 0x404000 -#define COLOR_LEAVE 0x400040 +#define COLOR_LEAVE 0x000000 #endif /* @@ -248,6 +248,7 @@ void padded_memcpy(char *dst, const char *src, int len); #endif #define DBL_TAP_MAGIC 0xf01669ef // Randomly selected, adjusted to have first and last bit set #define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef +#define DBL_TAP_MAGIC_SRAM_BL 0xf03669ef #if USE_SINGLE_RESET #ifdef SAMD21 @@ -321,6 +322,11 @@ void RGBLED_set_color(uint32_t color); #define LED_RX_TGL() #endif +// For BOOT_LOAD_PIN +#if defined(BOOT_LOAD_PIN) +#define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f)) +#endif + extern uint32_t timerHigh, resetHorizon; void timerTick(void); void delay(uint32_t ms); diff --git a/scripts/samd21j17a_self_conv_bl.ld b/scripts/samd21j17a_self_conv_bl.ld new file mode 100644 index 00000000..12a8f968 --- /dev/null +++ b/scripts/samd21j17a_self_conv_bl.ld @@ -0,0 +1,160 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD21J18A + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00002000, LENGTH = 128k -8k + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16k +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x1000; + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + /* + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + */ + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/scripts/samd21j17a_self_sram_bl.ld b/scripts/samd21j17a_self_sram_bl.ld new file mode 100644 index 00000000..05ffcd27 --- /dev/null +++ b/scripts/samd21j17a_self_sram_bl.ld @@ -0,0 +1,159 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD21J18A + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x1000; + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + /* + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + */ + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > ram + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ram + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/scripts/samd21j17a_sram_bl.ld b/scripts/samd21j17a_sram_bl.ld new file mode 100644 index 00000000..a9007326 --- /dev/null +++ b/scripts/samd21j17a_sram_bl.ld @@ -0,0 +1,165 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD21J18A + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00002000 + ram (rwx) : ORIGIN = 0x20002800, LENGTH = 0x00001800 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x0800; + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + /* + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + */ + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; + + _binfo_start = 0x00002000 - 4 * 4; + .binfo _binfo_start : { + KEEP(*(.binfo)) ; + } > rom +} diff --git a/src/cdc_enumerate.c b/src/cdc_enumerate.c index 2626c89f..7cf5dec6 100644 --- a/src/cdc_enumerate.c +++ b/src/cdc_enumerate.c @@ -721,7 +721,7 @@ uint32_t USB_WriteCore(const void *pData, uint32_t length, uint8_t ep_num, bool //* \brief Send zero length packet through the control endpoint //*---------------------------------------------------------------------------- void AT91F_USB_SendZlp(void) { - uint8_t c; + uint8_t c=0; USB_Write(&c, 0, 0); } diff --git a/src/fat.c b/src/fat.c index 70da28fb..11100715 100644 --- a/src/fat.c +++ b/src/fat.c @@ -219,8 +219,18 @@ void write_block(uint32_t block_no, uint8_t *data, bool quiet, WriteState *state return; } +#ifdef SRAM_BL_SIZE + bool use_flash = bl->targetAddr >= APP_START_ADDRESS && bl->targetAddr < FLASH_SIZE; + bool use_sram = bl->targetAddr >= SRAM_BASE_ADDR && bl->targetAddr < (SRAM_BASE_ADDR + SRAM_BL_SIZE); +#endif + if ((bl->flags & UF2_FLAG_NOFLASH) || bl->payloadSize != 256 || (bl->targetAddr & 0xff) || - bl->targetAddr < APP_START_ADDRESS || bl->targetAddr >= FLASH_SIZE) { +#ifdef SRAM_BL_SIZE + !(use_flash||use_sram) +#else + bl->targetAddr < APP_START_ADDRESS || bl->targetAddr >= FLASH_SIZE +#endif + ){ #if USE_DBG_MSC if (!quiet) logval("invalid target addr", bl->targetAddr); @@ -229,7 +239,22 @@ void write_block(uint32_t block_no, uint8_t *data, bool quiet, WriteState *state // copied from a device; we still want to count these blocks to reset properly } else { // logval("write block at", bl->targetAddr); +#ifdef SRAM_BL_SIZE + if ( use_flash) { + flash_write_row((void *)bl->targetAddr, (void *)bl->data); + *DBL_TAP_PTR = 0; + }else{ + memcpy((void*)bl->targetAddr, (void*)bl->data, FLASH_ROW_SIZE); + if ( bl->targetAddr == SRAM_BASE_ADDR ){ + uint32_t bootAddr = bl->data[4] | (bl->data[5]<<8) | (bl->data[6]<<16) | (bl->data[7]<<24); + if( bootAddr > SRAM_BASE_ADDR && bootAddr < (SRAM_BASE_ADDR + SRAM_BL_SIZE) ){ + *DBL_TAP_PTR = DBL_TAP_MAGIC_SRAM_BL; + } + } + } +#else flash_write_row((void *)bl->targetAddr, (void *)bl->data); +#endif } if (state && bl->numBlocks) { diff --git a/src/main.c b/src/main.c index 095fa0a0..5b9d5135 100644 --- a/src/main.c +++ b/src/main.c @@ -96,6 +96,20 @@ extern int8_t led_tick_step; * */ static void check_start_application(void) { +#ifdef SRAM_BL_SIZE + register uint32_t app_start_address asm("r6") ; + + bool boot_sram = *DBL_TAP_PTR == DBL_TAP_MAGIC_SRAM_BL; + uint32_t base_addr = boot_sram ? SRAM_BASE_ADDR : APP_START_ADDRESS; + uint32_t addr_limit = boot_sram ? SRAM_BASE_ADDR+SRAM_BL_SIZE : FLASH_SIZE; + + app_start_address = *(uint32_t *)( base_addr + 4 ); + if ( app_start_address < base_addr || app_start_address > addr_limit ){ + /* Stay in bootloader */ + return; + } + +#else uint32_t app_start_address; /* Load the Reset Handler address of the application */ @@ -109,6 +123,25 @@ static void check_start_application(void) { /* Stay in bootloader */ return; } +#endif + +#if defined(BOOT_LOAD_PIN) + volatile PortGroup *boot_port = (volatile PortGroup *)(&(PORT->Group[BOOT_LOAD_PIN / 32])); + volatile bool boot_en; + + /* Enable the input mode in Boot GPIO Pin */ + boot_port->DIRCLR.reg = BOOT_PIN_MASK; + boot_port->PINCFG[BOOT_LOAD_PIN & 0x1F].reg = PORT_PINCFG_INEN | PORT_PINCFG_PULLEN; + boot_port->OUTSET.reg = BOOT_PIN_MASK; + /* Read the BOOT_LOAD_PIN status */ + boot_en = (boot_port->IN.reg) & BOOT_PIN_MASK; + + /* Check the bootloader enable condition */ + if (!boot_en) { + /* Stay in bootloader */ + return; + } +#endif #if USE_SINGLE_RESET if (SINGLE_RESET()) { @@ -126,6 +159,10 @@ static void check_start_application(void) { if (RESET_CONTROLLER->RCAUSE.bit.POR) { *DBL_TAP_PTR = 0; } +#ifdef SRAM_BL_SIZE + else if ( *DBL_TAP_PTR == DBL_TAP_MAGIC_SRAM_BL ) { + } +#endif else if (*DBL_TAP_PTR == DBL_TAP_MAGIC) { *DBL_TAP_PTR = 0; return; // stay in bootloader @@ -145,11 +182,21 @@ static void check_start_application(void) { RGBLED_set_color(COLOR_LEAVE); #endif +#ifdef SRAM_BL_SIZE + /* Rebase the vector table base address */ + SCB->VTOR = (uint32_t) base_addr ; +// jump_to_app (app_start_address, *(uint32_t *)base_addr); +// register uint32_t tmp_start asm("r6") = app_start_address; + /* Rebase the Stack Pointer */ + __set_MSP(*(uint32_t *)base_addr); + +#else /* Rebase the Stack Pointer */ __set_MSP(*(uint32_t *)APP_START_ADDRESS); /* Rebase the vector table base address */ SCB->VTOR = ((uint32_t)APP_START_ADDRESS & SCB_VTOR_TBLOFF_Msk); +#endif /* Jump to application Reset Handler in the application */ asm("bx %0" ::"r"(app_start_address)); diff --git a/src/selfmain.c b/src/selfmain.c index 91496d96..82291385 100644 --- a/src/selfmain.c +++ b/src/selfmain.c @@ -183,6 +183,10 @@ int main(void) { logmsg("Update successful!"); +#if ( defined(SRAM_BL_SIZE) && (!defined(USE_STD_FLASH_BL) ) ) + *DBL_TAP_PTR = 0; +#endif + // re-base int vector back to bootloader, so that the flash erase // below doesn't write over the vectors. SCB->VTOR = 0; @@ -191,8 +195,10 @@ int main(void) { // bootloader doesn't run us a second time. We don't need to erase to write // zeros. The remainder of the write unit will be set to 1s which should // preserve the existing values but its not critical. +#if ( (! defined(SRAM_BL_SIZE)) || defined(USE_STD_FLASH_BL) ) uint32_t zeros[2] = {0, 0}; flash_write_words((void *)(BOOTLOADER_K * 1024), zeros, 2); +#endif #ifdef SAMD21 // Re-enable BOOTPROT diff --git a/src/utils.c b/src/utils.c index f1f3224a..7a506efa 100644 --- a/src/utils.c +++ b/src/utils.c @@ -79,7 +79,12 @@ int writeNum(char *buf, uint32_t n, bool full) { void resetIntoApp() { // reset without waiting for double tap (only works for one reset) RGBLED_set_color(COLOR_LEAVE); +#ifdef SRAM_BL_SIZE + if ( *DBL_TAP_PTR != DBL_TAP_MAGIC_SRAM_BL) + *DBL_TAP_PTR = DBL_TAP_MAGIC_QUICK_BOOT; +#else *DBL_TAP_PTR = DBL_TAP_MAGIC_QUICK_BOOT; +#endif NVIC_SystemReset(); }