mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew 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 167:e84263d55307 16
AnnaBridge 167:e84263d55307 17 #include "flash_api.h"
AnnaBridge 167:e84263d55307 18 #include "mbed_critical.h"
AnnaBridge 167:e84263d55307 19
AnnaBridge 167:e84263d55307 20 #if DEVICE_FLASH
AnnaBridge 167:e84263d55307 21 #include "mbed_assert.h"
AnnaBridge 167:e84263d55307 22 #include "cmsis.h"
AnnaBridge 167:e84263d55307 23
AnnaBridge 167:e84263d55307 24 /**
AnnaBridge 167:e84263d55307 25 * @brief Gets the page of a given address
AnnaBridge 167:e84263d55307 26 * @param Addr: Address of the FLASH Memory
AnnaBridge 167:e84263d55307 27 * @retval The page of a given address
AnnaBridge 167:e84263d55307 28 */
AnnaBridge 167:e84263d55307 29 static uint32_t GetPage(uint32_t Addr)
AnnaBridge 167:e84263d55307 30 {
AnnaBridge 167:e84263d55307 31 uint32_t page = 0;
AnnaBridge 167:e84263d55307 32
AnnaBridge 167:e84263d55307 33 if (Addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
AnnaBridge 167:e84263d55307 34 /* Bank 1 */
AnnaBridge 167:e84263d55307 35 page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
AnnaBridge 167:e84263d55307 36 } else {
AnnaBridge 167:e84263d55307 37 /* Bank 2 */
AnnaBridge 167:e84263d55307 38 page = (Addr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE;
AnnaBridge 167:e84263d55307 39 }
AnnaBridge 167:e84263d55307 40
AnnaBridge 167:e84263d55307 41 return page;
AnnaBridge 167:e84263d55307 42 }
AnnaBridge 167:e84263d55307 43
AnnaBridge 167:e84263d55307 44 /**
AnnaBridge 167:e84263d55307 45 * @brief Gets the bank of a given address
AnnaBridge 167:e84263d55307 46 * @param Addr: Address of the FLASH Memory
AnnaBridge 167:e84263d55307 47 * @retval The bank of a given address
AnnaBridge 167:e84263d55307 48 */
AnnaBridge 167:e84263d55307 49 static uint32_t GetBank(uint32_t Addr)
AnnaBridge 167:e84263d55307 50 {
AnnaBridge 167:e84263d55307 51 uint32_t bank = 0;
AnnaBridge 167:e84263d55307 52 #if defined(SYSCFG_MEMRMP_FB_MODE)
AnnaBridge 167:e84263d55307 53 if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0) {
AnnaBridge 167:e84263d55307 54 /* No Bank swap */
AnnaBridge 167:e84263d55307 55 if (Addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
AnnaBridge 167:e84263d55307 56 bank = FLASH_BANK_1;
AnnaBridge 167:e84263d55307 57 } else {
AnnaBridge 167:e84263d55307 58 bank = FLASH_BANK_2;
AnnaBridge 167:e84263d55307 59 }
AnnaBridge 167:e84263d55307 60 } else {
AnnaBridge 167:e84263d55307 61 /* Bank swap */
AnnaBridge 167:e84263d55307 62 if (Addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
AnnaBridge 167:e84263d55307 63 bank = FLASH_BANK_2;
AnnaBridge 167:e84263d55307 64 } else {
AnnaBridge 167:e84263d55307 65 bank = FLASH_BANK_1;
AnnaBridge 167:e84263d55307 66 }
AnnaBridge 167:e84263d55307 67 }
AnnaBridge 167:e84263d55307 68 #else
AnnaBridge 167:e84263d55307 69 /* Device like L432KC */
AnnaBridge 167:e84263d55307 70 bank = FLASH_BANK_1;
AnnaBridge 167:e84263d55307 71 #endif
AnnaBridge 167:e84263d55307 72
AnnaBridge 167:e84263d55307 73 return bank;
AnnaBridge 167:e84263d55307 74 }
AnnaBridge 167:e84263d55307 75
AnnaBridge 167:e84263d55307 76 /** Initialize the flash peripheral and the flash_t object
AnnaBridge 167:e84263d55307 77 *
AnnaBridge 167:e84263d55307 78 * @param obj The flash object
AnnaBridge 167:e84263d55307 79 * @return 0 for success, -1 for error
AnnaBridge 167:e84263d55307 80 */
AnnaBridge 167:e84263d55307 81 int32_t flash_init(flash_t *obj)
AnnaBridge 167:e84263d55307 82 {
AnnaBridge 167:e84263d55307 83 return 0;
AnnaBridge 167:e84263d55307 84 }
AnnaBridge 167:e84263d55307 85
AnnaBridge 167:e84263d55307 86 /** Uninitialize the flash peripheral and the flash_t object
AnnaBridge 167:e84263d55307 87 *
AnnaBridge 167:e84263d55307 88 * @param obj The flash object
AnnaBridge 167:e84263d55307 89 * @return 0 for success, -1 for error
AnnaBridge 167:e84263d55307 90 */
AnnaBridge 167:e84263d55307 91 int32_t flash_free(flash_t *obj)
AnnaBridge 167:e84263d55307 92 {
AnnaBridge 167:e84263d55307 93 return 0;
AnnaBridge 167:e84263d55307 94 }
AnnaBridge 167:e84263d55307 95
AnnaBridge 175:af195413fb11 96 static int32_t flash_unlock(void)
AnnaBridge 175:af195413fb11 97 {
AnnaBridge 175:af195413fb11 98 /* Allow Access to Flash control registers and user Falsh */
AnnaBridge 175:af195413fb11 99 if (HAL_FLASH_Unlock()) {
AnnaBridge 175:af195413fb11 100 return -1;
AnnaBridge 175:af195413fb11 101 } else {
AnnaBridge 175:af195413fb11 102 return 0;
AnnaBridge 175:af195413fb11 103 }
AnnaBridge 175:af195413fb11 104 }
AnnaBridge 175:af195413fb11 105
AnnaBridge 175:af195413fb11 106 static int32_t flash_lock(void)
AnnaBridge 175:af195413fb11 107 {
AnnaBridge 175:af195413fb11 108 /* Disable the Flash option control register access (recommended to protect
AnnaBridge 175:af195413fb11 109 the option Bytes against possible unwanted operations) */
AnnaBridge 175:af195413fb11 110 if (HAL_FLASH_Lock()) {
AnnaBridge 175:af195413fb11 111 return -1;
AnnaBridge 175:af195413fb11 112 } else {
AnnaBridge 175:af195413fb11 113 return 0;
AnnaBridge 175:af195413fb11 114 }
AnnaBridge 175:af195413fb11 115 }
AnnaBridge 175:af195413fb11 116
AnnaBridge 167:e84263d55307 117 /** Erase one sector starting at defined address
AnnaBridge 167:e84263d55307 118 *
AnnaBridge 167:e84263d55307 119 * The address should be at sector boundary. This function does not do any check for address alignments
AnnaBridge 167:e84263d55307 120 * @param obj The flash object
AnnaBridge 167:e84263d55307 121 * @param address The sector starting address
AnnaBridge 167:e84263d55307 122 * @return 0 for success, -1 for error
AnnaBridge 167:e84263d55307 123 */
AnnaBridge 167:e84263d55307 124 int32_t flash_erase_sector(flash_t *obj, uint32_t address)
AnnaBridge 167:e84263d55307 125 {
AnnaBridge 167:e84263d55307 126 uint32_t FirstPage = 0, BankNumber = 0;
AnnaBridge 167:e84263d55307 127 uint32_t PAGEError = 0;
AnnaBridge 167:e84263d55307 128 FLASH_EraseInitTypeDef EraseInitStruct;
AnnaBridge 175:af195413fb11 129 int32_t status = 0;
AnnaBridge 167:e84263d55307 130
AnnaBridge 167:e84263d55307 131 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
AnnaBridge 167:e84263d55307 132
AnnaBridge 167:e84263d55307 133 return -1;
AnnaBridge 167:e84263d55307 134 }
AnnaBridge 167:e84263d55307 135
AnnaBridge 175:af195413fb11 136 if (flash_unlock() != HAL_OK) {
AnnaBridge 175:af195413fb11 137 return -1;
AnnaBridge 175:af195413fb11 138 }
AnnaBridge 175:af195413fb11 139
AnnaBridge 188:bcfe06ba3d64 140 /* Clear error programming flags */
AnnaBridge 188:bcfe06ba3d64 141 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
AnnaBridge 188:bcfe06ba3d64 142
AnnaBridge 167:e84263d55307 143 /* Get the 1st page to erase */
AnnaBridge 167:e84263d55307 144 FirstPage = GetPage(address);
AnnaBridge 167:e84263d55307 145 /* MBED HAL erases 1 page / sector at a time */
AnnaBridge 167:e84263d55307 146 /* Get the bank */
AnnaBridge 167:e84263d55307 147 BankNumber = GetBank(address);
AnnaBridge 167:e84263d55307 148 /* Fill EraseInit structure*/
AnnaBridge 167:e84263d55307 149 EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
AnnaBridge 167:e84263d55307 150 EraseInitStruct.Banks = BankNumber;
AnnaBridge 167:e84263d55307 151 EraseInitStruct.Page = FirstPage;
AnnaBridge 167:e84263d55307 152 EraseInitStruct.NbPages = 1;
AnnaBridge 167:e84263d55307 153
AnnaBridge 167:e84263d55307 154 /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
AnnaBridge 167:e84263d55307 155 you have to make sure that these data are rewritten before they are accessed during code
AnnaBridge 167:e84263d55307 156 execution. If this cannot be done safely, it is recommended to flush the caches by setting the
AnnaBridge 167:e84263d55307 157 DCRST and ICRST bits in the FLASH_CR register. */
AnnaBridge 167:e84263d55307 158
AnnaBridge 167:e84263d55307 159 if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
AnnaBridge 175:af195413fb11 160 status = -1;
AnnaBridge 167:e84263d55307 161 }
AnnaBridge 175:af195413fb11 162
AnnaBridge 175:af195413fb11 163 flash_lock();
AnnaBridge 175:af195413fb11 164
AnnaBridge 175:af195413fb11 165 return status;
AnnaBridge 167:e84263d55307 166 }
AnnaBridge 167:e84263d55307 167
AnnaBridge 167:e84263d55307 168 /** Program one page starting at defined address
AnnaBridge 167:e84263d55307 169 *
AnnaBridge 167:e84263d55307 170 * The page should be at page boundary, should not cross multiple sectors.
AnnaBridge 167:e84263d55307 171 * This function does not do any check for address alignments or if size
AnnaBridge 167:e84263d55307 172 * is aligned to a page size.
AnnaBridge 167:e84263d55307 173 * @param obj The flash object
AnnaBridge 167:e84263d55307 174 * @param address The sector starting address
AnnaBridge 167:e84263d55307 175 * @param data The data buffer to be programmed
AnnaBridge 167:e84263d55307 176 * @param size The number of bytes to program
AnnaBridge 167:e84263d55307 177 * @return 0 for success, -1 for error
AnnaBridge 167:e84263d55307 178 */
AnnaBridge 167:e84263d55307 179 int32_t flash_program_page(flash_t *obj, uint32_t address,
AnnaBridge 187:0387e8f68319 180 const uint8_t *data, uint32_t size)
AnnaBridge 167:e84263d55307 181 {
AnnaBridge 167:e84263d55307 182 uint32_t StartAddress = 0;
AnnaBridge 175:af195413fb11 183 int32_t status = 0;
AnnaBridge 167:e84263d55307 184
AnnaBridge 167:e84263d55307 185 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
AnnaBridge 167:e84263d55307 186 return -1;
AnnaBridge 167:e84263d55307 187 }
AnnaBridge 167:e84263d55307 188
AnnaBridge 167:e84263d55307 189 if ((size % 8) != 0) {
AnnaBridge 167:e84263d55307 190 /* L4 flash devices can only be programmed 64bits/8 bytes at a time */
AnnaBridge 167:e84263d55307 191 return -1;
AnnaBridge 167:e84263d55307 192 }
AnnaBridge 167:e84263d55307 193
AnnaBridge 175:af195413fb11 194 if (flash_unlock() != HAL_OK) {
AnnaBridge 175:af195413fb11 195 return -1;
AnnaBridge 175:af195413fb11 196 }
AnnaBridge 175:af195413fb11 197
AnnaBridge 188:bcfe06ba3d64 198 /* Clear error programming flags */
AnnaBridge 188:bcfe06ba3d64 199 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
AnnaBridge 188:bcfe06ba3d64 200
AnnaBridge 167:e84263d55307 201 /* Program the user Flash area word by word */
AnnaBridge 167:e84263d55307 202 StartAddress = address;
AnnaBridge 167:e84263d55307 203
AnnaBridge 167:e84263d55307 204 /* HW needs an aligned address to program flash, which data
AnnaBridge 167:e84263d55307 205 * parameters doesn't ensure */
AnnaBridge 167:e84263d55307 206 if ((uint32_t) data % 4 != 0) {
AnnaBridge 167:e84263d55307 207 volatile uint64_t data64;
AnnaBridge 175:af195413fb11 208 while ((address < (StartAddress + size)) && (status == 0)) {
AnnaBridge 187:0387e8f68319 209 for (uint8_t i = 0; i < 8; i++) {
AnnaBridge 167:e84263d55307 210 *(((uint8_t *) &data64) + i) = *(data + i);
AnnaBridge 167:e84263d55307 211 }
AnnaBridge 167:e84263d55307 212
AnnaBridge 175:af195413fb11 213 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data64)
AnnaBridge 175:af195413fb11 214 == HAL_OK) {
AnnaBridge 167:e84263d55307 215 address = address + 8;
AnnaBridge 167:e84263d55307 216 data = data + 8;
AnnaBridge 167:e84263d55307 217 } else {
AnnaBridge 175:af195413fb11 218 status = -1;
AnnaBridge 167:e84263d55307 219 }
AnnaBridge 167:e84263d55307 220 }
AnnaBridge 167:e84263d55307 221 } else { /* case where data is aligned, so let's avoid any copy */
AnnaBridge 175:af195413fb11 222 while ((address < (StartAddress + size)) && (status == 0)) {
AnnaBridge 175:af195413fb11 223 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address,
AnnaBridge 187:0387e8f68319 224 *((uint64_t *) data))
AnnaBridge 175:af195413fb11 225 == HAL_OK) {
AnnaBridge 167:e84263d55307 226 address = address + 8;
AnnaBridge 167:e84263d55307 227 data = data + 8;
AnnaBridge 167:e84263d55307 228 } else {
AnnaBridge 175:af195413fb11 229 status = -1;
AnnaBridge 167:e84263d55307 230 }
AnnaBridge 167:e84263d55307 231 }
AnnaBridge 167:e84263d55307 232 }
AnnaBridge 167:e84263d55307 233
AnnaBridge 175:af195413fb11 234 flash_lock();
AnnaBridge 175:af195413fb11 235
AnnaBridge 175:af195413fb11 236 return status;
AnnaBridge 167:e84263d55307 237 }
AnnaBridge 167:e84263d55307 238
AnnaBridge 167:e84263d55307 239 /** Get sector size
AnnaBridge 175:af195413fb11 240 *
AnnaBridge 167:e84263d55307 241 * @param obj The flash object
AnnaBridge 167:e84263d55307 242 * @param address The sector starting address
AnnaBridge 167:e84263d55307 243 * @return The size of a sector
AnnaBridge 167:e84263d55307 244 */
AnnaBridge 187:0387e8f68319 245 uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
AnnaBridge 187:0387e8f68319 246 {
AnnaBridge 167:e84263d55307 247 /* considering 1 sector = 1 page */
AnnaBridge 167:e84263d55307 248 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
AnnaBridge 167:e84263d55307 249 return MBED_FLASH_INVALID_SIZE;
AnnaBridge 167:e84263d55307 250 } else {
AnnaBridge 167:e84263d55307 251 return FLASH_PAGE_SIZE;
AnnaBridge 167:e84263d55307 252 }
AnnaBridge 167:e84263d55307 253 }
AnnaBridge 167:e84263d55307 254
AnnaBridge 167:e84263d55307 255 /** Get page size
AnnaBridge 167:e84263d55307 256 *
AnnaBridge 167:e84263d55307 257 * @param obj The flash object
AnnaBridge 167:e84263d55307 258 * @param address The page starting address
AnnaBridge 167:e84263d55307 259 * @return The size of a page
AnnaBridge 167:e84263d55307 260 */
AnnaBridge 187:0387e8f68319 261 uint32_t flash_get_page_size(const flash_t *obj)
AnnaBridge 187:0387e8f68319 262 {
AnnaBridge 174:b96e65c34a4d 263 /* Page size is the minimum programable size, which 8 bytes */
AnnaBridge 174:b96e65c34a4d 264 return 8;
AnnaBridge 167:e84263d55307 265 }
AnnaBridge 167:e84263d55307 266
AnnaBridge 167:e84263d55307 267 /** Get start address for the flash region
AnnaBridge 167:e84263d55307 268 *
AnnaBridge 167:e84263d55307 269 * @param obj The flash object
AnnaBridge 167:e84263d55307 270 * @return The start address for the flash region
AnnaBridge 167:e84263d55307 271 */
AnnaBridge 187:0387e8f68319 272 uint32_t flash_get_start_address(const flash_t *obj)
AnnaBridge 187:0387e8f68319 273 {
AnnaBridge 167:e84263d55307 274 return FLASH_BASE;
AnnaBridge 167:e84263d55307 275 }
AnnaBridge 167:e84263d55307 276
AnnaBridge 167:e84263d55307 277 /** Get the flash region size
AnnaBridge 167:e84263d55307 278 *
AnnaBridge 167:e84263d55307 279 * @param obj The flash object
AnnaBridge 167:e84263d55307 280 * @return The flash region size
AnnaBridge 167:e84263d55307 281 */
AnnaBridge 187:0387e8f68319 282 uint32_t flash_get_size(const flash_t *obj)
AnnaBridge 187:0387e8f68319 283 {
AnnaBridge 167:e84263d55307 284 return FLASH_SIZE;
AnnaBridge 167:e84263d55307 285 }
AnnaBridge 167:e84263d55307 286
AnnaBridge 189:f392fc9709a3 287 uint8_t flash_get_erase_value(const flash_t *obj)
AnnaBridge 189:f392fc9709a3 288 {
AnnaBridge 189:f392fc9709a3 289 (void)obj;
AnnaBridge 189:f392fc9709a3 290
AnnaBridge 189:f392fc9709a3 291 return 0xFF;
AnnaBridge 189:f392fc9709a3 292 }
AnnaBridge 189:f392fc9709a3 293
AnnaBridge 167:e84263d55307 294 #endif