mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
Diff: targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c
- Revision:
- 174:b96e65c34a4d
- Parent:
- 167:e84263d55307
- Child:
- 184:08ed48f1de7f
--- a/targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c Fri Sep 15 14:59:18 2017 +0100 +++ b/targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c Mon Oct 02 15:33:19 2017 +0100 @@ -13,55 +13,169 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#if DEVICE_FLASH +#include "mbed_critical.h" #include "flash_api.h" -#include "platform/mbed_critical.h" +#include "mbed_assert.h" +#include "cmsis.h" +#include <stdlib.h> +#include <string.h> + +#define MEMMAP (*((volatile unsigned long *) 0x400FC040)) -// This file is automatically generated +#define PLL0CON (*((volatile unsigned long *) 0x400FC080)) +#define PLL0CFG (*((volatile unsigned long *) 0x400FC084)) +#define PLL0STAT (*((volatile unsigned long *) 0x400FC088)) +#define PLL0FEED (*((volatile unsigned long *) 0x400FC08C)) +#define CCLKSEL (*((volatile unsigned long *) 0x400FC104)) +#define CLKSRCSEL (*((volatile unsigned long *) 0x400FC10C)) + +#define STACK_SIZE 64 // Stack Size -#if DEVICE_FLASH +#define SET_VALID_CODE 1 // Set Valid User Code Signature +/* IAP Call */ +typedef void (*IAP_Entry) (unsigned long *cmd, unsigned long *stat); +#define IAP_Call ((IAP_Entry) 0x1FFF1FF1) + +typedef struct flash_s flash_t; +unsigned long CCLK; // CCLK in kHz -#include "flash_data.h" +struct sIAP { // IAP Structure + unsigned long cmd;// Command + unsigned long par[4];// Parameters + unsigned long stat;// Status + unsigned long res[2];// Result +}IAP; + +/* + * Get Sector Number + * Parameter: address: Sector Address + * Return Value: Sector Number + */ -// This is a flash algo binary blob. It is PIC (position independent code) that should be stored in RAM -static uint32_t FLASH_ALGO[] = { - 0x28100b00, 0x210ed302, 0x00d0eb01, 0xf44f4770, 0xfbb1707a, 0x4933f0f0, 0x60084449, 0x20014932, - 0x20006408, 0x20004770, 0xe92d4770, 0xf7ff41f0, 0x4d2effe7, 0x444d4604, 0xe9c52032, 0xf1050400, - 0x4e2b0114, 0x4628460f, 0x47b060ac, 0xb9686968, 0xe9c52034, 0x48230400, 0x444860ac, 0x68004639, - 0x462860e8, 0x696847b0, 0xd0002800, 0xe8bd2001, 0xe92d81f0, 0x461441f0, 0xd10e0006, 0x0100e9d4, - 0xe9d44408, 0x44111202, 0x69214408, 0x69614408, 0x69a14408, 0x42404408, 0x463061e0, 0xffb0f7ff, - 0x21324d12, 0x4f12444d, 0x1000e9c5, 0x0114f105, 0x468860a8, 0x47b84628, 0xb9806968, 0xe9c52033, - 0xf44f0600, 0xe9c56080, 0x48064002, 0x44484641, 0x61286800, 0x47b84628, 0x28006968, 0x2001d0c7, - 0x0000e7c5, 0x00000004, 0x400fc000, 0x00000008, 0x1fff1ff1, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 -}; +unsigned long GetSecNum (unsigned long address) +{ + unsigned long n; + + n = address >> 12; // 4kB Sector + if (n >= 0x10) { + n = 0x0E + (n >> 3); // 32kB Sector + } + + return (n); // Sector Number +} +int32_t flash_init(flash_t *obj) +{ + CCLK = SystemCoreClock / 1000; // CCLK value is in kHz, clk in Hz + + MEMMAP = 0x01;// User Flash Mode + + return (0); +} + +int32_t flash_free(flash_t *obj) +{ + return 0; +} + +int32_t flash_erase_sector(flash_t *obj, uint32_t address) +{ + unsigned long n; + + n = GetSecNum(address); // Get Sector Number + + core_util_critical_section_enter(); + IAP.cmd = 50;// Prepare Sector for Erase + IAP.par[0] = n;// Start Sector + IAP.par[1] = n;// End Sector + IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command + if (IAP.stat) { + return (1); // Command Failed + } -static const flash_algo_t flash_algo_config = { - .init = 0xf, - .uninit = 0x27, - .erase_sector = 0x2b, - .program_page = 0x73, - .static_base = 0xf4, - .algo_blob = FLASH_ALGO -}; + IAP.cmd = 52; // Erase Sector + IAP.par[0] = n;// Start Sector + IAP.par[1] = n;// End Sector + IAP.par[2] = CCLK;// CCLK in kHz + IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command + core_util_critical_section_exit(); + if (IAP.stat) { + return (1); // Command Failed + } + + return (0); // Finished without Errors + +} + +int32_t flash_program_page(flash_t *obj, uint32_t address, + const uint8_t *data, uint32_t size) +{ + unsigned long n; + // always malloc outside critical section + uint8_t *alignedData = malloc(size); + + n = GetSecNum(address); // Get Sector Number + + core_util_critical_section_enter(); + IAP.cmd = 50;// Prepare Sector for Write + IAP.par[0] = n;// Start Sector + IAP.par[1] = n;// End Sector + IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command + if (IAP.stat) { + return (1); // Command Failed + } + + IAP.cmd = 51; // Copy RAM to Flash + IAP.par[0] = address;// Destination Flash Address -static const sector_info_t sectors_info[] = { - {0x0, 0x1000}, - {0x10000, 0x8000}, -}; + if ((unsigned long)data%4==0) { // Word boundary + IAP.par[1] = (unsigned long)data;// Source RAM Address + } else { + memcpy(alignedData,data,size); + IAP.par[1] = (unsigned long)alignedData; // Source RAM Address + } + + IAP.par[2] = 1024; // Fixed Page Size + IAP.par[3] = CCLK;// CCLK in kHz + IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command + core_util_critical_section_exit(); + + if(alignedData !=0) { // We allocated our own memory + free(alignedData); + } + + if (IAP.stat) { + return (1); // Command Failed + } + return (0); // Finished without Errors +} -static const flash_target_config_t flash_target_config = { - .page_size = 0x400, - .flash_start = 0x0, - .flash_size = 0x80000, - .sectors = sectors_info, - .sector_info_count = sizeof(sectors_info) / sizeof(sector_info_t) -}; +uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) +{ + if (address < flash_get_start_address(obj) || address >= flash_get_start_address(obj) +flash_get_size(obj)) { + return MBED_FLASH_INVALID_SIZE; + } + if(GetSecNum(address)>=0x10) { + return 0x8000; + } else { + return 0x1000; + } +} -void flash_set_target_config(flash_t *obj) +uint32_t flash_get_page_size(const flash_t *obj) +{ + return 1024; +} + +uint32_t flash_get_start_address(const flash_t *obj) { - obj->flash_algo = &flash_algo_config; - obj->target_config = &flash_target_config; + return LPC_FLASH_BASE; +} + +uint32_t flash_get_size(const flash_t *obj) +{ + return 0x80000; } #endif