mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_GigaDevice/TARGET_GD32E10X/flash_api.c@189:f392fc9709a3, 2019-02-20 (annotated)
- Committer:
- AnnaBridge
- Date:
- Wed Feb 20 22:31:08 2019 +0000
- Revision:
- 189:f392fc9709a3
mbed library release version 165
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AnnaBridge | 189:f392fc9709a3 | 1 | /* mbed Microcontroller Library |
AnnaBridge | 189:f392fc9709a3 | 2 | * Copyright (c) 2018 GigaDevice Semiconductor Inc. |
AnnaBridge | 189:f392fc9709a3 | 3 | * |
AnnaBridge | 189:f392fc9709a3 | 4 | * SPDX-License-Identifier: Apache-2.0 |
AnnaBridge | 189:f392fc9709a3 | 5 | * |
AnnaBridge | 189:f392fc9709a3 | 6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
AnnaBridge | 189:f392fc9709a3 | 7 | * you may not use this file except in compliance with the License. |
AnnaBridge | 189:f392fc9709a3 | 8 | * You may obtain a copy of the License at |
AnnaBridge | 189:f392fc9709a3 | 9 | * |
AnnaBridge | 189:f392fc9709a3 | 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
AnnaBridge | 189:f392fc9709a3 | 11 | * |
AnnaBridge | 189:f392fc9709a3 | 12 | * Unless required by applicable law or agreed to in writing, software |
AnnaBridge | 189:f392fc9709a3 | 13 | * distributed under the License is distributed on an "AS IS" BASIS, |
AnnaBridge | 189:f392fc9709a3 | 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
AnnaBridge | 189:f392fc9709a3 | 15 | * See the License for the specific language governing permissions and |
AnnaBridge | 189:f392fc9709a3 | 16 | * limitations under the License. |
AnnaBridge | 189:f392fc9709a3 | 17 | */ |
AnnaBridge | 189:f392fc9709a3 | 18 | |
AnnaBridge | 189:f392fc9709a3 | 19 | #include "flash_api.h" |
AnnaBridge | 189:f392fc9709a3 | 20 | #include "mbed_critical.h" |
AnnaBridge | 189:f392fc9709a3 | 21 | |
AnnaBridge | 189:f392fc9709a3 | 22 | #if DEVICE_FLASH |
AnnaBridge | 189:f392fc9709a3 | 23 | #include "cmsis.h" |
AnnaBridge | 189:f392fc9709a3 | 24 | |
AnnaBridge | 189:f392fc9709a3 | 25 | #define FLASH_SIZE (0x00020000U) |
AnnaBridge | 189:f392fc9709a3 | 26 | #define FLASH_PAGE_SIZE (0x00000400U) |
AnnaBridge | 189:f392fc9709a3 | 27 | #define FLASH_START_ADDR (0X08000000U) |
AnnaBridge | 189:f392fc9709a3 | 28 | #define FLASH_END_ADDR (0x0801FFFFU) |
AnnaBridge | 189:f392fc9709a3 | 29 | #define WORD_SIZE (4U) |
AnnaBridge | 189:f392fc9709a3 | 30 | |
AnnaBridge | 189:f392fc9709a3 | 31 | /* unlock the main FLASH operation |
AnnaBridge | 189:f392fc9709a3 | 32 | * |
AnnaBridge | 189:f392fc9709a3 | 33 | * @return 0 for success, -1 for error |
AnnaBridge | 189:f392fc9709a3 | 34 | */ |
AnnaBridge | 189:f392fc9709a3 | 35 | static int32_t flash_unlock(void) |
AnnaBridge | 189:f392fc9709a3 | 36 | { |
AnnaBridge | 189:f392fc9709a3 | 37 | fmc_unlock(); |
AnnaBridge | 189:f392fc9709a3 | 38 | if (RESET != (FMC_CTL & FMC_CTL_LK)) { |
AnnaBridge | 189:f392fc9709a3 | 39 | return -1; |
AnnaBridge | 189:f392fc9709a3 | 40 | } |
AnnaBridge | 189:f392fc9709a3 | 41 | return 0; |
AnnaBridge | 189:f392fc9709a3 | 42 | } |
AnnaBridge | 189:f392fc9709a3 | 43 | |
AnnaBridge | 189:f392fc9709a3 | 44 | /* lock the main FLASH operation |
AnnaBridge | 189:f392fc9709a3 | 45 | * |
AnnaBridge | 189:f392fc9709a3 | 46 | * @return 0 for success, -1 for error |
AnnaBridge | 189:f392fc9709a3 | 47 | */ |
AnnaBridge | 189:f392fc9709a3 | 48 | static int32_t flash_lock(void) |
AnnaBridge | 189:f392fc9709a3 | 49 | { |
AnnaBridge | 189:f392fc9709a3 | 50 | fmc_lock(); |
AnnaBridge | 189:f392fc9709a3 | 51 | if (RESET == (FMC_CTL & FMC_CTL_LK)) { |
AnnaBridge | 189:f392fc9709a3 | 52 | return -1; |
AnnaBridge | 189:f392fc9709a3 | 53 | } |
AnnaBridge | 189:f392fc9709a3 | 54 | return 0; |
AnnaBridge | 189:f392fc9709a3 | 55 | } |
AnnaBridge | 189:f392fc9709a3 | 56 | |
AnnaBridge | 189:f392fc9709a3 | 57 | /** Initialize the flash peripheral and the flash_t object |
AnnaBridge | 189:f392fc9709a3 | 58 | * |
AnnaBridge | 189:f392fc9709a3 | 59 | * @param obj The flash object |
AnnaBridge | 189:f392fc9709a3 | 60 | * @return 0 for success, -1 for error |
AnnaBridge | 189:f392fc9709a3 | 61 | */ |
AnnaBridge | 189:f392fc9709a3 | 62 | int32_t flash_init(flash_t *obj) |
AnnaBridge | 189:f392fc9709a3 | 63 | { |
AnnaBridge | 189:f392fc9709a3 | 64 | return 0; |
AnnaBridge | 189:f392fc9709a3 | 65 | } |
AnnaBridge | 189:f392fc9709a3 | 66 | |
AnnaBridge | 189:f392fc9709a3 | 67 | /** Uninitialize the flash peripheral and the flash_t object |
AnnaBridge | 189:f392fc9709a3 | 68 | * |
AnnaBridge | 189:f392fc9709a3 | 69 | * @param obj The flash object |
AnnaBridge | 189:f392fc9709a3 | 70 | * @return 0 for success, -1 for error |
AnnaBridge | 189:f392fc9709a3 | 71 | */ |
AnnaBridge | 189:f392fc9709a3 | 72 | int32_t flash_free(flash_t *obj) |
AnnaBridge | 189:f392fc9709a3 | 73 | { |
AnnaBridge | 189:f392fc9709a3 | 74 | return 0; |
AnnaBridge | 189:f392fc9709a3 | 75 | } |
AnnaBridge | 189:f392fc9709a3 | 76 | |
AnnaBridge | 189:f392fc9709a3 | 77 | /** Erase one sector starting at defined address |
AnnaBridge | 189:f392fc9709a3 | 78 | * |
AnnaBridge | 189:f392fc9709a3 | 79 | * The address should be at sector boundary. This function does not do any check for address alignments |
AnnaBridge | 189:f392fc9709a3 | 80 | * @param obj The flash object |
AnnaBridge | 189:f392fc9709a3 | 81 | * @param address The sector starting address |
AnnaBridge | 189:f392fc9709a3 | 82 | * @return 0 for success, -1 for error |
AnnaBridge | 189:f392fc9709a3 | 83 | */ |
AnnaBridge | 189:f392fc9709a3 | 84 | int32_t flash_erase_sector(flash_t *obj, uint32_t address) |
AnnaBridge | 189:f392fc9709a3 | 85 | { |
AnnaBridge | 189:f392fc9709a3 | 86 | int32_t flash_state = 0; |
AnnaBridge | 189:f392fc9709a3 | 87 | flash_unlock(); |
AnnaBridge | 189:f392fc9709a3 | 88 | |
AnnaBridge | 189:f392fc9709a3 | 89 | /* clear FLASH flag */ |
AnnaBridge | 189:f392fc9709a3 | 90 | fmc_flag_clear(FMC_FLAG_PGERR); |
AnnaBridge | 189:f392fc9709a3 | 91 | fmc_flag_clear(FMC_FLAG_PGAERR); |
AnnaBridge | 189:f392fc9709a3 | 92 | fmc_flag_clear(FMC_FLAG_WPERR); |
AnnaBridge | 189:f392fc9709a3 | 93 | fmc_flag_clear(FMC_FLAG_END); |
AnnaBridge | 189:f392fc9709a3 | 94 | |
AnnaBridge | 189:f392fc9709a3 | 95 | /* make sure the address is a right page address */ |
AnnaBridge | 189:f392fc9709a3 | 96 | if (FMC_READY != fmc_page_erase(address)) { |
AnnaBridge | 189:f392fc9709a3 | 97 | flash_state = -1; |
AnnaBridge | 189:f392fc9709a3 | 98 | } |
AnnaBridge | 189:f392fc9709a3 | 99 | |
AnnaBridge | 189:f392fc9709a3 | 100 | flash_lock(); |
AnnaBridge | 189:f392fc9709a3 | 101 | return flash_state; |
AnnaBridge | 189:f392fc9709a3 | 102 | } |
AnnaBridge | 189:f392fc9709a3 | 103 | |
AnnaBridge | 189:f392fc9709a3 | 104 | /** Program pages starting at defined address |
AnnaBridge | 189:f392fc9709a3 | 105 | * |
AnnaBridge | 189:f392fc9709a3 | 106 | * The pages should not cross multiple sectors. |
AnnaBridge | 189:f392fc9709a3 | 107 | * This function does not do any check for address alignments or if size is aligned to a page size. |
AnnaBridge | 189:f392fc9709a3 | 108 | * @param obj The flash object |
AnnaBridge | 189:f392fc9709a3 | 109 | * @param address The sector starting address |
AnnaBridge | 189:f392fc9709a3 | 110 | * @param data The data buffer to be programmed |
AnnaBridge | 189:f392fc9709a3 | 111 | * @param size The number of bytes to program |
AnnaBridge | 189:f392fc9709a3 | 112 | * @return 0 for success, -1 for error |
AnnaBridge | 189:f392fc9709a3 | 113 | */ |
AnnaBridge | 189:f392fc9709a3 | 114 | int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size) |
AnnaBridge | 189:f392fc9709a3 | 115 | { |
AnnaBridge | 189:f392fc9709a3 | 116 | uint32_t *p_data; |
AnnaBridge | 189:f392fc9709a3 | 117 | p_data = (uint32_t *)data; |
AnnaBridge | 189:f392fc9709a3 | 118 | uint32_t num = 0; |
AnnaBridge | 189:f392fc9709a3 | 119 | int32_t flash_state = 0; |
AnnaBridge | 189:f392fc9709a3 | 120 | flash_unlock(); |
AnnaBridge | 189:f392fc9709a3 | 121 | |
AnnaBridge | 189:f392fc9709a3 | 122 | /* clear FLASH flag */ |
AnnaBridge | 189:f392fc9709a3 | 123 | fmc_flag_clear(FMC_FLAG_PGERR); |
AnnaBridge | 189:f392fc9709a3 | 124 | fmc_flag_clear(FMC_FLAG_PGAERR); |
AnnaBridge | 189:f392fc9709a3 | 125 | fmc_flag_clear(FMC_FLAG_WPERR); |
AnnaBridge | 189:f392fc9709a3 | 126 | fmc_flag_clear(FMC_FLAG_END); |
AnnaBridge | 189:f392fc9709a3 | 127 | |
AnnaBridge | 189:f392fc9709a3 | 128 | if (size % 4) { |
AnnaBridge | 189:f392fc9709a3 | 129 | num = size / 4 + 1; |
AnnaBridge | 189:f392fc9709a3 | 130 | } else { |
AnnaBridge | 189:f392fc9709a3 | 131 | num = size / 4; |
AnnaBridge | 189:f392fc9709a3 | 132 | } |
AnnaBridge | 189:f392fc9709a3 | 133 | for (uint32_t i = 0; i < num; i++) { |
AnnaBridge | 189:f392fc9709a3 | 134 | |
AnnaBridge | 189:f392fc9709a3 | 135 | if (FMC_READY != fmc_word_program(address, *(p_data + i))) { |
AnnaBridge | 189:f392fc9709a3 | 136 | flash_state = -1; |
AnnaBridge | 189:f392fc9709a3 | 137 | break; |
AnnaBridge | 189:f392fc9709a3 | 138 | } |
AnnaBridge | 189:f392fc9709a3 | 139 | address += 4; |
AnnaBridge | 189:f392fc9709a3 | 140 | } |
AnnaBridge | 189:f392fc9709a3 | 141 | flash_lock(); |
AnnaBridge | 189:f392fc9709a3 | 142 | return flash_state; |
AnnaBridge | 189:f392fc9709a3 | 143 | } |
AnnaBridge | 189:f392fc9709a3 | 144 | |
AnnaBridge | 189:f392fc9709a3 | 145 | /** Get sector size |
AnnaBridge | 189:f392fc9709a3 | 146 | * |
AnnaBridge | 189:f392fc9709a3 | 147 | * @param obj The flash object |
AnnaBridge | 189:f392fc9709a3 | 148 | * @param address The sector starting address |
AnnaBridge | 189:f392fc9709a3 | 149 | * @return The size of a sector |
AnnaBridge | 189:f392fc9709a3 | 150 | */ |
AnnaBridge | 189:f392fc9709a3 | 151 | uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) |
AnnaBridge | 189:f392fc9709a3 | 152 | { |
AnnaBridge | 189:f392fc9709a3 | 153 | if ((FLASH_START_ADDR > address) || (FLASH_END_ADDR < address)) { |
AnnaBridge | 189:f392fc9709a3 | 154 | return MBED_FLASH_INVALID_SIZE; |
AnnaBridge | 189:f392fc9709a3 | 155 | } |
AnnaBridge | 189:f392fc9709a3 | 156 | return FLASH_PAGE_SIZE; |
AnnaBridge | 189:f392fc9709a3 | 157 | } |
AnnaBridge | 189:f392fc9709a3 | 158 | |
AnnaBridge | 189:f392fc9709a3 | 159 | /** Get page size |
AnnaBridge | 189:f392fc9709a3 | 160 | * |
AnnaBridge | 189:f392fc9709a3 | 161 | * The page size defines the writable page size |
AnnaBridge | 189:f392fc9709a3 | 162 | * @param obj The flash object |
AnnaBridge | 189:f392fc9709a3 | 163 | * @return The size of a page |
AnnaBridge | 189:f392fc9709a3 | 164 | */ |
AnnaBridge | 189:f392fc9709a3 | 165 | uint32_t flash_get_page_size(const flash_t *obj) |
AnnaBridge | 189:f392fc9709a3 | 166 | { |
AnnaBridge | 189:f392fc9709a3 | 167 | return WORD_SIZE; |
AnnaBridge | 189:f392fc9709a3 | 168 | } |
AnnaBridge | 189:f392fc9709a3 | 169 | |
AnnaBridge | 189:f392fc9709a3 | 170 | /** Get start address for the flash region |
AnnaBridge | 189:f392fc9709a3 | 171 | * |
AnnaBridge | 189:f392fc9709a3 | 172 | * @param obj The flash object |
AnnaBridge | 189:f392fc9709a3 | 173 | * @return The start address for the flash region |
AnnaBridge | 189:f392fc9709a3 | 174 | */ |
AnnaBridge | 189:f392fc9709a3 | 175 | uint32_t flash_get_start_address(const flash_t *obj) |
AnnaBridge | 189:f392fc9709a3 | 176 | { |
AnnaBridge | 189:f392fc9709a3 | 177 | return FLASH_START_ADDR; |
AnnaBridge | 189:f392fc9709a3 | 178 | } |
AnnaBridge | 189:f392fc9709a3 | 179 | |
AnnaBridge | 189:f392fc9709a3 | 180 | /** Get the flash region size |
AnnaBridge | 189:f392fc9709a3 | 181 | * |
AnnaBridge | 189:f392fc9709a3 | 182 | * @param obj The flash object |
AnnaBridge | 189:f392fc9709a3 | 183 | * @return The flash region size |
AnnaBridge | 189:f392fc9709a3 | 184 | */ |
AnnaBridge | 189:f392fc9709a3 | 185 | uint32_t flash_get_size(const flash_t *obj) |
AnnaBridge | 189:f392fc9709a3 | 186 | { |
AnnaBridge | 189:f392fc9709a3 | 187 | return FLASH_SIZE; |
AnnaBridge | 189:f392fc9709a3 | 188 | } |
AnnaBridge | 189:f392fc9709a3 | 189 | |
AnnaBridge | 189:f392fc9709a3 | 190 | /** Get the flash erase value |
AnnaBridge | 189:f392fc9709a3 | 191 | * |
AnnaBridge | 189:f392fc9709a3 | 192 | * @param obj The flash object |
AnnaBridge | 189:f392fc9709a3 | 193 | * @return The flash erase value |
AnnaBridge | 189:f392fc9709a3 | 194 | */ |
AnnaBridge | 189:f392fc9709a3 | 195 | uint8_t flash_get_erase_value(const flash_t *obj) |
AnnaBridge | 189:f392fc9709a3 | 196 | { |
AnnaBridge | 189:f392fc9709a3 | 197 | return 0xFF; |
AnnaBridge | 189:f392fc9709a3 | 198 | } |
AnnaBridge | 189:f392fc9709a3 | 199 | |
AnnaBridge | 189:f392fc9709a3 | 200 | #endif /* DEVICE_FLASH */ |