mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
Parent:
0:5b88d5760320
updated based on mbed-os5.15.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:5b88d5760320 1 /* mbed Microcontroller Library
kenjiArai 0:5b88d5760320 2 * Copyright (c) 2017 ARM Limited
kenjiArai 0:5b88d5760320 3 *
kenjiArai 0:5b88d5760320 4 * Licensed under the Apache License, Version 2.0 (the "License");
kenjiArai 0:5b88d5760320 5 * you may not use this file except in compliance with the License.
kenjiArai 0:5b88d5760320 6 * You may obtain a copy of the License at
kenjiArai 0:5b88d5760320 7 *
kenjiArai 0:5b88d5760320 8 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 0:5b88d5760320 9 *
kenjiArai 0:5b88d5760320 10 * Unless required by applicable law or agreed to in writing, software
kenjiArai 0:5b88d5760320 11 * distributed under the License is distributed on an "AS IS" BASIS,
kenjiArai 0:5b88d5760320 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 0:5b88d5760320 13 * See the License for the specific language governing permissions and
kenjiArai 0:5b88d5760320 14 * limitations under the License.
kenjiArai 0:5b88d5760320 15 */
kenjiArai 0:5b88d5760320 16
kenjiArai 0:5b88d5760320 17 #include "HeapBlockDevice.h"
kenjiArai 0:5b88d5760320 18 #include "platform/mbed_atomic.h"
kenjiArai 0:5b88d5760320 19 #include <stdlib.h>
kenjiArai 0:5b88d5760320 20 #include <string.h>
kenjiArai 0:5b88d5760320 21
kenjiArai 0:5b88d5760320 22 namespace mbed {
kenjiArai 0:5b88d5760320 23
kenjiArai 0:5b88d5760320 24 HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t block)
kenjiArai 0:5b88d5760320 25 : _read_size(block), _program_size(block), _erase_size(block)
kenjiArai 0:5b88d5760320 26 , _count(size / block), _blocks(0), _init_ref_count(0), _is_initialized(false)
kenjiArai 0:5b88d5760320 27 {
kenjiArai 0:5b88d5760320 28 MBED_ASSERT(_count * _erase_size == size);
kenjiArai 0:5b88d5760320 29 }
kenjiArai 0:5b88d5760320 30
kenjiArai 0:5b88d5760320 31 HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t read, bd_size_t program, bd_size_t erase)
kenjiArai 0:5b88d5760320 32 : _read_size(read), _program_size(program), _erase_size(erase)
kenjiArai 0:5b88d5760320 33 , _count(size / erase), _blocks(0), _init_ref_count(0), _is_initialized(false)
kenjiArai 0:5b88d5760320 34 {
kenjiArai 0:5b88d5760320 35 MBED_ASSERT(_count * _erase_size == size);
kenjiArai 0:5b88d5760320 36 }
kenjiArai 0:5b88d5760320 37
kenjiArai 0:5b88d5760320 38 HeapBlockDevice::~HeapBlockDevice()
kenjiArai 0:5b88d5760320 39 {
kenjiArai 0:5b88d5760320 40 if (_blocks) {
kenjiArai 0:5b88d5760320 41 for (size_t i = 0; i < _count; i++) {
kenjiArai 0:5b88d5760320 42 free(_blocks[i]);
kenjiArai 0:5b88d5760320 43 }
kenjiArai 0:5b88d5760320 44
kenjiArai 0:5b88d5760320 45 delete[] _blocks;
kenjiArai 0:5b88d5760320 46 _blocks = 0;
kenjiArai 0:5b88d5760320 47 }
kenjiArai 0:5b88d5760320 48 }
kenjiArai 0:5b88d5760320 49
kenjiArai 0:5b88d5760320 50 int HeapBlockDevice::init()
kenjiArai 0:5b88d5760320 51 {
kenjiArai 0:5b88d5760320 52 uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
kenjiArai 0:5b88d5760320 53
kenjiArai 0:5b88d5760320 54 if (val != 1) {
kenjiArai 0:5b88d5760320 55 return BD_ERROR_OK;
kenjiArai 0:5b88d5760320 56 }
kenjiArai 0:5b88d5760320 57
kenjiArai 0:5b88d5760320 58 if (!_blocks) {
kenjiArai 0:5b88d5760320 59 _blocks = new uint8_t *[_count];
kenjiArai 0:5b88d5760320 60 for (size_t i = 0; i < _count; i++) {
kenjiArai 0:5b88d5760320 61 _blocks[i] = 0;
kenjiArai 0:5b88d5760320 62 }
kenjiArai 0:5b88d5760320 63 }
kenjiArai 0:5b88d5760320 64
kenjiArai 0:5b88d5760320 65 _is_initialized = true;
kenjiArai 0:5b88d5760320 66 return BD_ERROR_OK;
kenjiArai 0:5b88d5760320 67 }
kenjiArai 0:5b88d5760320 68
kenjiArai 0:5b88d5760320 69 int HeapBlockDevice::deinit()
kenjiArai 0:5b88d5760320 70 {
kenjiArai 0:5b88d5760320 71 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 72 return BD_ERROR_OK;
kenjiArai 0:5b88d5760320 73 }
kenjiArai 0:5b88d5760320 74
kenjiArai 0:5b88d5760320 75 uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
kenjiArai 0:5b88d5760320 76
kenjiArai 0:5b88d5760320 77 if (val) {
kenjiArai 0:5b88d5760320 78 return BD_ERROR_OK;
kenjiArai 0:5b88d5760320 79 }
kenjiArai 0:5b88d5760320 80
kenjiArai 0:5b88d5760320 81 MBED_ASSERT(_blocks != NULL);
kenjiArai 0:5b88d5760320 82 // Memory is lazily cleaned up in destructor to allow
kenjiArai 0:5b88d5760320 83 // data to live across de/reinitialization
kenjiArai 0:5b88d5760320 84 _is_initialized = false;
kenjiArai 0:5b88d5760320 85 return BD_ERROR_OK;
kenjiArai 0:5b88d5760320 86 }
kenjiArai 0:5b88d5760320 87
kenjiArai 0:5b88d5760320 88 bd_size_t HeapBlockDevice::get_read_size() const
kenjiArai 0:5b88d5760320 89 {
kenjiArai 0:5b88d5760320 90 return _read_size;
kenjiArai 0:5b88d5760320 91 }
kenjiArai 0:5b88d5760320 92
kenjiArai 0:5b88d5760320 93 bd_size_t HeapBlockDevice::get_program_size() const
kenjiArai 0:5b88d5760320 94 {
kenjiArai 0:5b88d5760320 95 return _program_size;
kenjiArai 0:5b88d5760320 96 }
kenjiArai 0:5b88d5760320 97
kenjiArai 0:5b88d5760320 98 bd_size_t HeapBlockDevice::get_erase_size() const
kenjiArai 0:5b88d5760320 99 {
kenjiArai 0:5b88d5760320 100 return _erase_size;
kenjiArai 0:5b88d5760320 101 }
kenjiArai 0:5b88d5760320 102
kenjiArai 0:5b88d5760320 103 bd_size_t HeapBlockDevice::get_erase_size(bd_addr_t addr) const
kenjiArai 0:5b88d5760320 104 {
kenjiArai 0:5b88d5760320 105 return _erase_size;
kenjiArai 0:5b88d5760320 106 }
kenjiArai 0:5b88d5760320 107
kenjiArai 0:5b88d5760320 108 bd_size_t HeapBlockDevice::size() const
kenjiArai 0:5b88d5760320 109 {
kenjiArai 0:5b88d5760320 110 return _count * _erase_size;
kenjiArai 0:5b88d5760320 111 }
kenjiArai 0:5b88d5760320 112
kenjiArai 0:5b88d5760320 113 int HeapBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
kenjiArai 0:5b88d5760320 114 {
kenjiArai 0:5b88d5760320 115 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 116 return BD_ERROR_DEVICE_ERROR;
kenjiArai 0:5b88d5760320 117 }
kenjiArai 1:9db0e321a9f4 118 if (!is_valid_read(addr, size)) {
kenjiArai 1:9db0e321a9f4 119 return BD_ERROR_DEVICE_ERROR;
kenjiArai 1:9db0e321a9f4 120 }
kenjiArai 0:5b88d5760320 121
kenjiArai 0:5b88d5760320 122 uint8_t *buffer = static_cast<uint8_t *>(b);
kenjiArai 0:5b88d5760320 123
kenjiArai 0:5b88d5760320 124 while (size > 0) {
kenjiArai 0:5b88d5760320 125 bd_addr_t hi = addr / _erase_size;
kenjiArai 0:5b88d5760320 126 bd_addr_t lo = addr % _erase_size;
kenjiArai 0:5b88d5760320 127
kenjiArai 0:5b88d5760320 128 if (_blocks[hi]) {
kenjiArai 0:5b88d5760320 129 memcpy(buffer, &_blocks[hi][lo], _read_size);
kenjiArai 0:5b88d5760320 130 } else {
kenjiArai 0:5b88d5760320 131 memset(buffer, 0, _read_size);
kenjiArai 0:5b88d5760320 132 }
kenjiArai 0:5b88d5760320 133
kenjiArai 0:5b88d5760320 134 buffer += _read_size;
kenjiArai 0:5b88d5760320 135 addr += _read_size;
kenjiArai 0:5b88d5760320 136 size -= _read_size;
kenjiArai 0:5b88d5760320 137 }
kenjiArai 0:5b88d5760320 138
kenjiArai 0:5b88d5760320 139 return 0;
kenjiArai 0:5b88d5760320 140 }
kenjiArai 0:5b88d5760320 141
kenjiArai 0:5b88d5760320 142 int HeapBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
kenjiArai 0:5b88d5760320 143 {
kenjiArai 0:5b88d5760320 144 if (!_is_initialized) {
kenjiArai 0:5b88d5760320 145 return BD_ERROR_DEVICE_ERROR;
kenjiArai 0:5b88d5760320 146 }
kenjiArai 1:9db0e321a9f4 147 if (!is_valid_program(addr, size)) {
kenjiArai 1:9db0e321a9f4 148 return BD_ERROR_DEVICE_ERROR;
kenjiArai 1:9db0e321a9f4 149 }
kenjiArai 0:5b88d5760320 150
kenjiArai 0:5b88d5760320 151 const uint8_t *buffer = static_cast<const uint8_t *>(b);
kenjiArai 0:5b88d5760320 152
kenjiArai 0:5b88d5760320 153 while (size > 0) {
kenjiArai 0:5b88d5760320 154 bd_addr_t hi = addr / _erase_size;
kenjiArai 0:5b88d5760320 155 bd_addr_t lo = addr % _erase_size;
kenjiArai 0:5b88d5760320 156
kenjiArai 0:5b88d5760320 157 if (!_blocks[hi]) {
kenjiArai 0:5b88d5760320 158 _blocks[hi] = (uint8_t *)malloc(_erase_size);
kenjiArai 0:5b88d5760320 159 if (!_blocks[hi]) {
kenjiArai 0:5b88d5760320 160 return BD_ERROR_DEVICE_ERROR;
kenjiArai 0:5b88d5760320 161 }
kenjiArai 0:5b88d5760320 162 }
kenjiArai 0:5b88d5760320 163
kenjiArai 0:5b88d5760320 164 memcpy(&_blocks[hi][lo], buffer, _program_size);
kenjiArai 0:5b88d5760320 165
kenjiArai 0:5b88d5760320 166 buffer += _program_size;
kenjiArai 0:5b88d5760320 167 addr += _program_size;
kenjiArai 0:5b88d5760320 168 size -= _program_size;
kenjiArai 0:5b88d5760320 169 }
kenjiArai 0:5b88d5760320 170
kenjiArai 0:5b88d5760320 171 return 0;
kenjiArai 0:5b88d5760320 172 }
kenjiArai 0:5b88d5760320 173
kenjiArai 0:5b88d5760320 174 int HeapBlockDevice::erase(bd_addr_t addr, bd_size_t size)
kenjiArai 0:5b88d5760320 175 {
kenjiArai 1:9db0e321a9f4 176 if (!_is_initialized) {
kenjiArai 1:9db0e321a9f4 177 return BD_ERROR_DEVICE_ERROR;
kenjiArai 1:9db0e321a9f4 178 }
kenjiArai 1:9db0e321a9f4 179 if (!is_valid_erase(addr, size)) {
kenjiArai 1:9db0e321a9f4 180 return BD_ERROR_DEVICE_ERROR;
kenjiArai 1:9db0e321a9f4 181 }
kenjiArai 0:5b88d5760320 182 return 0;
kenjiArai 0:5b88d5760320 183 }
kenjiArai 0:5b88d5760320 184
kenjiArai 0:5b88d5760320 185 const char *HeapBlockDevice::get_type() const
kenjiArai 0:5b88d5760320 186 {
kenjiArai 0:5b88d5760320 187 return "HEAP";
kenjiArai 0:5b88d5760320 188 }
kenjiArai 0:5b88d5760320 189
kenjiArai 0:5b88d5760320 190 } // namespace mbed