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 *******************************************************************************
elijahsj 1:8a094db1347f 3 * Copyright (c) 2017, STMicroelectronics
elijahsj 1:8a094db1347f 4 * All rights reserved.
elijahsj 1:8a094db1347f 5 *
elijahsj 1:8a094db1347f 6 * Redistribution and use in source and binary forms, with or without
elijahsj 1:8a094db1347f 7 * modification, are permitted provided that the following conditions are met:
elijahsj 1:8a094db1347f 8 *
elijahsj 1:8a094db1347f 9 * 1. Redistributions of source code must retain the above copyright notice,
elijahsj 1:8a094db1347f 10 * this list of conditions and the following disclaimer.
elijahsj 1:8a094db1347f 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
elijahsj 1:8a094db1347f 12 * this list of conditions and the following disclaimer in the documentation
elijahsj 1:8a094db1347f 13 * and/or other materials provided with the distribution.
elijahsj 1:8a094db1347f 14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
elijahsj 1:8a094db1347f 15 * may be used to endorse or promote products derived from this software
elijahsj 1:8a094db1347f 16 * without specific prior written permission.
elijahsj 1:8a094db1347f 17 *
elijahsj 1:8a094db1347f 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
elijahsj 1:8a094db1347f 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
elijahsj 1:8a094db1347f 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
elijahsj 1:8a094db1347f 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
elijahsj 1:8a094db1347f 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
elijahsj 1:8a094db1347f 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
elijahsj 1:8a094db1347f 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
elijahsj 1:8a094db1347f 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
elijahsj 1:8a094db1347f 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
elijahsj 1:8a094db1347f 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
elijahsj 1:8a094db1347f 28 *******************************************************************************
elijahsj 1:8a094db1347f 29 */
elijahsj 1:8a094db1347f 30
elijahsj 1:8a094db1347f 31 #if DEVICE_FLASH
elijahsj 1:8a094db1347f 32 #include "flash_api.h"
elijahsj 1:8a094db1347f 33 #include "flash_data.h"
elijahsj 1:8a094db1347f 34 #include "platform/mbed_critical.h"
elijahsj 1:8a094db1347f 35
elijahsj 1:8a094db1347f 36 static uint32_t GetSector(uint32_t Address);
elijahsj 1:8a094db1347f 37 static uint32_t GetSectorSize(uint32_t Sector);
elijahsj 1:8a094db1347f 38
elijahsj 1:8a094db1347f 39 int32_t flash_init(flash_t *obj)
elijahsj 1:8a094db1347f 40 {
elijahsj 1:8a094db1347f 41 return 0;
elijahsj 1:8a094db1347f 42 }
elijahsj 1:8a094db1347f 43 int32_t flash_free(flash_t *obj)
elijahsj 1:8a094db1347f 44 {
elijahsj 1:8a094db1347f 45 return 0;
elijahsj 1:8a094db1347f 46 }
elijahsj 1:8a094db1347f 47
elijahsj 1:8a094db1347f 48 static int32_t flash_unlock(void)
elijahsj 1:8a094db1347f 49 {
elijahsj 1:8a094db1347f 50 /* Allow Access to Flash control registers and user Falsh */
elijahsj 1:8a094db1347f 51 if (HAL_FLASH_Unlock()) {
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 static int32_t flash_lock(void)
elijahsj 1:8a094db1347f 59 {
elijahsj 1:8a094db1347f 60 /* Disable the Flash option control register access (recommended to protect
elijahsj 1:8a094db1347f 61 the option Bytes against possible unwanted operations) */
elijahsj 1:8a094db1347f 62 if (HAL_FLASH_Lock()) {
elijahsj 1:8a094db1347f 63 return -1;
elijahsj 1:8a094db1347f 64 } else {
elijahsj 1:8a094db1347f 65 return 0;
elijahsj 1:8a094db1347f 66 }
elijahsj 1:8a094db1347f 67 }
elijahsj 1:8a094db1347f 68
elijahsj 1:8a094db1347f 69 int32_t flash_erase_sector(flash_t *obj, uint32_t address)
elijahsj 1:8a094db1347f 70 {
elijahsj 1:8a094db1347f 71 /* Variable used for Erase procedure */
elijahsj 1:8a094db1347f 72 FLASH_EraseInitTypeDef EraseInitStruct;
elijahsj 1:8a094db1347f 73 FLASH_OBProgramInitTypeDef OBInit;
elijahsj 1:8a094db1347f 74 uint32_t SectorId;
elijahsj 1:8a094db1347f 75 uint32_t SectorError = 0;
elijahsj 1:8a094db1347f 76 int32_t status = 0;
elijahsj 1:8a094db1347f 77
elijahsj 1:8a094db1347f 78 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
elijahsj 1:8a094db1347f 79 return -1;
elijahsj 1:8a094db1347f 80 }
elijahsj 1:8a094db1347f 81
elijahsj 1:8a094db1347f 82 if (flash_unlock() != HAL_OK) {
elijahsj 1:8a094db1347f 83 return -1;
elijahsj 1:8a094db1347f 84 }
elijahsj 1:8a094db1347f 85
elijahsj 1:8a094db1347f 86 /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
elijahsj 1:8a094db1347f 87 you have to make sure that these data are rewritten before they are accessed during code
elijahsj 1:8a094db1347f 88 execution. If this cannot be done safely, it is recommended to flush the caches by setting the
elijahsj 1:8a094db1347f 89 DCRST and ICRST bits in the FLASH_CR register. */
elijahsj 1:8a094db1347f 90 __HAL_FLASH_ART_DISABLE();
elijahsj 1:8a094db1347f 91 __HAL_FLASH_ART_RESET();
elijahsj 1:8a094db1347f 92 __HAL_FLASH_ART_ENABLE();
elijahsj 1:8a094db1347f 93
elijahsj 1:8a094db1347f 94 /* Get the 1st sector to erase */
elijahsj 1:8a094db1347f 95 SectorId = GetSector(address);
elijahsj 1:8a094db1347f 96
elijahsj 1:8a094db1347f 97 /* Allow Access to option bytes sector */
elijahsj 1:8a094db1347f 98 HAL_FLASH_OB_Unlock();
elijahsj 1:8a094db1347f 99 /* Get the Dual bank configuration status */
elijahsj 1:8a094db1347f 100 HAL_FLASHEx_OBGetConfig(&OBInit);
elijahsj 1:8a094db1347f 101 /* Allow Access to option bytes sector */
elijahsj 1:8a094db1347f 102 HAL_FLASH_OB_Lock();
elijahsj 1:8a094db1347f 103
elijahsj 1:8a094db1347f 104 #if defined (FLASH_OPTCR_nDBANK)
elijahsj 1:8a094db1347f 105 /* On targets that support dynamic single or dual bank configuration
elijahsj 1:8a094db1347f 106 * Check that we're in SINGLE Bank mode, only supported mode now.
elijahsj 1:8a094db1347f 107 */
elijahsj 1:8a094db1347f 108 if((OBInit.USERConfig & OB_NDBANK_SINGLE_BANK) != OB_NDBANK_SINGLE_BANK) {
elijahsj 1:8a094db1347f 109 /* We don't support the DUAL BANK MODE for now, so return error */
elijahsj 1:8a094db1347f 110 return -1;
elijahsj 1:8a094db1347f 111 }
elijahsj 1:8a094db1347f 112 #endif
elijahsj 1:8a094db1347f 113
elijahsj 1:8a094db1347f 114 /* Fill EraseInit structure*/
elijahsj 1:8a094db1347f 115 EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
elijahsj 1:8a094db1347f 116 EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
elijahsj 1:8a094db1347f 117 EraseInitStruct.Sector = SectorId;
elijahsj 1:8a094db1347f 118 EraseInitStruct.NbSectors = 1;
elijahsj 1:8a094db1347f 119
elijahsj 1:8a094db1347f 120 if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
elijahsj 1:8a094db1347f 121 status = -1;
elijahsj 1:8a094db1347f 122 }
elijahsj 1:8a094db1347f 123
elijahsj 1:8a094db1347f 124 flash_lock();
elijahsj 1:8a094db1347f 125
elijahsj 1:8a094db1347f 126 return status;
elijahsj 1:8a094db1347f 127 }
elijahsj 1:8a094db1347f 128
elijahsj 1:8a094db1347f 129 int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
elijahsj 1:8a094db1347f 130 uint32_t size)
elijahsj 1:8a094db1347f 131 {
elijahsj 1:8a094db1347f 132 int32_t status = 0;
elijahsj 1:8a094db1347f 133
elijahsj 1:8a094db1347f 134 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
elijahsj 1:8a094db1347f 135 return -1;
elijahsj 1:8a094db1347f 136 }
elijahsj 1:8a094db1347f 137
elijahsj 1:8a094db1347f 138 if (flash_unlock() != HAL_OK) {
elijahsj 1:8a094db1347f 139 return -1;
elijahsj 1:8a094db1347f 140 }
elijahsj 1:8a094db1347f 141
elijahsj 1:8a094db1347f 142 /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
elijahsj 1:8a094db1347f 143 you have to make sure that these data are rewritten before they are accessed during code
elijahsj 1:8a094db1347f 144 execution. If this cannot be done safely, it is recommended to flush the caches by setting the
elijahsj 1:8a094db1347f 145 DCRST and ICRST bits in the FLASH_CR register. */
elijahsj 1:8a094db1347f 146 __HAL_FLASH_ART_DISABLE();
elijahsj 1:8a094db1347f 147 __HAL_FLASH_ART_RESET();
elijahsj 1:8a094db1347f 148 __HAL_FLASH_ART_ENABLE();
elijahsj 1:8a094db1347f 149
elijahsj 1:8a094db1347f 150 while ((size > 0) && (status == 0)) {
elijahsj 1:8a094db1347f 151 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE,
elijahsj 1:8a094db1347f 152 address, (uint64_t)*data) != HAL_OK) {
elijahsj 1:8a094db1347f 153 status = -1;
elijahsj 1:8a094db1347f 154 } else {
elijahsj 1:8a094db1347f 155 size--;
elijahsj 1:8a094db1347f 156 address++;
elijahsj 1:8a094db1347f 157 data++;
elijahsj 1:8a094db1347f 158 }
elijahsj 1:8a094db1347f 159 }
elijahsj 1:8a094db1347f 160
elijahsj 1:8a094db1347f 161 flash_lock();
elijahsj 1:8a094db1347f 162
elijahsj 1:8a094db1347f 163 return status;
elijahsj 1:8a094db1347f 164 }
elijahsj 1:8a094db1347f 165
elijahsj 1:8a094db1347f 166 uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
elijahsj 1:8a094db1347f 167 {
elijahsj 1:8a094db1347f 168 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
elijahsj 1:8a094db1347f 169 return MBED_FLASH_INVALID_SIZE;
elijahsj 1:8a094db1347f 170 }
elijahsj 1:8a094db1347f 171
elijahsj 1:8a094db1347f 172 return (GetSectorSize(GetSector(address)));
elijahsj 1:8a094db1347f 173 }
elijahsj 1:8a094db1347f 174
elijahsj 1:8a094db1347f 175 uint32_t flash_get_page_size(const flash_t *obj)
elijahsj 1:8a094db1347f 176 {
elijahsj 1:8a094db1347f 177 // Flash of STM32F7 devices can be programed 1 byte at a time
elijahsj 1:8a094db1347f 178 return (1);
elijahsj 1:8a094db1347f 179 }
elijahsj 1:8a094db1347f 180
elijahsj 1:8a094db1347f 181 uint32_t flash_get_start_address(const flash_t *obj)
elijahsj 1:8a094db1347f 182 {
elijahsj 1:8a094db1347f 183 return FLASH_BASE;
elijahsj 1:8a094db1347f 184 }
elijahsj 1:8a094db1347f 185 uint32_t flash_get_size(const flash_t *obj)
elijahsj 1:8a094db1347f 186 {
elijahsj 1:8a094db1347f 187 return FLASH_SIZE;
elijahsj 1:8a094db1347f 188 }
elijahsj 1:8a094db1347f 189
elijahsj 1:8a094db1347f 190 /**
elijahsj 1:8a094db1347f 191 * @brief Gets the sector of a given address
elijahsj 1:8a094db1347f 192 * @param None
elijahsj 1:8a094db1347f 193 * @retval The sector of a given address
elijahsj 1:8a094db1347f 194 */
elijahsj 1:8a094db1347f 195 static uint32_t GetSector(uint32_t address)
elijahsj 1:8a094db1347f 196 {
elijahsj 1:8a094db1347f 197 uint32_t sector = 0;
elijahsj 1:8a094db1347f 198 uint32_t tmp = address - ADDR_FLASH_SECTOR_0;
elijahsj 1:8a094db1347f 199
elijahsj 1:8a094db1347f 200 if (address < ADDR_FLASH_SECTOR_4) {
elijahsj 1:8a094db1347f 201 // 32k sectorsize
elijahsj 1:8a094db1347f 202 sector += tmp >>15;
elijahsj 1:8a094db1347f 203 } else if (address < ADDR_FLASH_SECTOR_5) {
elijahsj 1:8a094db1347f 204 //64k sector size
elijahsj 1:8a094db1347f 205 sector += FLASH_SECTOR_4;
elijahsj 1:8a094db1347f 206 } else {
elijahsj 1:8a094db1347f 207 sector += 4 + (tmp >>18);
elijahsj 1:8a094db1347f 208 }
elijahsj 1:8a094db1347f 209
elijahsj 1:8a094db1347f 210 return sector;
elijahsj 1:8a094db1347f 211 }
elijahsj 1:8a094db1347f 212
elijahsj 1:8a094db1347f 213 /**
elijahsj 1:8a094db1347f 214 * @brief Gets sector Size
elijahsj 1:8a094db1347f 215 * @param None
elijahsj 1:8a094db1347f 216 * @retval The size of a given sector
elijahsj 1:8a094db1347f 217 */
elijahsj 1:8a094db1347f 218 static uint32_t GetSectorSize(uint32_t Sector)
elijahsj 1:8a094db1347f 219 {
elijahsj 1:8a094db1347f 220 uint32_t sectorsize = 0x00;
elijahsj 1:8a094db1347f 221 if ((Sector == FLASH_SECTOR_0) || (Sector == FLASH_SECTOR_1) ||\
elijahsj 1:8a094db1347f 222 (Sector == FLASH_SECTOR_2) || (Sector == FLASH_SECTOR_3)) {
elijahsj 1:8a094db1347f 223 sectorsize = 32 * 1024;
elijahsj 1:8a094db1347f 224 } else if (Sector == FLASH_SECTOR_4) {
elijahsj 1:8a094db1347f 225 sectorsize = 128 * 1024;
elijahsj 1:8a094db1347f 226 } else {
elijahsj 1:8a094db1347f 227 sectorsize = 256 * 1024;
elijahsj 1:8a094db1347f 228 }
elijahsj 1:8a094db1347f 229
elijahsj 1:8a094db1347f 230 return sectorsize;
elijahsj 1:8a094db1347f 231 }
elijahsj 1:8a094db1347f 232
elijahsj 1:8a094db1347f 233 #endif