takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FlashIAPBlockDevice.cpp Source File

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 */