mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

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