Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
Diff: targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c
- Revision:
- 175:b96e65c34a4d
- Parent:
- 168:e84263d55307
--- 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
