RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
2019-03-13

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 2:7aab896b1a3b 1 /* mbed Microcontroller Library
kevman 2:7aab896b1a3b 2 * Copyright (c) 2016 ARM Limited
kevman 2:7aab896b1a3b 3 *
kevman 2:7aab896b1a3b 4 * Licensed under the Apache License, Version 2.0 (the "License");
kevman 2:7aab896b1a3b 5 * you may not use this file except in compliance with the License.
kevman 2:7aab896b1a3b 6 * You may obtain a copy of the License at
kevman 2:7aab896b1a3b 7 *
kevman 2:7aab896b1a3b 8 * http://www.apache.org/licenses/LICENSE-2.0
kevman 2:7aab896b1a3b 9 *
kevman 2:7aab896b1a3b 10 * Unless required by applicable law or agreed to in writing, software
kevman 2:7aab896b1a3b 11 * distributed under the License is distributed on an "AS IS" BASIS,
kevman 2:7aab896b1a3b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kevman 2:7aab896b1a3b 13 * See the License for the specific language governing permissions and
kevman 2:7aab896b1a3b 14 * limitations under the License.
kevman 2:7aab896b1a3b 15 */
kevman 2:7aab896b1a3b 16
kevman 2:7aab896b1a3b 17 #ifdef DEVICE_FLASH
kevman 2:7aab896b1a3b 18
kevman 2:7aab896b1a3b 19 #include "FlashIAPBlockDevice.h"
kevman 2:7aab896b1a3b 20 #include "mbed_critical.h"
kevman 2:7aab896b1a3b 21
kevman 2:7aab896b1a3b 22 #include "mbed.h"
kevman 2:7aab896b1a3b 23
kevman 2:7aab896b1a3b 24 #include <inttypes.h>
kevman 2:7aab896b1a3b 25
kevman 2:7aab896b1a3b 26 #define FLASHIAP_READ_SIZE 1
kevman 2:7aab896b1a3b 27
kevman 2:7aab896b1a3b 28 // Debug available
kevman 2:7aab896b1a3b 29 #ifndef FLASHIAP_DEBUG
kevman 2:7aab896b1a3b 30 #define FLASHIAP_DEBUG 0
kevman 2:7aab896b1a3b 31 #endif
kevman 2:7aab896b1a3b 32
kevman 2:7aab896b1a3b 33 #if FLASHIAP_DEBUG
kevman 2:7aab896b1a3b 34 #define DEBUG_PRINTF(...) printf(__VA_ARGS__)
kevman 2:7aab896b1a3b 35 #else
kevman 2:7aab896b1a3b 36 #define DEBUG_PRINTF(...)
kevman 2:7aab896b1a3b 37 #endif
kevman 2:7aab896b1a3b 38
kevman 2:7aab896b1a3b 39 FlashIAPBlockDevice::FlashIAPBlockDevice(uint32_t address, uint32_t size)
kevman 2:7aab896b1a3b 40 : _flash(), _base(address), _size(size), _is_initialized(false), _init_ref_count(0)
kevman 2:7aab896b1a3b 41 {
kevman 2:7aab896b1a3b 42
kevman 2:7aab896b1a3b 43 }
kevman 2:7aab896b1a3b 44
kevman 2:7aab896b1a3b 45 FlashIAPBlockDevice::~FlashIAPBlockDevice()
kevman 2:7aab896b1a3b 46 {
kevman 2:7aab896b1a3b 47 deinit();
kevman 2:7aab896b1a3b 48 }
kevman 2:7aab896b1a3b 49
kevman 2:7aab896b1a3b 50 int FlashIAPBlockDevice::init()
kevman 2:7aab896b1a3b 51 {
kevman 2:7aab896b1a3b 52 DEBUG_PRINTF("init\r\n");
kevman 2:7aab896b1a3b 53
kevman 2:7aab896b1a3b 54 if (!_is_initialized) {
kevman 2:7aab896b1a3b 55 _init_ref_count = 0;
kevman 2:7aab896b1a3b 56 }
kevman 2:7aab896b1a3b 57
kevman 2:7aab896b1a3b 58 uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
kevman 2:7aab896b1a3b 59
kevman 2:7aab896b1a3b 60 if (val != 1) {
kevman 2:7aab896b1a3b 61 return BD_ERROR_OK;
kevman 2:7aab896b1a3b 62 }
kevman 2:7aab896b1a3b 63
kevman 2:7aab896b1a3b 64 int ret = _flash.init();
kevman 2:7aab896b1a3b 65
kevman 2:7aab896b1a3b 66 if (ret) {
kevman 2:7aab896b1a3b 67 core_util_atomic_decr_u32(&_init_ref_count, 1);
kevman 2:7aab896b1a3b 68 return ret;
kevman 2:7aab896b1a3b 69 }
kevman 2:7aab896b1a3b 70
kevman 2:7aab896b1a3b 71 if (_size + _base > _flash.get_flash_size() + _flash.get_flash_start()) {
kevman 2:7aab896b1a3b 72 core_util_atomic_decr_u32(&_init_ref_count, 1);
kevman 2:7aab896b1a3b 73 return BD_ERROR_DEVICE_ERROR;
kevman 2:7aab896b1a3b 74 }
kevman 2:7aab896b1a3b 75
kevman 2:7aab896b1a3b 76 if (_base < _flash.get_flash_start()) {
kevman 2:7aab896b1a3b 77 core_util_atomic_decr_u32(&_init_ref_count, 1);
kevman 2:7aab896b1a3b 78 return BD_ERROR_DEVICE_ERROR;
kevman 2:7aab896b1a3b 79 }
kevman 2:7aab896b1a3b 80
kevman 2:7aab896b1a3b 81 if (!_base) {
kevman 2:7aab896b1a3b 82 _base = _flash.get_flash_start();
kevman 2:7aab896b1a3b 83 }
kevman 2:7aab896b1a3b 84
kevman 2:7aab896b1a3b 85 if (!_size) {
kevman 2:7aab896b1a3b 86 _size = _flash.get_flash_size() - (_base - _flash.get_flash_start());
kevman 2:7aab896b1a3b 87 }
kevman 2:7aab896b1a3b 88
kevman 2:7aab896b1a3b 89 _is_initialized = true;
kevman 2:7aab896b1a3b 90 return ret;
kevman 2:7aab896b1a3b 91 }
kevman 2:7aab896b1a3b 92
kevman 2:7aab896b1a3b 93 int FlashIAPBlockDevice::deinit()
kevman 2:7aab896b1a3b 94 {
kevman 2:7aab896b1a3b 95 DEBUG_PRINTF("deinit\r\n");
kevman 2:7aab896b1a3b 96
kevman 2:7aab896b1a3b 97 if (!_is_initialized) {
kevman 2:7aab896b1a3b 98 _init_ref_count = 0;
kevman 2:7aab896b1a3b 99 return 0;
kevman 2:7aab896b1a3b 100 }
kevman 2:7aab896b1a3b 101
kevman 2:7aab896b1a3b 102 uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
kevman 2:7aab896b1a3b 103
kevman 2:7aab896b1a3b 104 if (val) {
kevman 2:7aab896b1a3b 105 return 0;
kevman 2:7aab896b1a3b 106 }
kevman 2:7aab896b1a3b 107
kevman 2:7aab896b1a3b 108 _is_initialized = false;
kevman 2:7aab896b1a3b 109
kevman 2:7aab896b1a3b 110 return _flash.deinit();
kevman 2:7aab896b1a3b 111 }
kevman 2:7aab896b1a3b 112
kevman 2:7aab896b1a3b 113 int FlashIAPBlockDevice::read(void *buffer,
kevman 2:7aab896b1a3b 114 bd_addr_t virtual_address,
kevman 2:7aab896b1a3b 115 bd_size_t size)
kevman 2:7aab896b1a3b 116 {
kevman 2:7aab896b1a3b 117 DEBUG_PRINTF("read: %" PRIX64 " %" PRIX64 "\r\n", virtual_address, size);
kevman 2:7aab896b1a3b 118
kevman 2:7aab896b1a3b 119 /* Default to error return code; success must be set explicitly. */
kevman 2:7aab896b1a3b 120 int result = BD_ERROR_DEVICE_ERROR;
kevman 2:7aab896b1a3b 121
kevman 2:7aab896b1a3b 122 /* Check that the address and size are properly aligned and fit. */
kevman 2:7aab896b1a3b 123 if (_is_initialized && is_valid_read(virtual_address, size)) {
kevman 2:7aab896b1a3b 124
kevman 2:7aab896b1a3b 125 /* Convert virtual address to the physical address for the device. */
kevman 2:7aab896b1a3b 126 bd_addr_t physical_address = _base + virtual_address;
kevman 2:7aab896b1a3b 127
kevman 2:7aab896b1a3b 128 /* Read data using the internal flash driver. */
kevman 2:7aab896b1a3b 129 result = _flash.read(buffer, physical_address, size);
kevman 2:7aab896b1a3b 130
kevman 2:7aab896b1a3b 131 DEBUG_PRINTF("physical: %" PRIX64 "\r\n", physical_address);
kevman 2:7aab896b1a3b 132 }
kevman 2:7aab896b1a3b 133
kevman 2:7aab896b1a3b 134 return result;
kevman 2:7aab896b1a3b 135 }
kevman 2:7aab896b1a3b 136
kevman 2:7aab896b1a3b 137 int FlashIAPBlockDevice::program(const void *buffer,
kevman 2:7aab896b1a3b 138 bd_addr_t virtual_address,
kevman 2:7aab896b1a3b 139 bd_size_t size)
kevman 2:7aab896b1a3b 140 {
kevman 2:7aab896b1a3b 141 DEBUG_PRINTF("program: %" PRIX64 " %" PRIX64 "\r\n", virtual_address, size);
kevman 2:7aab896b1a3b 142
kevman 2:7aab896b1a3b 143 /* Default to error return code; success must be set explicitly. */
kevman 2:7aab896b1a3b 144 int result = BD_ERROR_DEVICE_ERROR;
kevman 2:7aab896b1a3b 145
kevman 2:7aab896b1a3b 146 /* Check that the address and size are properly aligned and fit. */
kevman 2:7aab896b1a3b 147 if (_is_initialized && is_valid_program(virtual_address, size)) {
kevman 2:7aab896b1a3b 148
kevman 2:7aab896b1a3b 149 /* Convert virtual address to the physical address for the device. */
kevman 2:7aab896b1a3b 150 bd_addr_t physical_address = _base + virtual_address;
kevman 2:7aab896b1a3b 151
kevman 2:7aab896b1a3b 152 /* Write data using the internal flash driver. */
kevman 2:7aab896b1a3b 153 result = _flash.program(buffer, physical_address, size);
kevman 2:7aab896b1a3b 154
kevman 2:7aab896b1a3b 155 DEBUG_PRINTF("physical: %" PRIX64 " %" PRIX64 "\r\n",
kevman 2:7aab896b1a3b 156 physical_address,
kevman 2:7aab896b1a3b 157 size);
kevman 2:7aab896b1a3b 158 }
kevman 2:7aab896b1a3b 159
kevman 2:7aab896b1a3b 160 return result;
kevman 2:7aab896b1a3b 161 }
kevman 2:7aab896b1a3b 162
kevman 2:7aab896b1a3b 163 int FlashIAPBlockDevice::erase(bd_addr_t virtual_address,
kevman 2:7aab896b1a3b 164 bd_size_t size)
kevman 2:7aab896b1a3b 165 {
kevman 2:7aab896b1a3b 166 DEBUG_PRINTF("erase: %" PRIX64 " %" PRIX64 "\r\n", virtual_address, size);
kevman 2:7aab896b1a3b 167
kevman 2:7aab896b1a3b 168 /* Default to error return code; success must be set explicitly. */
kevman 2:7aab896b1a3b 169 int result = BD_ERROR_DEVICE_ERROR;
kevman 2:7aab896b1a3b 170
kevman 2:7aab896b1a3b 171 /* Check that the address and size are properly aligned and fit. */
kevman 2:7aab896b1a3b 172 if (_is_initialized && is_valid_erase(virtual_address, size)) {
kevman 2:7aab896b1a3b 173
kevman 2:7aab896b1a3b 174 /* Convert virtual address to the physical address for the device. */
kevman 2:7aab896b1a3b 175 bd_addr_t physical_address = _base + virtual_address;
kevman 2:7aab896b1a3b 176
kevman 2:7aab896b1a3b 177 /* Erase sector */
kevman 2:7aab896b1a3b 178 result = _flash.erase(physical_address, size);
kevman 2:7aab896b1a3b 179 }
kevman 2:7aab896b1a3b 180
kevman 2:7aab896b1a3b 181 return result;
kevman 2:7aab896b1a3b 182 }
kevman 2:7aab896b1a3b 183
kevman 2:7aab896b1a3b 184 bd_size_t FlashIAPBlockDevice::get_read_size() const
kevman 2:7aab896b1a3b 185 {
kevman 2:7aab896b1a3b 186 DEBUG_PRINTF("get_read_size: %d\r\n", FLASHIAP_READ_SIZE);
kevman 2:7aab896b1a3b 187
kevman 2:7aab896b1a3b 188 return FLASHIAP_READ_SIZE;
kevman 2:7aab896b1a3b 189 }
kevman 2:7aab896b1a3b 190
kevman 2:7aab896b1a3b 191 bd_size_t FlashIAPBlockDevice::get_program_size() const
kevman 2:7aab896b1a3b 192 {
kevman 2:7aab896b1a3b 193 if (!_is_initialized) {
kevman 2:7aab896b1a3b 194 return 0;
kevman 2:7aab896b1a3b 195 }
kevman 2:7aab896b1a3b 196
kevman 2:7aab896b1a3b 197 uint32_t page_size = _flash.get_page_size();
kevman 2:7aab896b1a3b 198
kevman 2:7aab896b1a3b 199 DEBUG_PRINTF("get_program_size: %" PRIX32 "\r\n", page_size);
kevman 2:7aab896b1a3b 200
kevman 2:7aab896b1a3b 201 return page_size;
kevman 2:7aab896b1a3b 202 }
kevman 2:7aab896b1a3b 203
kevman 2:7aab896b1a3b 204 bd_size_t FlashIAPBlockDevice::get_erase_size() const
kevman 2:7aab896b1a3b 205 {
kevman 2:7aab896b1a3b 206 if (!_is_initialized) {
kevman 2:7aab896b1a3b 207 return 0;
kevman 2:7aab896b1a3b 208 }
kevman 2:7aab896b1a3b 209
kevman 2:7aab896b1a3b 210 uint32_t erase_size = _flash.get_sector_size(_base);
kevman 2:7aab896b1a3b 211
kevman 2:7aab896b1a3b 212 DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size);
kevman 2:7aab896b1a3b 213
kevman 2:7aab896b1a3b 214 return erase_size;
kevman 2:7aab896b1a3b 215 }
kevman 2:7aab896b1a3b 216
kevman 2:7aab896b1a3b 217 bd_size_t FlashIAPBlockDevice::get_erase_size(bd_addr_t addr) const
kevman 2:7aab896b1a3b 218 {
kevman 2:7aab896b1a3b 219 if (!_is_initialized) {
kevman 2:7aab896b1a3b 220 return 0;
kevman 2:7aab896b1a3b 221 }
kevman 2:7aab896b1a3b 222
kevman 2:7aab896b1a3b 223 uint32_t erase_size = _flash.get_sector_size(_base + addr);
kevman 2:7aab896b1a3b 224
kevman 2:7aab896b1a3b 225 DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size);
kevman 2:7aab896b1a3b 226
kevman 2:7aab896b1a3b 227 return erase_size;
kevman 2:7aab896b1a3b 228 }
kevman 2:7aab896b1a3b 229
kevman 2:7aab896b1a3b 230 bd_size_t FlashIAPBlockDevice::size() const
kevman 2:7aab896b1a3b 231 {
kevman 2:7aab896b1a3b 232 DEBUG_PRINTF("size: %" PRIX64 "\r\n", _size);
kevman 2:7aab896b1a3b 233
kevman 2:7aab896b1a3b 234 return _size;
kevman 2:7aab896b1a3b 235 }
kevman 2:7aab896b1a3b 236
kevman 2:7aab896b1a3b 237 #endif /* DEVICE_FLASH */