mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c@174:b96e65c34a4d, 2017-10-02 (annotated)
- Committer:
- AnnaBridge
- Date:
- Mon Oct 02 15:33:19 2017 +0100
- Revision:
- 174:b96e65c34a4d
- Parent:
- 167:e84263d55307
- Child:
- 184:08ed48f1de7f
This updates the lib to the mbed lib v 152
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AnnaBridge | 167:e84263d55307 | 1 | /* mbed Microcontroller Library |
AnnaBridge | 167:e84263d55307 | 2 | * Copyright (c) 2017 ARM Limited |
AnnaBridge | 167:e84263d55307 | 3 | * |
AnnaBridge | 167:e84263d55307 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
AnnaBridge | 167:e84263d55307 | 5 | * you may not use this file except in compliance with the License. |
AnnaBridge | 167:e84263d55307 | 6 | * You may obtain a copy of the License at |
AnnaBridge | 167:e84263d55307 | 7 | * |
AnnaBridge | 167:e84263d55307 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
AnnaBridge | 167:e84263d55307 | 9 | * |
AnnaBridge | 167:e84263d55307 | 10 | * Unless required by applicable law or agreed to in writing, software |
AnnaBridge | 167:e84263d55307 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
AnnaBridge | 167:e84263d55307 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
AnnaBridge | 167:e84263d55307 | 13 | * See the License for the specific language governing permissions and |
AnnaBridge | 167:e84263d55307 | 14 | * limitations under the License. |
AnnaBridge | 167:e84263d55307 | 15 | */ |
AnnaBridge | 174:b96e65c34a4d | 16 | #if DEVICE_FLASH |
AnnaBridge | 174:b96e65c34a4d | 17 | #include "mbed_critical.h" |
AnnaBridge | 167:e84263d55307 | 18 | |
AnnaBridge | 167:e84263d55307 | 19 | #include "flash_api.h" |
AnnaBridge | 174:b96e65c34a4d | 20 | #include "mbed_assert.h" |
AnnaBridge | 174:b96e65c34a4d | 21 | #include "cmsis.h" |
AnnaBridge | 174:b96e65c34a4d | 22 | #include <stdlib.h> |
AnnaBridge | 174:b96e65c34a4d | 23 | #include <string.h> |
AnnaBridge | 174:b96e65c34a4d | 24 | |
AnnaBridge | 174:b96e65c34a4d | 25 | #define MEMMAP (*((volatile unsigned long *) 0x400FC040)) |
AnnaBridge | 167:e84263d55307 | 26 | |
AnnaBridge | 174:b96e65c34a4d | 27 | #define PLL0CON (*((volatile unsigned long *) 0x400FC080)) |
AnnaBridge | 174:b96e65c34a4d | 28 | #define PLL0CFG (*((volatile unsigned long *) 0x400FC084)) |
AnnaBridge | 174:b96e65c34a4d | 29 | #define PLL0STAT (*((volatile unsigned long *) 0x400FC088)) |
AnnaBridge | 174:b96e65c34a4d | 30 | #define PLL0FEED (*((volatile unsigned long *) 0x400FC08C)) |
AnnaBridge | 174:b96e65c34a4d | 31 | #define CCLKSEL (*((volatile unsigned long *) 0x400FC104)) |
AnnaBridge | 174:b96e65c34a4d | 32 | #define CLKSRCSEL (*((volatile unsigned long *) 0x400FC10C)) |
AnnaBridge | 174:b96e65c34a4d | 33 | |
AnnaBridge | 174:b96e65c34a4d | 34 | #define STACK_SIZE 64 // Stack Size |
AnnaBridge | 167:e84263d55307 | 35 | |
AnnaBridge | 174:b96e65c34a4d | 36 | #define SET_VALID_CODE 1 // Set Valid User Code Signature |
AnnaBridge | 174:b96e65c34a4d | 37 | /* IAP Call */ |
AnnaBridge | 174:b96e65c34a4d | 38 | typedef void (*IAP_Entry) (unsigned long *cmd, unsigned long *stat); |
AnnaBridge | 174:b96e65c34a4d | 39 | #define IAP_Call ((IAP_Entry) 0x1FFF1FF1) |
AnnaBridge | 174:b96e65c34a4d | 40 | |
AnnaBridge | 174:b96e65c34a4d | 41 | typedef struct flash_s flash_t; |
AnnaBridge | 174:b96e65c34a4d | 42 | unsigned long CCLK; // CCLK in kHz |
AnnaBridge | 167:e84263d55307 | 43 | |
AnnaBridge | 174:b96e65c34a4d | 44 | struct sIAP { // IAP Structure |
AnnaBridge | 174:b96e65c34a4d | 45 | unsigned long cmd;// Command |
AnnaBridge | 174:b96e65c34a4d | 46 | unsigned long par[4];// Parameters |
AnnaBridge | 174:b96e65c34a4d | 47 | unsigned long stat;// Status |
AnnaBridge | 174:b96e65c34a4d | 48 | unsigned long res[2];// Result |
AnnaBridge | 174:b96e65c34a4d | 49 | }IAP; |
AnnaBridge | 174:b96e65c34a4d | 50 | |
AnnaBridge | 174:b96e65c34a4d | 51 | /* |
AnnaBridge | 174:b96e65c34a4d | 52 | * Get Sector Number |
AnnaBridge | 174:b96e65c34a4d | 53 | * Parameter: address: Sector Address |
AnnaBridge | 174:b96e65c34a4d | 54 | * Return Value: Sector Number |
AnnaBridge | 174:b96e65c34a4d | 55 | */ |
AnnaBridge | 167:e84263d55307 | 56 | |
AnnaBridge | 174:b96e65c34a4d | 57 | unsigned long GetSecNum (unsigned long address) |
AnnaBridge | 174:b96e65c34a4d | 58 | { |
AnnaBridge | 174:b96e65c34a4d | 59 | unsigned long n; |
AnnaBridge | 174:b96e65c34a4d | 60 | |
AnnaBridge | 174:b96e65c34a4d | 61 | n = address >> 12; // 4kB Sector |
AnnaBridge | 174:b96e65c34a4d | 62 | if (n >= 0x10) { |
AnnaBridge | 174:b96e65c34a4d | 63 | n = 0x0E + (n >> 3); // 32kB Sector |
AnnaBridge | 174:b96e65c34a4d | 64 | } |
AnnaBridge | 174:b96e65c34a4d | 65 | |
AnnaBridge | 174:b96e65c34a4d | 66 | return (n); // Sector Number |
AnnaBridge | 174:b96e65c34a4d | 67 | } |
AnnaBridge | 174:b96e65c34a4d | 68 | int32_t flash_init(flash_t *obj) |
AnnaBridge | 174:b96e65c34a4d | 69 | { |
AnnaBridge | 174:b96e65c34a4d | 70 | CCLK = SystemCoreClock / 1000; // CCLK value is in kHz, clk in Hz |
AnnaBridge | 174:b96e65c34a4d | 71 | |
AnnaBridge | 174:b96e65c34a4d | 72 | MEMMAP = 0x01;// User Flash Mode |
AnnaBridge | 174:b96e65c34a4d | 73 | |
AnnaBridge | 174:b96e65c34a4d | 74 | return (0); |
AnnaBridge | 174:b96e65c34a4d | 75 | } |
AnnaBridge | 174:b96e65c34a4d | 76 | |
AnnaBridge | 174:b96e65c34a4d | 77 | int32_t flash_free(flash_t *obj) |
AnnaBridge | 174:b96e65c34a4d | 78 | { |
AnnaBridge | 174:b96e65c34a4d | 79 | return 0; |
AnnaBridge | 174:b96e65c34a4d | 80 | } |
AnnaBridge | 174:b96e65c34a4d | 81 | |
AnnaBridge | 174:b96e65c34a4d | 82 | int32_t flash_erase_sector(flash_t *obj, uint32_t address) |
AnnaBridge | 174:b96e65c34a4d | 83 | { |
AnnaBridge | 174:b96e65c34a4d | 84 | unsigned long n; |
AnnaBridge | 174:b96e65c34a4d | 85 | |
AnnaBridge | 174:b96e65c34a4d | 86 | n = GetSecNum(address); // Get Sector Number |
AnnaBridge | 174:b96e65c34a4d | 87 | |
AnnaBridge | 174:b96e65c34a4d | 88 | core_util_critical_section_enter(); |
AnnaBridge | 174:b96e65c34a4d | 89 | IAP.cmd = 50;// Prepare Sector for Erase |
AnnaBridge | 174:b96e65c34a4d | 90 | IAP.par[0] = n;// Start Sector |
AnnaBridge | 174:b96e65c34a4d | 91 | IAP.par[1] = n;// End Sector |
AnnaBridge | 174:b96e65c34a4d | 92 | IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command |
AnnaBridge | 174:b96e65c34a4d | 93 | if (IAP.stat) { |
AnnaBridge | 174:b96e65c34a4d | 94 | return (1); // Command Failed |
AnnaBridge | 174:b96e65c34a4d | 95 | } |
AnnaBridge | 167:e84263d55307 | 96 | |
AnnaBridge | 174:b96e65c34a4d | 97 | IAP.cmd = 52; // Erase Sector |
AnnaBridge | 174:b96e65c34a4d | 98 | IAP.par[0] = n;// Start Sector |
AnnaBridge | 174:b96e65c34a4d | 99 | IAP.par[1] = n;// End Sector |
AnnaBridge | 174:b96e65c34a4d | 100 | IAP.par[2] = CCLK;// CCLK in kHz |
AnnaBridge | 174:b96e65c34a4d | 101 | IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command |
AnnaBridge | 174:b96e65c34a4d | 102 | core_util_critical_section_exit(); |
AnnaBridge | 174:b96e65c34a4d | 103 | if (IAP.stat) { |
AnnaBridge | 174:b96e65c34a4d | 104 | return (1); // Command Failed |
AnnaBridge | 174:b96e65c34a4d | 105 | } |
AnnaBridge | 174:b96e65c34a4d | 106 | |
AnnaBridge | 174:b96e65c34a4d | 107 | return (0); // Finished without Errors |
AnnaBridge | 174:b96e65c34a4d | 108 | |
AnnaBridge | 174:b96e65c34a4d | 109 | } |
AnnaBridge | 174:b96e65c34a4d | 110 | |
AnnaBridge | 174:b96e65c34a4d | 111 | int32_t flash_program_page(flash_t *obj, uint32_t address, |
AnnaBridge | 174:b96e65c34a4d | 112 | const uint8_t *data, uint32_t size) |
AnnaBridge | 174:b96e65c34a4d | 113 | { |
AnnaBridge | 174:b96e65c34a4d | 114 | unsigned long n; |
AnnaBridge | 174:b96e65c34a4d | 115 | // always malloc outside critical section |
AnnaBridge | 174:b96e65c34a4d | 116 | uint8_t *alignedData = malloc(size); |
AnnaBridge | 174:b96e65c34a4d | 117 | |
AnnaBridge | 174:b96e65c34a4d | 118 | n = GetSecNum(address); // Get Sector Number |
AnnaBridge | 174:b96e65c34a4d | 119 | |
AnnaBridge | 174:b96e65c34a4d | 120 | core_util_critical_section_enter(); |
AnnaBridge | 174:b96e65c34a4d | 121 | IAP.cmd = 50;// Prepare Sector for Write |
AnnaBridge | 174:b96e65c34a4d | 122 | IAP.par[0] = n;// Start Sector |
AnnaBridge | 174:b96e65c34a4d | 123 | IAP.par[1] = n;// End Sector |
AnnaBridge | 174:b96e65c34a4d | 124 | IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command |
AnnaBridge | 174:b96e65c34a4d | 125 | if (IAP.stat) { |
AnnaBridge | 174:b96e65c34a4d | 126 | return (1); // Command Failed |
AnnaBridge | 174:b96e65c34a4d | 127 | } |
AnnaBridge | 174:b96e65c34a4d | 128 | |
AnnaBridge | 174:b96e65c34a4d | 129 | IAP.cmd = 51; // Copy RAM to Flash |
AnnaBridge | 174:b96e65c34a4d | 130 | IAP.par[0] = address;// Destination Flash Address |
AnnaBridge | 167:e84263d55307 | 131 | |
AnnaBridge | 174:b96e65c34a4d | 132 | if ((unsigned long)data%4==0) { // Word boundary |
AnnaBridge | 174:b96e65c34a4d | 133 | IAP.par[1] = (unsigned long)data;// Source RAM Address |
AnnaBridge | 174:b96e65c34a4d | 134 | } else { |
AnnaBridge | 174:b96e65c34a4d | 135 | memcpy(alignedData,data,size); |
AnnaBridge | 174:b96e65c34a4d | 136 | IAP.par[1] = (unsigned long)alignedData; // Source RAM Address |
AnnaBridge | 174:b96e65c34a4d | 137 | } |
AnnaBridge | 174:b96e65c34a4d | 138 | |
AnnaBridge | 174:b96e65c34a4d | 139 | IAP.par[2] = 1024; // Fixed Page Size |
AnnaBridge | 174:b96e65c34a4d | 140 | IAP.par[3] = CCLK;// CCLK in kHz |
AnnaBridge | 174:b96e65c34a4d | 141 | IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command |
AnnaBridge | 174:b96e65c34a4d | 142 | core_util_critical_section_exit(); |
AnnaBridge | 174:b96e65c34a4d | 143 | |
AnnaBridge | 174:b96e65c34a4d | 144 | if(alignedData !=0) { // We allocated our own memory |
AnnaBridge | 174:b96e65c34a4d | 145 | free(alignedData); |
AnnaBridge | 174:b96e65c34a4d | 146 | } |
AnnaBridge | 174:b96e65c34a4d | 147 | |
AnnaBridge | 174:b96e65c34a4d | 148 | if (IAP.stat) { |
AnnaBridge | 174:b96e65c34a4d | 149 | return (1); // Command Failed |
AnnaBridge | 174:b96e65c34a4d | 150 | } |
AnnaBridge | 174:b96e65c34a4d | 151 | return (0); // Finished without Errors |
AnnaBridge | 174:b96e65c34a4d | 152 | } |
AnnaBridge | 167:e84263d55307 | 153 | |
AnnaBridge | 174:b96e65c34a4d | 154 | uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) |
AnnaBridge | 174:b96e65c34a4d | 155 | { |
AnnaBridge | 174:b96e65c34a4d | 156 | if (address < flash_get_start_address(obj) || address >= flash_get_start_address(obj) +flash_get_size(obj)) { |
AnnaBridge | 174:b96e65c34a4d | 157 | return MBED_FLASH_INVALID_SIZE; |
AnnaBridge | 174:b96e65c34a4d | 158 | } |
AnnaBridge | 174:b96e65c34a4d | 159 | if(GetSecNum(address)>=0x10) { |
AnnaBridge | 174:b96e65c34a4d | 160 | return 0x8000; |
AnnaBridge | 174:b96e65c34a4d | 161 | } else { |
AnnaBridge | 174:b96e65c34a4d | 162 | return 0x1000; |
AnnaBridge | 174:b96e65c34a4d | 163 | } |
AnnaBridge | 174:b96e65c34a4d | 164 | } |
AnnaBridge | 167:e84263d55307 | 165 | |
AnnaBridge | 174:b96e65c34a4d | 166 | uint32_t flash_get_page_size(const flash_t *obj) |
AnnaBridge | 174:b96e65c34a4d | 167 | { |
AnnaBridge | 174:b96e65c34a4d | 168 | return 1024; |
AnnaBridge | 174:b96e65c34a4d | 169 | } |
AnnaBridge | 174:b96e65c34a4d | 170 | |
AnnaBridge | 174:b96e65c34a4d | 171 | uint32_t flash_get_start_address(const flash_t *obj) |
AnnaBridge | 167:e84263d55307 | 172 | { |
AnnaBridge | 174:b96e65c34a4d | 173 | return LPC_FLASH_BASE; |
AnnaBridge | 174:b96e65c34a4d | 174 | } |
AnnaBridge | 174:b96e65c34a4d | 175 | |
AnnaBridge | 174:b96e65c34a4d | 176 | uint32_t flash_get_size(const flash_t *obj) |
AnnaBridge | 174:b96e65c34a4d | 177 | { |
AnnaBridge | 174:b96e65c34a4d | 178 | return 0x80000; |
AnnaBridge | 167:e84263d55307 | 179 | } |
AnnaBridge | 167:e84263d55307 | 180 | |
AnnaBridge | 167:e84263d55307 | 181 | #endif |