From 61cb524fa2cdee86345f72adce0b6195a9b073d6 Mon Sep 17 00:00:00 2001 From: Fotis Panagiotopoulos Date: Fri, 9 Jul 2021 17:53:36 +0300 Subject: [PATCH] lpc17_40: Fixed progmem driver. --- arch/arm/src/lpc17xx_40xx/Kconfig | 15 ---- arch/arm/src/lpc17xx_40xx/lpc17_40_progmem.c | 94 ++++++++++++++------ arch/arm/src/lpc17xx_40xx/lpc17_40_progmem.h | 47 ++-------- 3 files changed, 76 insertions(+), 80 deletions(-) diff --git a/arch/arm/src/lpc17xx_40xx/Kconfig b/arch/arm/src/lpc17xx_40xx/Kconfig index efc617e8ecf..e41961a4f35 100644 --- a/arch/arm/src/lpc17xx_40xx/Kconfig +++ b/arch/arm/src/lpc17xx_40xx/Kconfig @@ -1070,18 +1070,3 @@ config LPC17_40_USBHOST_REGDEBUG also CONFIG_DEBUG_USB_INFO. endmenu - -menu "Memory-Technolgy-Device Options (PROGMEM)" - depends on LPC17_40_PROGMEM - -config LPC17_40_PROGMEM_NSECTORS - int "Size in 32 kB sectors" - default 2 - ---help--- - Number of 32 kB sectors to use as an MTD-device. This driver - will allocate the last n sectors. Only 32 kB sectors are - supported, so this works only on devices with 128 kB, 256 kB and - 512 kB of flash. The maximum number of sectors for these - devices is 2, 6 and 14, respectively. Default is 2. - -endmenu diff --git a/arch/arm/src/lpc17xx_40xx/lpc17_40_progmem.c b/arch/arm/src/lpc17xx_40xx/lpc17_40_progmem.c index 2c4edc1652d..7ad79302487 100644 --- a/arch/arm/src/lpc17xx_40xx/lpc17_40_progmem.c +++ b/arch/arm/src/lpc17xx_40xx/lpc17_40_progmem.c @@ -27,13 +27,12 @@ * Included Files ****************************************************************************/ -#include - #include #include -#include -#include +#include +#include +#include #include #include #include @@ -171,7 +170,7 @@ static uint32_t lpc17_40_iap_copy_ram_to_flash(void *flash, const void *ram, size_t up_progmem_neraseblocks(void) { - return CONFIG_LPC17_40_PROGMEM_NSECTORS; + return LPC17_40_FLASH_NUM_SECTORS; } /**************************************************************************** @@ -184,7 +183,7 @@ size_t up_progmem_neraseblocks(void) bool up_progmem_isuniform(void) { - return true; + return false; } /**************************************************************************** @@ -197,7 +196,7 @@ bool up_progmem_isuniform(void) size_t up_progmem_pagesize(size_t page) { - return (size_t)LPC17_40_PROGMEM_PAGE_SIZE; + return up_progmem_erasesize(page); } /**************************************************************************** @@ -210,7 +209,19 @@ size_t up_progmem_pagesize(size_t page) size_t up_progmem_erasesize(size_t block) { - return (size_t)LPC17_40_PROGMEM_SECTOR_SIZE; + if (block >= LPC17_40_FLASH_NUM_SECTORS) + { + return 0; + } + + if (block < LPC17_40_FLASH_NUM_4K_SECTORS) + { + return (size_t)(4 * 1024); + } + else + { + return (size_t)(32 * 1024); + } } /**************************************************************************** @@ -233,12 +244,25 @@ size_t up_progmem_erasesize(size_t block) ssize_t up_progmem_getpage(size_t addr) { - if (addr >= LPC17_40_PROGMEM_START_ADDR) + ssize_t page; + + if (addr >= LPC17_40_FLASH_SIZE) { - addr -= LPC17_40_PROGMEM_START_ADDR; + return -EFAULT; } - return (size_t)(addr / LPC17_40_PROGMEM_PAGE_SIZE); + if (addr < (LPC17_40_FLASH_NUM_4K_SECTORS * (4 * 1024))) + { + page = addr / (4 * 1024); + } + else + { + page = LPC17_40_FLASH_NUM_4K_SECTORS + + ((addr - (LPC17_40_FLASH_NUM_4K_SECTORS * + (4 * 1024))) / (32 * 1024)); + } + + return page; } /**************************************************************************** @@ -257,8 +281,24 @@ ssize_t up_progmem_getpage(size_t addr) size_t up_progmem_getaddress(size_t page) { - return (size_t)(LPC17_40_PROGMEM_START_ADDR + - page * LPC17_40_PROGMEM_PAGE_SIZE); + size_t addr; + + if (page >= LPC17_40_FLASH_NUM_SECTORS) + { + return SIZE_MAX; + } + + if (page < LPC17_40_FLASH_NUM_4K_SECTORS) + { + addr = page * (4 * 1024); + } + else + { + addr = (LPC17_40_FLASH_NUM_4K_SECTORS * (4 * 1024)) + + ((page - LPC17_40_FLASH_NUM_4K_SECTORS) * (32 * 1024)); + } + + return addr; } /**************************************************************************** @@ -287,27 +327,25 @@ ssize_t up_progmem_eraseblock(size_t block) { uint32_t rc; - if (block >= CONFIG_LPC17_40_PROGMEM_NSECTORS) + if (block >= LPC17_40_FLASH_NUM_SECTORS) { return -EFAULT; } - rc = lpc17_40_iap_prepare_sector_for_write_operation((uint32_t)block + - LPC17_40_PROGMEM_START_SECTOR); + rc = lpc17_40_iap_prepare_sector_for_write_operation((uint32_t)block); if (rc != LPC17_40_IAP_RC_CMD_SUCCESS) { return -EIO; } - rc = lpc17_40_iap_erase_sector((uint32_t)block + - LPC17_40_PROGMEM_START_SECTOR); + rc = lpc17_40_iap_erase_sector((uint32_t)block); if (rc != LPC17_40_IAP_RC_CMD_SUCCESS) { return -EIO; } - return (ssize_t)LPC17_40_PROGMEM_SECTOR_SIZE; + return (ssize_t)up_progmem_erasesize(block); } /**************************************************************************** @@ -330,17 +368,19 @@ ssize_t up_progmem_eraseblock(size_t block) ssize_t up_progmem_ispageerased(size_t page) { + size_t page_size; const uint8_t *p; int i; - if (page >= CONFIG_LPC17_40_PROGMEM_NSECTORS) + if (page >= LPC17_40_FLASH_NUM_SECTORS) { return -EFAULT; } + page_size = up_progmem_pagesize(page); p = (const uint8_t *)up_progmem_getaddress(page); - for (i = 0; i < LPC17_40_PROGMEM_SECTOR_SIZE; i++) + for (i = 0; i < page_size; i++) { if (p[i] != 0xffu) { @@ -348,7 +388,7 @@ ssize_t up_progmem_ispageerased(size_t page) } } - return (ssize_t)(LPC17_40_PROGMEM_SECTOR_SIZE - i); + return (ssize_t)(page_size - i); } /**************************************************************************** @@ -386,13 +426,17 @@ ssize_t up_progmem_write(size_t addr, FAR const void *buf, size_t count) size_t page; uint32_t rc; - if (count % LPC17_40_PROGMEM_PAGE_SIZE) + if (addr % LPC17_40_WRITE_SIZE) + { + return -EFAULT; + } + + if (count % LPC17_40_WRITE_SIZE) { return -EINVAL; } - page = up_progmem_getpage(addr) / LPC17_40_PROGMEM_PAGES_PER_SECTOR + - LPC17_40_PROGMEM_START_SECTOR; + page = up_progmem_getpage(addr); rc = lpc17_40_iap_prepare_sector_for_write_operation((uint32_t)page); diff --git a/arch/arm/src/lpc17xx_40xx/lpc17_40_progmem.h b/arch/arm/src/lpc17xx_40xx/lpc17_40_progmem.h index a9fd3030002..18f766df67f 100644 --- a/arch/arm/src/lpc17xx_40xx/lpc17_40_progmem.h +++ b/arch/arm/src/lpc17xx_40xx/lpc17_40_progmem.h @@ -35,60 +35,27 @@ * ****************************************************************************/ -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -/* The first 16 sectors are 4kB in size and thus not supported as progmem. */ +/* The first 16 sectors are 4kB in size. */ #define LPC17_40_FLASH_NUM_4K_SECTORS 16 -/* The number of 32kB sectors depends on the target device's flash size */ +/* The number of 32kB sectors depends on the target device's flash size. */ #define LPC17_40_FLASH_NUM_32K_SECTORS \ ((LPC17_40_FLASH_SIZE - LPC17_40_FLASH_NUM_4K_SECTORS * 4096) / 32768) -/* The number of 32kB sectors to be used for progmem is configurable. - * The sectors at the end of the flash are used for progmem, the rest is - * left for code and data. - */ +/* The total number of sectors is the sum of the 4k and 32k sectors. */ -#define LPC17_40_PROGMEM_START_SECTOR \ - (LPC17_40_FLASH_NUM_4K_SECTORS + LPC17_40_FLASH_NUM_32K_SECTORS - \ - CONFIG_LPC17_40_PROGMEM_NSECTORS) +#define LPC17_40_FLASH_NUM_SECTORS \ + (LPC17_40_FLASH_NUM_4K_SECTORS + LPC17_40_FLASH_NUM_32K_SECTORS) -/* Base address of the flash segment used for progmem. */ +/* Size of a write page. */ -#define LPC17_40_PROGMEM_START_ADDR \ - (LPC17_40_FLASH_NUM_4K_SECTORS * 4096 + \ - (LPC17_40_PROGMEM_START_SECTOR - LPC17_40_FLASH_NUM_4K_SECTORS) * 32768) - -/* Size of the flash segment used for progmem. */ - -#define LPC17_40_PROGMEM_SIZE (CONFIG_LPC17_40_PROGMEM_NSECTORS * 32768) - -/* Size of a read/write page. */ - -#define LPC17_40_PROGMEM_PAGE_SIZE 256 - -/* Total number of read/write pages. */ - -#define LPC17_40_PROGMEM_NUM_PAGES (LPC17_40_PROGMEM_SIZE / LPC17_40_PROGMEM_PAGE_SIZE) - -/* Size of an erase page. This driver only supports the 32kB sectors. */ - -#define LPC17_40_PROGMEM_SECTOR_SIZE 32768 - -/* Number of read/write pages per erase page. */ - -#define LPC17_40_PROGMEM_PAGES_PER_SECTOR \ - (LPC17_40_PROGMEM_SECTOR_SIZE / LPC17_40_PROGMEM_PAGE_SIZE) +#define LPC17_40_WRITE_SIZE 256 /* LPC17 entry point for In-Application-Programming boot rom service * function