Rahul Dahiya / Mbed OS STM32F7 Ethernet
Committer:
rahul_dahiya
Date:
Wed Jan 15 15:57:15 2020 +0530
Revision:
0:fb8047b156bb
STM32F7 LWIP

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rahul_dahiya 0:fb8047b156bb 1 /* mbed Microcontroller Library
rahul_dahiya 0:fb8047b156bb 2 * Copyright (c) 2017 ARM Limited
rahul_dahiya 0:fb8047b156bb 3 *
rahul_dahiya 0:fb8047b156bb 4 * Licensed under the Apache License, Version 2.0 (the "License");
rahul_dahiya 0:fb8047b156bb 5 * you may not use this file except in compliance with the License.
rahul_dahiya 0:fb8047b156bb 6 * You may obtain a copy of the License at
rahul_dahiya 0:fb8047b156bb 7 *
rahul_dahiya 0:fb8047b156bb 8 * http://www.apache.org/licenses/LICENSE-2.0
rahul_dahiya 0:fb8047b156bb 9 *
rahul_dahiya 0:fb8047b156bb 10 * Unless required by applicable law or agreed to in writing, software
rahul_dahiya 0:fb8047b156bb 11 * distributed under the License is distributed on an "AS IS" BASIS,
rahul_dahiya 0:fb8047b156bb 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rahul_dahiya 0:fb8047b156bb 13 * See the License for the specific language governing permissions and
rahul_dahiya 0:fb8047b156bb 14 * limitations under the License.
rahul_dahiya 0:fb8047b156bb 15 */
rahul_dahiya 0:fb8047b156bb 16
rahul_dahiya 0:fb8047b156bb 17 #include "ChainingBlockDevice.h"
rahul_dahiya 0:fb8047b156bb 18
rahul_dahiya 0:fb8047b156bb 19
rahul_dahiya 0:fb8047b156bb 20 ChainingBlockDevice::ChainingBlockDevice(BlockDevice **bds, size_t bd_count)
rahul_dahiya 0:fb8047b156bb 21 : _bds(bds), _bd_count(bd_count)
rahul_dahiya 0:fb8047b156bb 22 , _read_size(0), _program_size(0), _erase_size(0), _size(0)
rahul_dahiya 0:fb8047b156bb 23 {
rahul_dahiya 0:fb8047b156bb 24 }
rahul_dahiya 0:fb8047b156bb 25
rahul_dahiya 0:fb8047b156bb 26 static bool is_aligned(uint64_t x, uint64_t alignment)
rahul_dahiya 0:fb8047b156bb 27 {
rahul_dahiya 0:fb8047b156bb 28 return (x / alignment) * alignment == x;
rahul_dahiya 0:fb8047b156bb 29 }
rahul_dahiya 0:fb8047b156bb 30
rahul_dahiya 0:fb8047b156bb 31 int ChainingBlockDevice::init()
rahul_dahiya 0:fb8047b156bb 32 {
rahul_dahiya 0:fb8047b156bb 33 _read_size = 0;
rahul_dahiya 0:fb8047b156bb 34 _program_size = 0;
rahul_dahiya 0:fb8047b156bb 35 _erase_size = 0;
rahul_dahiya 0:fb8047b156bb 36 _size = 0;
rahul_dahiya 0:fb8047b156bb 37
rahul_dahiya 0:fb8047b156bb 38 // Initialize children block devices, find all sizes and
rahul_dahiya 0:fb8047b156bb 39 // assert that block sizes are similar. We can't do this in
rahul_dahiya 0:fb8047b156bb 40 // the constructor since some block devices may need to be
rahul_dahiya 0:fb8047b156bb 41 // initialized before they know their block size/count
rahul_dahiya 0:fb8047b156bb 42 for (size_t i = 0; i < _bd_count; i++) {
rahul_dahiya 0:fb8047b156bb 43 int err = _bds[i]->init();
rahul_dahiya 0:fb8047b156bb 44 if (err) {
rahul_dahiya 0:fb8047b156bb 45 return err;
rahul_dahiya 0:fb8047b156bb 46 }
rahul_dahiya 0:fb8047b156bb 47
rahul_dahiya 0:fb8047b156bb 48 bd_size_t read = _bds[i]->get_read_size();
rahul_dahiya 0:fb8047b156bb 49 if (i == 0 || (read >= _read_size && is_aligned(read, _read_size))) {
rahul_dahiya 0:fb8047b156bb 50 _read_size = read;
rahul_dahiya 0:fb8047b156bb 51 } else {
rahul_dahiya 0:fb8047b156bb 52 MBED_ASSERT(_read_size > read && is_aligned(_read_size, read));
rahul_dahiya 0:fb8047b156bb 53 }
rahul_dahiya 0:fb8047b156bb 54
rahul_dahiya 0:fb8047b156bb 55 bd_size_t program = _bds[i]->get_program_size();
rahul_dahiya 0:fb8047b156bb 56 if (i == 0 || (program >= _program_size && is_aligned(program, _program_size))) {
rahul_dahiya 0:fb8047b156bb 57 _program_size = program;
rahul_dahiya 0:fb8047b156bb 58 } else {
rahul_dahiya 0:fb8047b156bb 59 MBED_ASSERT(_program_size > program && is_aligned(_program_size, program));
rahul_dahiya 0:fb8047b156bb 60 }
rahul_dahiya 0:fb8047b156bb 61
rahul_dahiya 0:fb8047b156bb 62 bd_size_t erase = _bds[i]->get_erase_size();
rahul_dahiya 0:fb8047b156bb 63 if (i == 0 || (erase >= _erase_size && is_aligned(erase, _erase_size))) {
rahul_dahiya 0:fb8047b156bb 64 _erase_size = erase;
rahul_dahiya 0:fb8047b156bb 65 } else {
rahul_dahiya 0:fb8047b156bb 66 MBED_ASSERT(_erase_size > erase && is_aligned(_erase_size, erase));
rahul_dahiya 0:fb8047b156bb 67 }
rahul_dahiya 0:fb8047b156bb 68
rahul_dahiya 0:fb8047b156bb 69 _size += _bds[i]->size();
rahul_dahiya 0:fb8047b156bb 70 }
rahul_dahiya 0:fb8047b156bb 71
rahul_dahiya 0:fb8047b156bb 72 return 0;
rahul_dahiya 0:fb8047b156bb 73 }
rahul_dahiya 0:fb8047b156bb 74
rahul_dahiya 0:fb8047b156bb 75 int ChainingBlockDevice::deinit()
rahul_dahiya 0:fb8047b156bb 76 {
rahul_dahiya 0:fb8047b156bb 77 for (size_t i = 0; i < _bd_count; i++) {
rahul_dahiya 0:fb8047b156bb 78 int err = _bds[i]->deinit();
rahul_dahiya 0:fb8047b156bb 79 if (err) {
rahul_dahiya 0:fb8047b156bb 80 return err;
rahul_dahiya 0:fb8047b156bb 81 }
rahul_dahiya 0:fb8047b156bb 82 }
rahul_dahiya 0:fb8047b156bb 83
rahul_dahiya 0:fb8047b156bb 84 return 0;
rahul_dahiya 0:fb8047b156bb 85 }
rahul_dahiya 0:fb8047b156bb 86
rahul_dahiya 0:fb8047b156bb 87 int ChainingBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
rahul_dahiya 0:fb8047b156bb 88 {
rahul_dahiya 0:fb8047b156bb 89 MBED_ASSERT(is_valid_read(addr, size));
rahul_dahiya 0:fb8047b156bb 90 uint8_t *buffer = static_cast<uint8_t*>(b);
rahul_dahiya 0:fb8047b156bb 91
rahul_dahiya 0:fb8047b156bb 92 // Find block devices containing blocks, may span multiple block devices
rahul_dahiya 0:fb8047b156bb 93 for (size_t i = 0; i < _bd_count && size > 0; i++) {
rahul_dahiya 0:fb8047b156bb 94 bd_size_t bdsize = _bds[i]->size();
rahul_dahiya 0:fb8047b156bb 95
rahul_dahiya 0:fb8047b156bb 96 if (addr < bdsize) {
rahul_dahiya 0:fb8047b156bb 97 bd_size_t read = size;
rahul_dahiya 0:fb8047b156bb 98 if (addr + read > bdsize) {
rahul_dahiya 0:fb8047b156bb 99 read = bdsize - addr;
rahul_dahiya 0:fb8047b156bb 100 }
rahul_dahiya 0:fb8047b156bb 101
rahul_dahiya 0:fb8047b156bb 102 int err = _bds[i]->read(buffer, addr, read);
rahul_dahiya 0:fb8047b156bb 103 if (err) {
rahul_dahiya 0:fb8047b156bb 104 return err;
rahul_dahiya 0:fb8047b156bb 105 }
rahul_dahiya 0:fb8047b156bb 106
rahul_dahiya 0:fb8047b156bb 107 buffer += read;
rahul_dahiya 0:fb8047b156bb 108 addr += read;
rahul_dahiya 0:fb8047b156bb 109 size -= read;
rahul_dahiya 0:fb8047b156bb 110 }
rahul_dahiya 0:fb8047b156bb 111
rahul_dahiya 0:fb8047b156bb 112 addr -= bdsize;
rahul_dahiya 0:fb8047b156bb 113 }
rahul_dahiya 0:fb8047b156bb 114
rahul_dahiya 0:fb8047b156bb 115 return 0;
rahul_dahiya 0:fb8047b156bb 116 }
rahul_dahiya 0:fb8047b156bb 117
rahul_dahiya 0:fb8047b156bb 118 int ChainingBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
rahul_dahiya 0:fb8047b156bb 119 {
rahul_dahiya 0:fb8047b156bb 120 MBED_ASSERT(is_valid_program(addr, size));
rahul_dahiya 0:fb8047b156bb 121 const uint8_t *buffer = static_cast<const uint8_t*>(b);
rahul_dahiya 0:fb8047b156bb 122
rahul_dahiya 0:fb8047b156bb 123 // Find block devices containing blocks, may span multiple block devices
rahul_dahiya 0:fb8047b156bb 124 for (size_t i = 0; i < _bd_count && size > 0; i++) {
rahul_dahiya 0:fb8047b156bb 125 bd_size_t bdsize = _bds[i]->size();
rahul_dahiya 0:fb8047b156bb 126
rahul_dahiya 0:fb8047b156bb 127 if (addr < bdsize) {
rahul_dahiya 0:fb8047b156bb 128 bd_size_t program = size;
rahul_dahiya 0:fb8047b156bb 129 if (addr + program > bdsize) {
rahul_dahiya 0:fb8047b156bb 130 program = bdsize - addr;
rahul_dahiya 0:fb8047b156bb 131 }
rahul_dahiya 0:fb8047b156bb 132
rahul_dahiya 0:fb8047b156bb 133 int err = _bds[i]->program(buffer, addr, program);
rahul_dahiya 0:fb8047b156bb 134 if (err) {
rahul_dahiya 0:fb8047b156bb 135 return err;
rahul_dahiya 0:fb8047b156bb 136 }
rahul_dahiya 0:fb8047b156bb 137
rahul_dahiya 0:fb8047b156bb 138 buffer += program;
rahul_dahiya 0:fb8047b156bb 139 addr += program;
rahul_dahiya 0:fb8047b156bb 140 size -= program;
rahul_dahiya 0:fb8047b156bb 141 }
rahul_dahiya 0:fb8047b156bb 142
rahul_dahiya 0:fb8047b156bb 143 addr -= bdsize;
rahul_dahiya 0:fb8047b156bb 144 }
rahul_dahiya 0:fb8047b156bb 145
rahul_dahiya 0:fb8047b156bb 146 return 0;
rahul_dahiya 0:fb8047b156bb 147 }
rahul_dahiya 0:fb8047b156bb 148
rahul_dahiya 0:fb8047b156bb 149 int ChainingBlockDevice::erase(bd_addr_t addr, bd_size_t size)
rahul_dahiya 0:fb8047b156bb 150 {
rahul_dahiya 0:fb8047b156bb 151 MBED_ASSERT(is_valid_erase(addr, size));
rahul_dahiya 0:fb8047b156bb 152
rahul_dahiya 0:fb8047b156bb 153 // Find block devices containing blocks, may span multiple block devices
rahul_dahiya 0:fb8047b156bb 154 for (size_t i = 0; i < _bd_count && size > 0; i++) {
rahul_dahiya 0:fb8047b156bb 155 bd_size_t bdsize = _bds[i]->size();
rahul_dahiya 0:fb8047b156bb 156
rahul_dahiya 0:fb8047b156bb 157 if (addr < bdsize) {
rahul_dahiya 0:fb8047b156bb 158 bd_size_t erase = size;
rahul_dahiya 0:fb8047b156bb 159 if (addr + erase > bdsize) {
rahul_dahiya 0:fb8047b156bb 160 erase = bdsize - addr;
rahul_dahiya 0:fb8047b156bb 161 }
rahul_dahiya 0:fb8047b156bb 162
rahul_dahiya 0:fb8047b156bb 163 int err = _bds[i]->erase(addr, erase);
rahul_dahiya 0:fb8047b156bb 164 if (err) {
rahul_dahiya 0:fb8047b156bb 165 return err;
rahul_dahiya 0:fb8047b156bb 166 }
rahul_dahiya 0:fb8047b156bb 167
rahul_dahiya 0:fb8047b156bb 168 addr += erase;
rahul_dahiya 0:fb8047b156bb 169 size -= erase;
rahul_dahiya 0:fb8047b156bb 170 }
rahul_dahiya 0:fb8047b156bb 171
rahul_dahiya 0:fb8047b156bb 172 addr -= bdsize;
rahul_dahiya 0:fb8047b156bb 173 }
rahul_dahiya 0:fb8047b156bb 174
rahul_dahiya 0:fb8047b156bb 175 return 0;
rahul_dahiya 0:fb8047b156bb 176 }
rahul_dahiya 0:fb8047b156bb 177
rahul_dahiya 0:fb8047b156bb 178 bd_size_t ChainingBlockDevice::get_read_size() const
rahul_dahiya 0:fb8047b156bb 179 {
rahul_dahiya 0:fb8047b156bb 180 return _read_size;
rahul_dahiya 0:fb8047b156bb 181 }
rahul_dahiya 0:fb8047b156bb 182
rahul_dahiya 0:fb8047b156bb 183 bd_size_t ChainingBlockDevice::get_program_size() const
rahul_dahiya 0:fb8047b156bb 184 {
rahul_dahiya 0:fb8047b156bb 185 return _program_size;
rahul_dahiya 0:fb8047b156bb 186 }
rahul_dahiya 0:fb8047b156bb 187
rahul_dahiya 0:fb8047b156bb 188 bd_size_t ChainingBlockDevice::get_erase_size() const
rahul_dahiya 0:fb8047b156bb 189 {
rahul_dahiya 0:fb8047b156bb 190 return _erase_size;
rahul_dahiya 0:fb8047b156bb 191 }
rahul_dahiya 0:fb8047b156bb 192
rahul_dahiya 0:fb8047b156bb 193 bd_size_t ChainingBlockDevice::size() const
rahul_dahiya 0:fb8047b156bb 194 {
rahul_dahiya 0:fb8047b156bb 195 return _size;
rahul_dahiya 0:fb8047b156bb 196 }