test

Committer:
elijahsj
Date:
Mon Nov 09 00:02:47 2020 -0500
Revision:
1:8a094db1347f
test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elijahsj 1:8a094db1347f 1 /* mbed Microcontroller Library
elijahsj 1:8a094db1347f 2 * Copyright (c) 2017 ARM Limited
elijahsj 1:8a094db1347f 3 *
elijahsj 1:8a094db1347f 4 * Licensed under the Apache License, Version 2.0 (the "License");
elijahsj 1:8a094db1347f 5 * you may not use this file except in compliance with the License.
elijahsj 1:8a094db1347f 6 * You may obtain a copy of the License at
elijahsj 1:8a094db1347f 7 *
elijahsj 1:8a094db1347f 8 * http://www.apache.org/licenses/LICENSE-2.0
elijahsj 1:8a094db1347f 9 *
elijahsj 1:8a094db1347f 10 * Unless required by applicable law or agreed to in writing, software
elijahsj 1:8a094db1347f 11 * distributed under the License is distributed on an "AS IS" BASIS,
elijahsj 1:8a094db1347f 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
elijahsj 1:8a094db1347f 13 * See the License for the specific language governing permissions and
elijahsj 1:8a094db1347f 14 * limitations under the License.
elijahsj 1:8a094db1347f 15 */
elijahsj 1:8a094db1347f 16
elijahsj 1:8a094db1347f 17 #include "flash_api.h"
elijahsj 1:8a094db1347f 18 #include "mbed_critical.h"
elijahsj 1:8a094db1347f 19
elijahsj 1:8a094db1347f 20 #if DEVICE_FLASH
elijahsj 1:8a094db1347f 21 #include "mbed_assert.h"
elijahsj 1:8a094db1347f 22 #include "cmsis.h"
elijahsj 1:8a094db1347f 23
elijahsj 1:8a094db1347f 24 /* L0 targets embed 32 pages sectors */
elijahsj 1:8a094db1347f 25 #define NUM_PAGES_IN_SECTOR 32
elijahsj 1:8a094db1347f 26
elijahsj 1:8a094db1347f 27 int32_t flash_init(flash_t *obj)
elijahsj 1:8a094db1347f 28 {
elijahsj 1:8a094db1347f 29 return 0;
elijahsj 1:8a094db1347f 30 }
elijahsj 1:8a094db1347f 31
elijahsj 1:8a094db1347f 32 int32_t flash_free(flash_t *obj)
elijahsj 1:8a094db1347f 33 {
elijahsj 1:8a094db1347f 34 return 0;
elijahsj 1:8a094db1347f 35 }
elijahsj 1:8a094db1347f 36
elijahsj 1:8a094db1347f 37 static int32_t flash_unlock(void)
elijahsj 1:8a094db1347f 38 {
elijahsj 1:8a094db1347f 39 /* Allow Access to Flash control registers and user Falsh */
elijahsj 1:8a094db1347f 40 if (HAL_FLASH_Unlock()) {
elijahsj 1:8a094db1347f 41 return -1;
elijahsj 1:8a094db1347f 42 } else {
elijahsj 1:8a094db1347f 43 return 0;
elijahsj 1:8a094db1347f 44 }
elijahsj 1:8a094db1347f 45 }
elijahsj 1:8a094db1347f 46
elijahsj 1:8a094db1347f 47 static int32_t flash_lock(void)
elijahsj 1:8a094db1347f 48 {
elijahsj 1:8a094db1347f 49 /* Disable the Flash option control register access (recommended to protect
elijahsj 1:8a094db1347f 50 the option Bytes against possible unwanted operations) */
elijahsj 1:8a094db1347f 51 if (HAL_FLASH_Lock()) {
elijahsj 1:8a094db1347f 52 return -1;
elijahsj 1:8a094db1347f 53 } else {
elijahsj 1:8a094db1347f 54 return 0;
elijahsj 1:8a094db1347f 55 }
elijahsj 1:8a094db1347f 56 }
elijahsj 1:8a094db1347f 57
elijahsj 1:8a094db1347f 58 int32_t flash_erase_sector(flash_t *obj, uint32_t address)
elijahsj 1:8a094db1347f 59 {
elijahsj 1:8a094db1347f 60 uint32_t FirstPage = 0;
elijahsj 1:8a094db1347f 61 uint32_t PAGEError = 0;
elijahsj 1:8a094db1347f 62 FLASH_EraseInitTypeDef EraseInitStruct;
elijahsj 1:8a094db1347f 63 int32_t status = 0;
elijahsj 1:8a094db1347f 64
elijahsj 1:8a094db1347f 65 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
elijahsj 1:8a094db1347f 66
elijahsj 1:8a094db1347f 67 return -1;
elijahsj 1:8a094db1347f 68 }
elijahsj 1:8a094db1347f 69
elijahsj 1:8a094db1347f 70 if (flash_unlock() != HAL_OK) {
elijahsj 1:8a094db1347f 71 return -1;
elijahsj 1:8a094db1347f 72 }
elijahsj 1:8a094db1347f 73
elijahsj 1:8a094db1347f 74 /* Clear OPTVERR bit set on virgin samples */
elijahsj 1:8a094db1347f 75 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
elijahsj 1:8a094db1347f 76
elijahsj 1:8a094db1347f 77 /* MBED HAL erases 1 sector at a time */
elijahsj 1:8a094db1347f 78 /* Fill EraseInit structure*/
elijahsj 1:8a094db1347f 79 EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
elijahsj 1:8a094db1347f 80 EraseInitStruct.PageAddress = address;
elijahsj 1:8a094db1347f 81 EraseInitStruct.NbPages = NUM_PAGES_IN_SECTOR;
elijahsj 1:8a094db1347f 82
elijahsj 1:8a094db1347f 83 /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
elijahsj 1:8a094db1347f 84 you have to make sure that these data are rewritten before they are accessed during code
elijahsj 1:8a094db1347f 85 execution. If this cannot be done safely, it is recommended to flush the caches by setting the
elijahsj 1:8a094db1347f 86 DCRST and ICRST bits in the FLASH_CR register. */
elijahsj 1:8a094db1347f 87
elijahsj 1:8a094db1347f 88 if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
elijahsj 1:8a094db1347f 89 status = -1;
elijahsj 1:8a094db1347f 90 }
elijahsj 1:8a094db1347f 91
elijahsj 1:8a094db1347f 92 flash_lock();
elijahsj 1:8a094db1347f 93
elijahsj 1:8a094db1347f 94 return status;
elijahsj 1:8a094db1347f 95
elijahsj 1:8a094db1347f 96 }
elijahsj 1:8a094db1347f 97
elijahsj 1:8a094db1347f 98 int32_t flash_program_page(flash_t *obj, uint32_t address,
elijahsj 1:8a094db1347f 99 const uint8_t *data, uint32_t size)
elijahsj 1:8a094db1347f 100 {
elijahsj 1:8a094db1347f 101 uint32_t StartAddress = 0;
elijahsj 1:8a094db1347f 102 int32_t status = 0;
elijahsj 1:8a094db1347f 103
elijahsj 1:8a094db1347f 104 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
elijahsj 1:8a094db1347f 105 return -1;
elijahsj 1:8a094db1347f 106 }
elijahsj 1:8a094db1347f 107
elijahsj 1:8a094db1347f 108 if ((size % 4) != 0) {
elijahsj 1:8a094db1347f 109 /* L4 flash devices can only be programmed 64bits/8 bytes at a time */
elijahsj 1:8a094db1347f 110 return -1;
elijahsj 1:8a094db1347f 111 }
elijahsj 1:8a094db1347f 112
elijahsj 1:8a094db1347f 113 if (flash_unlock() != HAL_OK) {
elijahsj 1:8a094db1347f 114 return -1;
elijahsj 1:8a094db1347f 115 }
elijahsj 1:8a094db1347f 116
elijahsj 1:8a094db1347f 117 /* Program the user Flash area word by word */
elijahsj 1:8a094db1347f 118 StartAddress = address;
elijahsj 1:8a094db1347f 119
elijahsj 1:8a094db1347f 120 /* HW needs an aligned address to program flash, which data
elijahsj 1:8a094db1347f 121 * parameters doesn't ensure */
elijahsj 1:8a094db1347f 122 if ((uint32_t) data % 4 != 0) {
elijahsj 1:8a094db1347f 123 volatile uint32_t data32;
elijahsj 1:8a094db1347f 124 while ((address < (StartAddress + size)) && (status == 0)) {
elijahsj 1:8a094db1347f 125 for (uint8_t i =0; i < 4; i++) {
elijahsj 1:8a094db1347f 126 *(((uint8_t *) &data32) + i) = *(data + i);
elijahsj 1:8a094db1347f 127 }
elijahsj 1:8a094db1347f 128
elijahsj 1:8a094db1347f 129 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data32) == HAL_OK) {
elijahsj 1:8a094db1347f 130 address = address + 4;
elijahsj 1:8a094db1347f 131 data = data + 4;
elijahsj 1:8a094db1347f 132 } else {
elijahsj 1:8a094db1347f 133 status = -1;
elijahsj 1:8a094db1347f 134 }
elijahsj 1:8a094db1347f 135 }
elijahsj 1:8a094db1347f 136 } else { /* case where data is aligned, so let's avoid any copy */
elijahsj 1:8a094db1347f 137 while ((address < (StartAddress + size)) && (status == 0)) {
elijahsj 1:8a094db1347f 138 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) {
elijahsj 1:8a094db1347f 139 address = address + 4;
elijahsj 1:8a094db1347f 140 data = data + 4;
elijahsj 1:8a094db1347f 141 } else {
elijahsj 1:8a094db1347f 142 status = -1;
elijahsj 1:8a094db1347f 143 }
elijahsj 1:8a094db1347f 144 }
elijahsj 1:8a094db1347f 145 }
elijahsj 1:8a094db1347f 146
elijahsj 1:8a094db1347f 147 flash_lock();
elijahsj 1:8a094db1347f 148
elijahsj 1:8a094db1347f 149 return status;
elijahsj 1:8a094db1347f 150 }
elijahsj 1:8a094db1347f 151
elijahsj 1:8a094db1347f 152 uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) {
elijahsj 1:8a094db1347f 153 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
elijahsj 1:8a094db1347f 154 return MBED_FLASH_INVALID_SIZE;
elijahsj 1:8a094db1347f 155 } else {
elijahsj 1:8a094db1347f 156 /* sector composed of N pages */
elijahsj 1:8a094db1347f 157 return (NUM_PAGES_IN_SECTOR * FLASH_PAGE_SIZE);
elijahsj 1:8a094db1347f 158 }
elijahsj 1:8a094db1347f 159 }
elijahsj 1:8a094db1347f 160
elijahsj 1:8a094db1347f 161 uint32_t flash_get_page_size(const flash_t *obj) {
elijahsj 1:8a094db1347f 162 /* Page size is the minimum programable size, which 4 bytes */
elijahsj 1:8a094db1347f 163 return 4;
elijahsj 1:8a094db1347f 164 }
elijahsj 1:8a094db1347f 165
elijahsj 1:8a094db1347f 166 uint32_t flash_get_start_address(const flash_t *obj) {
elijahsj 1:8a094db1347f 167 return FLASH_BASE;
elijahsj 1:8a094db1347f 168 }
elijahsj 1:8a094db1347f 169
elijahsj 1:8a094db1347f 170 uint32_t flash_get_size(const flash_t *obj) {
elijahsj 1:8a094db1347f 171 return FLASH_SIZE;
elijahsj 1:8a094db1347f 172 }
elijahsj 1:8a094db1347f 173
elijahsj 1:8a094db1347f 174 #endif