diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-08-28 09:11:20 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-08-28 09:11:20 -0600 |
commit | 0c9cc61c16109db3ae44af014243aac1cd5e5d66 (patch) | |
tree | 2421913392053362e054bebcfff826ff304c7113 | |
parent | bdb25bba2e972cea6f46f0a5a3c760153549c2e1 (diff) | |
download | nuttx-0c9cc61c16109db3ae44af014243aac1cd5e5d66.tar.gz nuttx-0c9cc61c16109db3ae44af014243aac1cd5e5d66.tar.bz2 nuttx-0c9cc61c16109db3ae44af014243aac1cd5e5d66.zip |
STM32 FLASH fixes: use size_t instead of uint16_t, make interface more generic. From Freddie Chopin
-rw-r--r-- | apps/system/free/free.c | 6 | ||||
-rw-r--r-- | apps/system/install/install.c | 18 | ||||
-rw-r--r-- | nuttx/arch/arm/src/stm32/chip/stm32_flash.h | 11 | ||||
-rw-r--r-- | nuttx/arch/arm/src/stm32/stm32_flash.c | 176 | ||||
-rw-r--r-- | nuttx/configs/vsn/src/sif.c | 10 | ||||
-rw-r--r-- | nuttx/include/nuttx/progmem.h | 29 |
6 files changed, 190 insertions, 60 deletions
diff --git a/apps/system/free/free.c b/apps/system/free/free.c index c44cd5e22..3132be5ed 100644 --- a/apps/system/free/free.c +++ b/apps/system/free/free.c @@ -51,9 +51,9 @@ static void free_getprogmeminfo(struct mallinfo * mem) { - uint16_t page = 0, stpage = 0xFFFF; - uint16_t pagesize = 0; - int status; + size_t page = 0, stpage = 0xFFFF; + size_t pagesize = 0; + ssize_t status; mem->arena = 0; mem->fordblks = 0; diff --git a/apps/system/install/install.c b/apps/system/install/install.c index 807744a7d..fe0c467f7 100644 --- a/apps/system/install/install.c +++ b/apps/system/install/install.c @@ -87,11 +87,11 @@ static const char *install_script_exec = static int install_getstartpage(int startpage, int pagemargin, int desiredsize) { - uint16_t page = 0, stpage = 0xffff; - uint16_t pagesize = 0; + size_t page = 0, stpage = 0xffff; + size_t pagesize = 0; int maxlen = -1; int maxlen_start = 0xffff; - int status; + ssize_t status; for (status=0, page=0; status >= 0; page++) { @@ -148,11 +148,11 @@ static int install_getstartpage(int startpage, int pagemargin, int desiredsize) static int install_programflash(int startaddr, const char *source) { - int status; - int count; - int totalsize = 0; - char *buf; - FILE *fp; + ssize_t status; + size_t count; + ssize_t totalsize = 0; + char *buf; + FILE *fp; if ((buf = malloc(INSTALL_PROGRAMBLOCKSIZE)) == NULL) { @@ -265,7 +265,7 @@ static int install_remove(const char *scriptname) { FILE *fp; int progsize, addr, freedsize; - uint16_t page; + ssize_t page; int status = 0; /* Parse script */ diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_flash.h b/nuttx/arch/arm/src/stm32/chip/stm32_flash.h index 3a4e97bd1..06e33386a 100644 --- a/nuttx/arch/arm/src/stm32/chip/stm32_flash.h +++ b/nuttx/arch/arm/src/stm32/chip/stm32_flash.h @@ -72,11 +72,15 @@ #elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) # define STM32_FLASH_NPAGES 8 -# define STM32_FLASH_PAGESIZE (128*1024) - /* XXX this is wrong for 427, and not really right for 40x due to mixed page sizes */ +/* STM32F4 has mixed page size */ +# undef STM32_FLASH_PAGESIZE +/* TODO: add proper sizes for each chip in the family - maybe in chip.h? */ +# define STM32_FLASH_SIZE (8 * 128 * 1024) #endif -#define STM32_FLASH_SIZE (STM32_FLASH_NPAGES * STM32_FLASH_PAGESIZE) +#ifdef STM32_FLASH_PAGESIZE +# define STM32_FLASH_SIZE (STM32_FLASH_NPAGES * STM32_FLASH_PAGESIZE) +#endif /* def STM32_FLASH_PAGESIZE */ /* Register Offsets *****************************************************************/ @@ -204,6 +208,7 @@ # define FLASH_CR_PSIZE_X16 (1 << FLASH_CR_PSIZE_SHIFT) /* 01 program x16 */ # define FLASH_CR_PSIZE_X32 (2 << FLASH_CR_PSIZE_SHIFT) /* 10 program x32 */ # define FLASH_CR_PSIZE_X64 (3 << FLASH_CR_PSIZE_SHIFT) /* 11 program x64 */ +# define FLASH_CR_STRT (1 << 16) /* Bit 16: Start Erase */ # define FLASH_CR_EOPIE (1 << 24) /* Bit 24: End of operation interrupt enable */ # define FLASH_CR_ERRIE (1 << 25) /* Bit 25: Error interrupt enable */ # define FLASH_CR_LOCK (1 << 31) /* Bit 31: Lock */ diff --git a/nuttx/arch/arm/src/stm32/stm32_flash.c b/nuttx/arch/arm/src/stm32/stm32_flash.c index f725fb7f7..d9e09da06 100644 --- a/nuttx/arch/arm/src/stm32/stm32_flash.c +++ b/nuttx/arch/arm/src/stm32/stm32_flash.c @@ -57,7 +57,7 @@ /* Only for the STM32F10xx family for now */ -#ifdef CONFIG_STM32_STM32F10XX +#if defined(CONFIG_STM32_STM32F10XX) || defined (CONFIG_STM32_STM32F40XX) /************************************************************************************ * Pre-processor Definitions @@ -66,6 +66,14 @@ #define FLASH_KEY1 0x45670123 #define FLASH_KEY2 0xCDEF89AB +#if defined(CONFIG_STM32_STM32F10XX) +#define FLASH_CR_PAGE_ERASE FLASH_CR_PER +#define FLASH_SR_WRITE_PROTECTION_ERROR FLASH_SR_WRPRT_ERR +#elif defined(CONFIG_STM32_STM32F40XX) +#define FLASH_CR_PAGE_ERASE FLASH_CR_SER +#define FLASH_SR_WRITE_PROTECTION_ERROR FLASH_SR_WRPERR +#endif + /************************************************************************************ * Private Functions ************************************************************************************/ @@ -88,30 +96,78 @@ void stm32_flash_unlock(void) void stm32_flash_lock(void) { - modifyreg16(STM32_FLASH_CR, 0, FLASH_CR_LOCK); + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_LOCK); } /************************************************************************************ * Public Functions ************************************************************************************/ -uint16_t up_progmem_npages(void) +#ifdef CONFIG_STM32_STM32F10XX + +size_t up_progmem_pagesize(size_t page) { - return STM32_FLASH_NPAGES; + return STM32_FLASH_PAGESIZE; } -bool up_progmem_isuniform(void) +ssize_t up_progmem_getpage(size_t addr) { - return true; + if (addr >= STM32_FLASH_BASE) + { + addr -= STM32_FLASH_BASE; + } + + if (addr >= STM32_FLASH_SIZE) + { + return -EFAULT; + } + + return addr / STM32_FLASH_PAGESIZE; } -uint16_t up_progmem_pagesize(uint16_t page) +size_t up_progmem_getaddress(size_t page) { - return STM32_FLASH_PAGESIZE; + if (page >= STM32_FLASH_NPAGES) + { + return SIZE_MAX; + } + + return page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE; +} + +#endif /* def CONFIG_STM32_STM32F10XX */ + +#ifdef CONFIG_STM32_STM32F40XX + +size_t up_progmem_pagesize(size_t page) +{ + static const size_t page_sizes[STM32_FLASH_NPAGES] = + { + 16 * 1024, + 16 * 1024, + 16 * 1024, + 16 * 1024, + 64 * 1024, + 128 * 1024, + 128 * 1024, + 128 * 1024, + }; + + if (page >= sizeof(page_sizes) / sizeof(*page_sizes)) + { + return 0; + } + else + { + return page_sizes[page]; + } } -int up_progmem_getpage(uint32_t addr) +ssize_t up_progmem_getpage(size_t addr) { + size_t page_end = 0; + size_t i; + if (addr >= STM32_FLASH_BASE) { addr -= STM32_FLASH_BASE; @@ -122,13 +178,57 @@ int up_progmem_getpage(uint32_t addr) return -EFAULT; } - return addr / STM32_FLASH_PAGESIZE; + for (i = 0; i < STM32_FLASH_NPAGES; ++i) + { + page_end += up_progmem_pagesize(i); + if (page_end > addr) + { + return i; + } + } + + return -EFAULT; } -int up_progmem_erasepage(uint16_t page) +size_t up_progmem_getaddress(size_t page) { - uint32_t addr; - uint16_t count; + size_t base_address = STM32_FLASH_BASE; + size_t i; + + if (page >= STM32_FLASH_NPAGES) + { + return SIZE_MAX; + } + + for (i = 0; i < page; ++i) + { + base_address += up_progmem_pagesize(i); + } + + return base_address; +} + +#endif /* def CONFIG_STM32_STM32F40XX */ + +size_t up_progmem_npages(void) +{ + return STM32_FLASH_NPAGES; +} + +bool up_progmem_isuniform(void) +{ +#ifdef STM32_FLASH_PAGESIZE + return true; +#else + return false; +#endif /* def STM32_FLASH_PAGESIZE */ +} + +ssize_t up_progmem_erasepage(size_t page) +{ +#ifdef CONFIG_STM32_STM32F10XX + size_t page_address; +#endif /* def CONFIG_STM32_STM32F10XX */ if (page >= STM32_FLASH_NPAGES) { @@ -144,33 +244,38 @@ int up_progmem_erasepage(uint16_t page) stm32_flash_unlock(); - modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PER); - putreg32(page * STM32_FLASH_PAGESIZE, STM32_FLASH_AR); + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PAGE_ERASE); + +#if defined(CONFIG_STM32_STM32F10XX) + /* must be valid - page index checked above */ + page_address = up_progmem_getaddress(page); + putreg32(page_address, STM32_FLASH_AR); +#elif defined(CONFIG_STM32_STM32F40XX) + modifyreg32(STM32_FLASH_CR, FLASH_CR_SNB_MASK, FLASH_CR_SNB(page)); +#endif + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_STRT); while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste(); - modifyreg32(STM32_FLASH_CR, FLASH_CR_PER, 0); + modifyreg32(STM32_FLASH_CR, FLASH_CR_PAGE_ERASE, 0); /* Verify */ - - for (addr = page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE, count = STM32_FLASH_PAGESIZE; - count; count-=4, addr += 4) + if (up_progmem_ispageerased(page) == 0) { - if (getreg32(addr) != 0xffffffff) - { - return -EIO; - } + return up_progmem_pagesize(page); /* success */ + } + else + { + return -EIO; /* failure */ } - - return STM32_FLASH_PAGESIZE; } -int up_progmem_ispageerased(uint16_t page) +ssize_t up_progmem_ispageerased(size_t page) { - uint32_t addr; - uint16_t count; - uint16_t bwritten = 0; + size_t addr; + size_t count; + size_t bwritten = 0; if (page >= STM32_FLASH_NPAGES) { @@ -179,7 +284,7 @@ int up_progmem_ispageerased(uint16_t page) /* Verify */ - for (addr = page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE, count = STM32_FLASH_PAGESIZE; + for (addr = up_progmem_getaddress(page), count = up_progmem_pagesize(page); count; count--, addr++) { if (getreg8(addr) != 0xff) @@ -191,7 +296,7 @@ int up_progmem_ispageerased(uint16_t page) return bwritten; } -int up_progmem_write(uint32_t addr, const void *buf, size_t count) +ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) { uint16_t *hword = (uint16_t *)buf; size_t written = count; @@ -226,6 +331,11 @@ int up_progmem_write(uint32_t addr, const void *buf, size_t count) modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PG); +#if defined(CONFIG_STM32_STM32F40XX) + /* TODO: implement up_progmem_write() to support other sizes than 16-bits */ + modifyreg32(STM32_FLASH_CR, FLASH_CR_PSIZE_MASK, FLASH_CR_PSIZE_X16); +#endif + for (addr += STM32_FLASH_BASE; count; count-=2, hword++, addr+=2) { /* Write half-word and wait to complete */ @@ -236,7 +346,7 @@ int up_progmem_write(uint32_t addr, const void *buf, size_t count) /* Verify */ - if (getreg32(STM32_FLASH_SR) & FLASH_SR_WRPRT_ERR) + if (getreg32(STM32_FLASH_SR) & FLASH_SR_WRITE_PROTECTION_ERROR) { modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0); return -EROFS; @@ -253,4 +363,4 @@ int up_progmem_write(uint32_t addr, const void *buf, size_t count) return written; } -#endif /* CONFIG_STM32_STM32F10XX */ +#endif /* defined(CONFIG_STM32_STM32F10XX) || defined (CONFIG_STM32_STM32F40XX) */ diff --git a/nuttx/configs/vsn/src/sif.c b/nuttx/configs/vsn/src/sif.c index ed7f805a8..d9e859cc7 100644 --- a/nuttx/configs/vsn/src/sif.c +++ b/nuttx/configs/vsn/src/sif.c @@ -566,8 +566,8 @@ int sif_main(int argc, char *argv[]) clock_settime(CLOCK_REALTIME, &t_set); } else if (!strcmp(argv[1], "free")) { - uint16_t page = 0, stpage = 0xFFFF; - int status; + size_t page = 0, stpage = 0xFFFF; + ssize_t status; do { status = up_progmem_ispageerased(page++); @@ -586,13 +586,13 @@ int sif_main(int argc, char *argv[]) return 0; } else if (!strcmp(argv[1], "erase") && argc == 3) { - int page = atoi(argv[2]); + size_t page = atoi(argv[2]); printf("Erase result: %d\n", up_progmem_erasepage(page)); return 0; } else if (!strcmp(argv[1], "flash") && argc == 3) { - uint16_t page = atoi(argv[2]); - uint32_t addr = page * up_progmem_pagesize(page); + size_t page = atoi(argv[2]); + size_t addr = page * up_progmem_pagesize(page); printf("Write result: %d (writing to address %xh)\n", up_progmem_write(addr, "Test", 4), addr); diff --git a/nuttx/include/nuttx/progmem.h b/nuttx/include/nuttx/progmem.h index 46dd1db61..7f5d13f89 100644 --- a/nuttx/include/nuttx/progmem.h +++ b/nuttx/include/nuttx/progmem.h @@ -43,7 +43,6 @@ #include <nuttx/config.h> #include <sys/types.h> -#include <stdint.h> #include <stdbool.h> /**************************************************************************** @@ -70,7 +69,7 @@ extern "C" { * ****************************************************************************/ -uint16_t up_progmem_npages(void); +size_t up_progmem_npages(void); /**************************************************************************** * Name: up_progmem_isuniform @@ -90,7 +89,7 @@ bool up_progmem_isuniform(void); * ****************************************************************************/ -uint16_t up_progmem_pagesize(uint16_t page); +size_t up_progmem_pagesize(size_t page); /**************************************************************************** * Name: up_progmem_getpage @@ -109,7 +108,23 @@ uint16_t up_progmem_pagesize(uint16_t page); * ****************************************************************************/ -int up_progmem_getpage(uint32_t addr); +ssize_t up_progmem_getpage(size_t addr); + +/**************************************************************************** + * Name: up_progmem_getaddress + * + * Description: + * Page to address conversion + * + * Input Parameters: + * page - page index + * + * Returned Value: + * Base address of given page, SIZE_MAX if page index is not valid. + * + ****************************************************************************/ + +size_t up_progmem_getaddress(size_t page); /**************************************************************************** * Name: up_progmem_erasepage @@ -133,7 +148,7 @@ int up_progmem_getpage(uint32_t addr); * ****************************************************************************/ -int up_progmem_erasepage(uint16_t page); +ssize_t up_progmem_erasepage(size_t page); /**************************************************************************** * Name: up_progmem_ispageerased @@ -153,7 +168,7 @@ int up_progmem_erasepage(uint16_t page); * ****************************************************************************/ -int up_progmem_ispageerased(uint16_t page); +ssize_t up_progmem_ispageerased(size_t page); /**************************************************************************** * Name: up_progmem_write @@ -184,7 +199,7 @@ int up_progmem_ispageerased(uint16_t page); * ****************************************************************************/ -int up_progmem_write(uint32_t addr, const void *buf, size_t count); +ssize_t up_progmem_write(size_t addr, const void *buf, size_t count); /* TODO: Define the following functions and their options: * - up_progmem_protect() |