From 29164c5706490b74a84d44ba0f79cd588fd3e910 Mon Sep 17 00:00:00 2001 From: Valmantas Paliksa Date: Fri, 12 Apr 2019 08:43:16 -0600 Subject: [PATCH] arch/arm/src/stm32f7/stm32_flash.c: Add flash block mapping support for progmem. --- arch/arm/src/stm32f7/Kconfig | 21 ++++ arch/arm/src/stm32f7/Make.defs | 8 +- arch/arm/src/stm32f7/stm32_flash.c | 161 +++++++++++++++++++---------- 3 files changed, 132 insertions(+), 58 deletions(-) diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig index 5316a12142..d5f19303da 100644 --- a/arch/arm/src/stm32f7/Kconfig +++ b/arch/arm/src/stm32f7/Kconfig @@ -1118,6 +1118,27 @@ config STM32F7_FLASH_ART_ACCELERATOR Enable if code and/or read-only data is accessed through ITCM bus instead of AXIM bus. +config STM32F7_PROGMEM + bool "Flash progmem support" + default n + ---help--- + Add progmem support, start block and end block options are provided to + obtain an uniform flash memory mapping. + +if STM32F7_PROGMEM + +config STM32F7_PROGMEM_STARTBLOCK + int "First mapped progmem block" + default 0 + range 0 64 + +config STM32F7_PROGMEM_LASTBLOCK + int "Last mapped progmem block" + default -1 + range -1 64 + +endif # STM32F7_PROGMEM + menu "STM32 Peripheral Support" # These "hidden" settings determine is a peripheral option is available for the diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs index 604add9e72..4ebc645d50 100644 --- a/arch/arm/src/stm32f7/Make.defs +++ b/arch/arm/src/stm32f7/Make.defs @@ -104,10 +104,16 @@ endif CHIP_ASRCS = CHIP_CSRCS = stm32_allocateheap.c stm32_exti_gpio.c stm32_gpio.c CHIP_CSRCS += stm32_irq.c stm32_lowputc.c stm32_rcc.c stm32_serial.c -CHIP_CSRCS += stm32_start.c stm32_capture.c stm32_flash.c +CHIP_CSRCS += stm32_start.c stm32_capture.c stm32_uid.c ifneq ($(CONFIG_SCHED_TICKLESS),y) CHIP_CSRCS += stm32_timerisr.c +else +CHIP_CSRCS += stm32_tickless.c +endif + +ifeq ($(CONFIG_STM32F7_PROGMEM),y) +CHIP_CSRCS += stm32_flash.c endif ifeq ($(CONFIG_BUILD_PROTECTED),y) diff --git a/arch/arm/src/stm32f7/stm32_flash.c b/arch/arm/src/stm32f7/stm32_flash.c index 26619bb65d..ca0da67f58 100644 --- a/arch/arm/src/stm32f7/stm32_flash.c +++ b/arch/arm/src/stm32f7/stm32_flash.c @@ -73,20 +73,33 @@ #define FLASH_OPTKEY2 0x4c5d6e7f #define FLASH_ERASEDVALUE 0xff +#if CONFIG_STM32F7_PROGMEM_STARTBLOCK < 0 || \ + CONFIG_STM32F7_PROGMEM_STARTBLOCK >= STM32_FLASH_NPAGES +# error "Invalid CONFIG_STM32F7_PROGMEM_STARTBLOCK" +#endif + +#if CONFIG_STM32F7_PROGMEM_LASTBLOCK < 0 +# undef CONFIG_STM32F7_PROGMEM_LASTBLOCK +# define CONFIG_STM32F7_PROGMEM_LASTBLOCK (STM32_FLASH_NPAGES-1) +#endif + +#define PROGMEM_NBLOCKS \ + (CONFIG_STM32F7_PROGMEM_LASTBLOCK - CONFIG_STM32F7_PROGMEM_STARTBLOCK + 1) + +#define PAGESIZE 256 + /**************************************************************************** * Private Data ****************************************************************************/ static sem_t g_sem = SEM_INITIALIZER(1); +static const size_t page_sizes[STM32_FLASH_NPAGES] = STM32_FLASH_SIZES; + /**************************************************************************** * Private Functions ****************************************************************************/ -static void up_waste(void) -{ -} - static void sem_lock(void) { int ret; @@ -115,7 +128,6 @@ static void flash_unlock(void) { while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) { - up_waste(); } if (getreg32(STM32_FLASH_CR) & FLASH_CR_LOCK) @@ -132,6 +144,39 @@ static void flash_lock(void) modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_LOCK); } +static uint32_t flash_size(void) +{ + static uint32_t size; + int i; + + if (size == 0) + { + for (i = 0; i < PROGMEM_NBLOCKS; i++) + { + size += page_sizes[CONFIG_STM32F7_PROGMEM_STARTBLOCK + i]; + } + } + + return size; +} + +static uint32_t flash_base(void) +{ + static uint32_t base; + int i; + + if (base == 0) + { + base = STM32_FLASH_BASE; + for (i = 0; i < CONFIG_STM32F7_PROGMEM_STARTBLOCK; i++) + { + base += page_sizes[i]; + } + } + + return base; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -158,27 +203,29 @@ void stm32_flash_lock(void) * ****************************************************************************/ -int stm32_flash_writeprotect(size_t page, bool enabled) +int stm32_flash_writeprotect(size_t block, bool enabled) { uint32_t reg; uint32_t val; - if (page >= STM32_FLASH_NPAGES) + if (block >= PROGMEM_NBLOCKS) { return -EFAULT; } + block = block + CONFIG_STM32F7_PROGMEM_STARTBLOCK; + /* Select the register that contains the bit to be changed */ - if (page < 12) + if (block < 12) { reg = STM32_FLASH_OPTCR; } -#if defined(CONFIG_STM32_FLASH_CONFIG_I) +#if defined(CONFIG_STM32F7_FLASH_CONFIG_I) else { reg = STM32_FLASH_OPTCR1; - page -= 12; + block -= 12; } #else else @@ -195,11 +242,11 @@ int stm32_flash_writeprotect(size_t page, bool enabled) if (enabled) { - val &= ~(1 << (16 + page)); + val &= ~(1 << (16 + block)); } else { - val |= (1 << (16 + page)); + val |= (1 << (16 + block)); } /* Unlock options */ @@ -219,7 +266,6 @@ int stm32_flash_writeprotect(size_t page, bool enabled) while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) { - up_waste(); } /* Re-lock options */ @@ -230,75 +276,57 @@ int stm32_flash_writeprotect(size_t page, bool enabled) size_t up_progmem_pagesize(size_t page) { - static const size_t page_sizes[STM32_FLASH_NPAGES] = STM32_FLASH_SIZES; - - if (page >= sizeof(page_sizes) / sizeof(*page_sizes)) - { - return 0; - } - else - { - return page_sizes[page]; - } + return PAGESIZE; } ssize_t up_progmem_getpage(size_t addr) { - size_t page_end = 0; - size_t i; - - if (addr >= STM32_FLASH_BASE) + if (addr >= flash_base()) { - addr -= STM32_FLASH_BASE; + addr -= flash_base(); } - if (addr >= STM32_FLASH_SIZE) + if (addr >= flash_size()) { return -EFAULT; } - for (i = 0; i < STM32_FLASH_NPAGES; ++i) - { - page_end += up_progmem_pagesize(i); - if (page_end > addr) - { - return i; - } - } - - return -EFAULT; + return addr / PAGESIZE; } size_t up_progmem_getaddress(size_t page) { - size_t base_address = STM32_FLASH_BASE; - size_t i; + size_t base_address = flash_base(); - if (page >= STM32_FLASH_NPAGES) + if (page >= flash_size() / PAGESIZE) { return SIZE_MAX; } - for (i = 0; i < page; ++i) - { - base_address += up_progmem_pagesize(i); - } + base_address += PAGESIZE * page; return base_address; } size_t up_progmem_neraseblocks(void) { - return STM32_FLASH_NPAGES; + return PROGMEM_NBLOCKS; } bool up_progmem_isuniform(void) { -#ifdef STM32_FLASH_PAGESIZE + size_t size = up_progmem_pagesize(0); + int i; + + for (i = 1; i < PROGMEM_NBLOCKS; i++) + { + if (up_progmem_pagesize(i) != size) + { + return false; + } + } + return true; -#else - return false; -#endif } ssize_t up_progmem_ispageerased(size_t page) @@ -307,7 +335,7 @@ ssize_t up_progmem_ispageerased(size_t page) size_t count; size_t bwritten = 0; - if (page >= STM32_FLASH_NPAGES) + if (page >= flash_size() / PAGESIZE) { return -EFAULT; } @@ -328,7 +356,7 @@ ssize_t up_progmem_ispageerased(size_t page) ssize_t up_progmem_eraseblock(size_t block) { - if (block >= STM32_FLASH_NPAGES) + if (block >= PROGMEM_NBLOCKS) { return -EFAULT; } @@ -340,10 +368,13 @@ ssize_t up_progmem_eraseblock(size_t block) flash_unlock(); modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_SER); - modifyreg32(STM32_FLASH_CR, FLASH_CR_SNB_MASK, FLASH_CR_SNB(block)); + modifyreg32(STM32_FLASH_CR, FLASH_CR_SNB_MASK, + FLASH_CR_SNB((block + CONFIG_STM32F7_PROGMEM_STARTBLOCK))); modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_STRT); - while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste(); + while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) + { + } modifyreg32(STM32_FLASH_CR, FLASH_CR_SER, 0); sem_unlock(); @@ -360,6 +391,20 @@ ssize_t up_progmem_eraseblock(size_t block) } } +size_t up_progmem_erasesize(size_t block) +{ + block = block + CONFIG_STM32F7_PROGMEM_STARTBLOCK; + + if (block >= sizeof(page_sizes) / sizeof(*page_sizes)) + { + return 0; + } + else + { + return page_sizes[block]; + } +} + ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) { uint8_t *byte = (uint8_t *)buf; @@ -371,7 +416,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) if (addr >= STM32_FLASH_BASE && addr + count <= STM32_FLASH_BASE + STM32_FLASH_SIZE) { - flash_base = STM32_FLASH_BASE; + flash_base = up_progmem_getaddress(0); } else if (addr >= STM32_OPT_BASE && addr + count <= STM32_OPT_BASE + STM32_OPT_SIZE) @@ -410,7 +455,9 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) ARM_DSB(); - while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste(); + while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) + { + } /* Verify */