Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
FlashIAPBlockDevice.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2016 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifdef DEVICE_FLASH 00018 00019 #include "FlashIAPBlockDevice.h" 00020 #include "mbed_critical.h" 00021 00022 #include "mbed.h" 00023 00024 #include <inttypes.h> 00025 00026 #define FLASHIAP_READ_SIZE 1 00027 00028 // Debug available 00029 #ifndef FLASHIAP_DEBUG 00030 #define FLASHIAP_DEBUG 0 00031 #endif 00032 00033 #if FLASHIAP_DEBUG 00034 #define DEBUG_PRINTF(...) printf(__VA_ARGS__) 00035 #else 00036 #define DEBUG_PRINTF(...) 00037 #endif 00038 00039 FlashIAPBlockDevice::FlashIAPBlockDevice() 00040 : _flash(), _base(0), _size(0), _is_initialized(false), _init_ref_count(0) 00041 { 00042 DEBUG_PRINTF("FlashIAPBlockDevice: %" PRIX32 " %" PRIX32 "\r\n", address, size); 00043 } 00044 00045 FlashIAPBlockDevice::FlashIAPBlockDevice(uint32_t address, uint32_t) 00046 : _flash(), _base(0), _size(0), _is_initialized(false), _init_ref_count(0) 00047 { 00048 00049 } 00050 00051 FlashIAPBlockDevice::~FlashIAPBlockDevice() 00052 { 00053 deinit(); 00054 } 00055 00056 int FlashIAPBlockDevice::init() 00057 { 00058 DEBUG_PRINTF("init\r\n"); 00059 00060 if (!_is_initialized) { 00061 _init_ref_count = 0; 00062 } 00063 00064 uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); 00065 00066 if (val != 1) { 00067 return BD_ERROR_OK; 00068 } 00069 00070 int ret = _flash.init(); 00071 00072 if (ret) { 00073 return ret; 00074 } 00075 00076 _base = _flash.get_flash_start(); 00077 _size = _flash.get_flash_size(); 00078 00079 _is_initialized = true; 00080 return ret; 00081 } 00082 00083 int FlashIAPBlockDevice::deinit() 00084 { 00085 DEBUG_PRINTF("deinit\r\n"); 00086 00087 if (!_is_initialized) { 00088 _init_ref_count = 0; 00089 return 0; 00090 } 00091 00092 uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1); 00093 00094 if (val) { 00095 return 0; 00096 } 00097 00098 _is_initialized = false; 00099 00100 return _flash.deinit(); 00101 } 00102 00103 int FlashIAPBlockDevice::read(void *buffer, 00104 bd_addr_t virtual_address, 00105 bd_size_t size) 00106 { 00107 DEBUG_PRINTF("read: %" PRIX64 " %" PRIX64 "\r\n", virtual_address, size); 00108 00109 /* Default to error return code; success must be set explicitly. */ 00110 int result = BD_ERROR_DEVICE_ERROR; 00111 00112 /* Check that the address and size are properly aligned and fit. */ 00113 if (_is_initialized && is_valid_read(virtual_address, size)) { 00114 00115 /* Convert virtual address to the physical address for the device. */ 00116 bd_addr_t physical_address = _base + virtual_address; 00117 00118 /* Read data using the internal flash driver. */ 00119 result = _flash.read(buffer, physical_address, size); 00120 00121 DEBUG_PRINTF("physical: %" PRIX64 "\r\n", physical_address); 00122 } 00123 00124 return result; 00125 } 00126 00127 int FlashIAPBlockDevice::program(const void *buffer, 00128 bd_addr_t virtual_address, 00129 bd_size_t size) 00130 { 00131 DEBUG_PRINTF("program: %" PRIX64 " %" PRIX64 "\r\n", virtual_address, size); 00132 00133 /* Default to error return code; success must be set explicitly. */ 00134 int result = BD_ERROR_DEVICE_ERROR; 00135 00136 /* Check that the address and size are properly aligned and fit. */ 00137 if (_is_initialized && is_valid_program(virtual_address, size)) { 00138 00139 /* Convert virtual address to the physical address for the device. */ 00140 bd_addr_t physical_address = _base + virtual_address; 00141 00142 /* Write data using the internal flash driver. */ 00143 result = _flash.program(buffer, physical_address, size); 00144 00145 DEBUG_PRINTF("physical: %" PRIX64 " %" PRIX64 "\r\n", 00146 physical_address, 00147 size); 00148 } 00149 00150 return result; 00151 } 00152 00153 int FlashIAPBlockDevice::erase(bd_addr_t virtual_address, 00154 bd_size_t size) 00155 { 00156 DEBUG_PRINTF("erase: %" PRIX64 " %" PRIX64 "\r\n", virtual_address, size); 00157 00158 /* Default to error return code; success must be set explicitly. */ 00159 int result = BD_ERROR_DEVICE_ERROR; 00160 00161 /* Check that the address and size are properly aligned and fit. */ 00162 if (_is_initialized && is_valid_erase(virtual_address, size)) { 00163 00164 /* Convert virtual address to the physical address for the device. */ 00165 bd_addr_t physical_address = _base + virtual_address; 00166 00167 /* Erase sector */ 00168 result = _flash.erase(physical_address, size); 00169 } 00170 00171 return result; 00172 } 00173 00174 bd_size_t FlashIAPBlockDevice::get_read_size() const 00175 { 00176 DEBUG_PRINTF("get_read_size: %d\r\n", FLASHIAP_READ_SIZE); 00177 00178 return FLASHIAP_READ_SIZE; 00179 } 00180 00181 bd_size_t FlashIAPBlockDevice::get_program_size() const 00182 { 00183 if (!_is_initialized) { 00184 return 0; 00185 } 00186 00187 uint32_t page_size = _flash.get_page_size(); 00188 00189 DEBUG_PRINTF("get_program_size: %" PRIX32 "\r\n", page_size); 00190 00191 return page_size; 00192 } 00193 00194 bd_size_t FlashIAPBlockDevice::get_erase_size() const 00195 { 00196 if (!_is_initialized) { 00197 return 0; 00198 } 00199 00200 uint32_t erase_size = _flash.get_sector_size(_base); 00201 00202 DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size); 00203 00204 return erase_size; 00205 } 00206 00207 bd_size_t FlashIAPBlockDevice::get_erase_size(bd_addr_t addr) const 00208 { 00209 if (!_is_initialized) { 00210 return 0; 00211 } 00212 00213 uint32_t erase_size = _flash.get_sector_size(_base + addr); 00214 00215 DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size); 00216 00217 return erase_size; 00218 } 00219 00220 bd_size_t FlashIAPBlockDevice::size() const 00221 { 00222 DEBUG_PRINTF("size: %" PRIX64 "\r\n", _size); 00223 00224 return _size; 00225 } 00226 00227 #endif /* DEVICE_FLASH */
Generated on Tue Aug 9 2022 00:37:07 by
