mbed

Fork of mbed-dev by mbed official

Committer:
AnnaBridge
Date:
Wed Nov 08 13:50:44 2017 +0000
Revision:
178:d650f5d4c87a
Parent:
176:af195413fb11
This updates the lib to the mbed lib v 155

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 /* L0 targets embed 32 pages sectors */
AnnaBridge 167:e84263d55307 25 #define NUM_PAGES_IN_SECTOR 32
AnnaBridge 167:e84263d55307 26
AnnaBridge 167:e84263d55307 27 int32_t flash_init(flash_t *obj)
AnnaBridge 167:e84263d55307 28 {
AnnaBridge 167:e84263d55307 29 return 0;
AnnaBridge 167:e84263d55307 30 }
AnnaBridge 167:e84263d55307 31
AnnaBridge 167:e84263d55307 32 int32_t flash_free(flash_t *obj)
AnnaBridge 167:e84263d55307 33 {
AnnaBridge 167:e84263d55307 34 return 0;
AnnaBridge 167:e84263d55307 35 }
AnnaBridge 167:e84263d55307 36
AnnaBridge 176:af195413fb11 37 static int32_t flash_unlock(void)
AnnaBridge 176:af195413fb11 38 {
AnnaBridge 176:af195413fb11 39 /* Allow Access to Flash control registers and user Falsh */
AnnaBridge 176:af195413fb11 40 if (HAL_FLASH_Unlock()) {
AnnaBridge 176:af195413fb11 41 return -1;
AnnaBridge 176:af195413fb11 42 } else {
AnnaBridge 176:af195413fb11 43 return 0;
AnnaBridge 176:af195413fb11 44 }
AnnaBridge 176:af195413fb11 45 }
AnnaBridge 176:af195413fb11 46
AnnaBridge 176:af195413fb11 47 static int32_t flash_lock(void)
AnnaBridge 176:af195413fb11 48 {
AnnaBridge 176:af195413fb11 49 /* Disable the Flash option control register access (recommended to protect
AnnaBridge 176:af195413fb11 50 the option Bytes against possible unwanted operations) */
AnnaBridge 176:af195413fb11 51 if (HAL_FLASH_Lock()) {
AnnaBridge 176:af195413fb11 52 return -1;
AnnaBridge 176:af195413fb11 53 } else {
AnnaBridge 176:af195413fb11 54 return 0;
AnnaBridge 176:af195413fb11 55 }
AnnaBridge 176:af195413fb11 56 }
AnnaBridge 176:af195413fb11 57
AnnaBridge 167:e84263d55307 58 int32_t flash_erase_sector(flash_t *obj, uint32_t address)
AnnaBridge 167:e84263d55307 59 {
AnnaBridge 167:e84263d55307 60 uint32_t PAGEError = 0;
AnnaBridge 167:e84263d55307 61 FLASH_EraseInitTypeDef EraseInitStruct;
AnnaBridge 176:af195413fb11 62 int32_t status = 0;
AnnaBridge 167:e84263d55307 63
AnnaBridge 167:e84263d55307 64 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
AnnaBridge 167:e84263d55307 65
AnnaBridge 167:e84263d55307 66 return -1;
AnnaBridge 167:e84263d55307 67 }
AnnaBridge 167:e84263d55307 68
AnnaBridge 176:af195413fb11 69 if (flash_unlock() != HAL_OK) {
AnnaBridge 176:af195413fb11 70 return -1;
AnnaBridge 176:af195413fb11 71 }
AnnaBridge 176:af195413fb11 72
AnnaBridge 167:e84263d55307 73 /* Clear OPTVERR bit set on virgin samples */
AnnaBridge 167:e84263d55307 74 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
AnnaBridge 167:e84263d55307 75
AnnaBridge 167:e84263d55307 76 /* MBED HAL erases 1 sector at a time */
AnnaBridge 167:e84263d55307 77 /* Fill EraseInit structure*/
AnnaBridge 167:e84263d55307 78 EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
AnnaBridge 167:e84263d55307 79 EraseInitStruct.PageAddress = address;
AnnaBridge 167:e84263d55307 80 EraseInitStruct.NbPages = NUM_PAGES_IN_SECTOR;
AnnaBridge 167:e84263d55307 81
AnnaBridge 167:e84263d55307 82 /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
AnnaBridge 167:e84263d55307 83 you have to make sure that these data are rewritten before they are accessed during code
AnnaBridge 167:e84263d55307 84 execution. If this cannot be done safely, it is recommended to flush the caches by setting the
AnnaBridge 167:e84263d55307 85 DCRST and ICRST bits in the FLASH_CR register. */
AnnaBridge 167:e84263d55307 86
AnnaBridge 167:e84263d55307 87 if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
AnnaBridge 176:af195413fb11 88 status = -1;
AnnaBridge 167:e84263d55307 89 }
AnnaBridge 176:af195413fb11 90
AnnaBridge 176:af195413fb11 91 flash_lock();
AnnaBridge 176:af195413fb11 92
AnnaBridge 176:af195413fb11 93 return status;
AnnaBridge 176:af195413fb11 94
AnnaBridge 167:e84263d55307 95 }
AnnaBridge 167:e84263d55307 96
AnnaBridge 167:e84263d55307 97 int32_t flash_program_page(flash_t *obj, uint32_t address,
AnnaBridge 167:e84263d55307 98 const uint8_t *data, uint32_t size)
AnnaBridge 167:e84263d55307 99 {
AnnaBridge 167:e84263d55307 100 uint32_t StartAddress = 0;
AnnaBridge 176:af195413fb11 101 int32_t status = 0;
AnnaBridge 167:e84263d55307 102
AnnaBridge 167:e84263d55307 103 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
AnnaBridge 167:e84263d55307 104 return -1;
AnnaBridge 167:e84263d55307 105 }
AnnaBridge 167:e84263d55307 106
AnnaBridge 167:e84263d55307 107 if ((size % 4) != 0) {
AnnaBridge 167:e84263d55307 108 /* L4 flash devices can only be programmed 64bits/8 bytes at a time */
AnnaBridge 167:e84263d55307 109 return -1;
AnnaBridge 167:e84263d55307 110 }
AnnaBridge 167:e84263d55307 111
AnnaBridge 176:af195413fb11 112 if (flash_unlock() != HAL_OK) {
AnnaBridge 176:af195413fb11 113 return -1;
AnnaBridge 176:af195413fb11 114 }
AnnaBridge 176:af195413fb11 115
AnnaBridge 167:e84263d55307 116 /* Program the user Flash area word by word */
AnnaBridge 167:e84263d55307 117 StartAddress = address;
AnnaBridge 167:e84263d55307 118
AnnaBridge 167:e84263d55307 119 /* HW needs an aligned address to program flash, which data
AnnaBridge 167:e84263d55307 120 * parameters doesn't ensure */
AnnaBridge 167:e84263d55307 121 if ((uint32_t) data % 4 != 0) {
AnnaBridge 167:e84263d55307 122 volatile uint32_t data32;
AnnaBridge 176:af195413fb11 123 while ((address < (StartAddress + size)) && (status == 0)) {
AnnaBridge 167:e84263d55307 124 for (uint8_t i =0; i < 4; i++) {
AnnaBridge 167:e84263d55307 125 *(((uint8_t *) &data32) + i) = *(data + i);
AnnaBridge 167:e84263d55307 126 }
AnnaBridge 167:e84263d55307 127
AnnaBridge 167:e84263d55307 128 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data32) == HAL_OK) {
AnnaBridge 167:e84263d55307 129 address = address + 4;
AnnaBridge 167:e84263d55307 130 data = data + 4;
AnnaBridge 167:e84263d55307 131 } else {
AnnaBridge 176:af195413fb11 132 status = -1;
AnnaBridge 167:e84263d55307 133 }
AnnaBridge 167:e84263d55307 134 }
AnnaBridge 167:e84263d55307 135 } else { /* case where data is aligned, so let's avoid any copy */
AnnaBridge 176:af195413fb11 136 while ((address < (StartAddress + size)) && (status == 0)) {
AnnaBridge 167:e84263d55307 137 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) {
AnnaBridge 167:e84263d55307 138 address = address + 4;
AnnaBridge 167:e84263d55307 139 data = data + 4;
AnnaBridge 167:e84263d55307 140 } else {
AnnaBridge 176:af195413fb11 141 status = -1;
AnnaBridge 167:e84263d55307 142 }
AnnaBridge 167:e84263d55307 143 }
AnnaBridge 167:e84263d55307 144 }
AnnaBridge 167:e84263d55307 145
AnnaBridge 176:af195413fb11 146 flash_lock();
AnnaBridge 176:af195413fb11 147
AnnaBridge 176:af195413fb11 148 return status;
AnnaBridge 167:e84263d55307 149 }
AnnaBridge 167:e84263d55307 150
AnnaBridge 167:e84263d55307 151 uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) {
AnnaBridge 167:e84263d55307 152 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
AnnaBridge 167:e84263d55307 153 return MBED_FLASH_INVALID_SIZE;
AnnaBridge 167:e84263d55307 154 } else {
AnnaBridge 168:9672193075cf 155 /* sector composed of N pages */
AnnaBridge 167:e84263d55307 156 return (NUM_PAGES_IN_SECTOR * FLASH_PAGE_SIZE);
AnnaBridge 167:e84263d55307 157 }
AnnaBridge 167:e84263d55307 158 }
AnnaBridge 167:e84263d55307 159
AnnaBridge 167:e84263d55307 160 uint32_t flash_get_page_size(const flash_t *obj) {
AnnaBridge 175:b96e65c34a4d 161 /* Page size is the minimum programable size, which 4 bytes */
AnnaBridge 175:b96e65c34a4d 162 return 4;
AnnaBridge 167:e84263d55307 163 }
AnnaBridge 167:e84263d55307 164
AnnaBridge 167:e84263d55307 165 uint32_t flash_get_start_address(const flash_t *obj) {
AnnaBridge 167:e84263d55307 166 return FLASH_BASE;
AnnaBridge 167:e84263d55307 167 }
AnnaBridge 167:e84263d55307 168
AnnaBridge 167:e84263d55307 169 uint32_t flash_get_size(const flash_t *obj) {
AnnaBridge 167:e84263d55307 170 return FLASH_SIZE;
AnnaBridge 167:e84263d55307 171 }
AnnaBridge 167:e84263d55307 172
AnnaBridge 167:e84263d55307 173 #endif