inport from local

Dependents:   Hobbyking_Cheetah_0511

Committer:
NYX
Date:
Mon Mar 16 06:35:48 2020 +0000
Revision:
0:85b3fd62ea1a
reinport to mbed;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
NYX 0:85b3fd62ea1a 1 /* mbed Microcontroller Library
NYX 0:85b3fd62ea1a 2 * Copyright (c) 2017 ARM Limited
NYX 0:85b3fd62ea1a 3 *
NYX 0:85b3fd62ea1a 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
NYX 0:85b3fd62ea1a 5 * of this software and associated documentation files (the "Software"), to deal
NYX 0:85b3fd62ea1a 6 * in the Software without restriction, including without limitation the rights
NYX 0:85b3fd62ea1a 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
NYX 0:85b3fd62ea1a 8 * copies of the Software, and to permit persons to whom the Software is
NYX 0:85b3fd62ea1a 9 * furnished to do so, subject to the following conditions:
NYX 0:85b3fd62ea1a 10 *
NYX 0:85b3fd62ea1a 11 * The above copyright notice and this permission notice shall be included in
NYX 0:85b3fd62ea1a 12 * all copies or substantial portions of the Software.
NYX 0:85b3fd62ea1a 13 *
NYX 0:85b3fd62ea1a 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
NYX 0:85b3fd62ea1a 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
NYX 0:85b3fd62ea1a 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
NYX 0:85b3fd62ea1a 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
NYX 0:85b3fd62ea1a 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
NYX 0:85b3fd62ea1a 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
NYX 0:85b3fd62ea1a 20 * SOFTWARE.
NYX 0:85b3fd62ea1a 21 */
NYX 0:85b3fd62ea1a 22
NYX 0:85b3fd62ea1a 23 #include <string.h>
NYX 0:85b3fd62ea1a 24 #include "FlashIAP.h"
NYX 0:85b3fd62ea1a 25 #include "mbed_assert.h"
NYX 0:85b3fd62ea1a 26
NYX 0:85b3fd62ea1a 27
NYX 0:85b3fd62ea1a 28 #ifdef DEVICE_FLASH
NYX 0:85b3fd62ea1a 29
NYX 0:85b3fd62ea1a 30 namespace mbed {
NYX 0:85b3fd62ea1a 31
NYX 0:85b3fd62ea1a 32 SingletonPtr<PlatformMutex> FlashIAP::_mutex;
NYX 0:85b3fd62ea1a 33
NYX 0:85b3fd62ea1a 34 static inline bool is_aligned(uint32_t number, uint32_t alignment)
NYX 0:85b3fd62ea1a 35 {
NYX 0:85b3fd62ea1a 36 if ((number % alignment) != 0) {
NYX 0:85b3fd62ea1a 37 return false;
NYX 0:85b3fd62ea1a 38 } else {
NYX 0:85b3fd62ea1a 39 return true;
NYX 0:85b3fd62ea1a 40 }
NYX 0:85b3fd62ea1a 41 }
NYX 0:85b3fd62ea1a 42
NYX 0:85b3fd62ea1a 43 FlashIAP::FlashIAP()
NYX 0:85b3fd62ea1a 44 {
NYX 0:85b3fd62ea1a 45
NYX 0:85b3fd62ea1a 46 }
NYX 0:85b3fd62ea1a 47
NYX 0:85b3fd62ea1a 48 FlashIAP::~FlashIAP()
NYX 0:85b3fd62ea1a 49 {
NYX 0:85b3fd62ea1a 50
NYX 0:85b3fd62ea1a 51 }
NYX 0:85b3fd62ea1a 52
NYX 0:85b3fd62ea1a 53 int FlashIAP::init()
NYX 0:85b3fd62ea1a 54 {
NYX 0:85b3fd62ea1a 55 int ret = 0;
NYX 0:85b3fd62ea1a 56 _mutex->lock();
NYX 0:85b3fd62ea1a 57 if (flash_init(&_flash)) {
NYX 0:85b3fd62ea1a 58 ret = -1;
NYX 0:85b3fd62ea1a 59 }
NYX 0:85b3fd62ea1a 60 _mutex->unlock();
NYX 0:85b3fd62ea1a 61 return ret;
NYX 0:85b3fd62ea1a 62 }
NYX 0:85b3fd62ea1a 63
NYX 0:85b3fd62ea1a 64 int FlashIAP::deinit()
NYX 0:85b3fd62ea1a 65 {
NYX 0:85b3fd62ea1a 66 int ret = 0;
NYX 0:85b3fd62ea1a 67 _mutex->lock();
NYX 0:85b3fd62ea1a 68 if (flash_free(&_flash)) {
NYX 0:85b3fd62ea1a 69 ret = -1;
NYX 0:85b3fd62ea1a 70 }
NYX 0:85b3fd62ea1a 71 _mutex->unlock();
NYX 0:85b3fd62ea1a 72 return ret;
NYX 0:85b3fd62ea1a 73 }
NYX 0:85b3fd62ea1a 74
NYX 0:85b3fd62ea1a 75
NYX 0:85b3fd62ea1a 76 int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size)
NYX 0:85b3fd62ea1a 77 {
NYX 0:85b3fd62ea1a 78 int32_t ret = -1;
NYX 0:85b3fd62ea1a 79 _mutex->lock();
NYX 0:85b3fd62ea1a 80 ret = flash_read(&_flash, addr, (uint8_t *) buffer, size);
NYX 0:85b3fd62ea1a 81 _mutex->unlock();
NYX 0:85b3fd62ea1a 82 return ret;
NYX 0:85b3fd62ea1a 83 }
NYX 0:85b3fd62ea1a 84
NYX 0:85b3fd62ea1a 85 int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size)
NYX 0:85b3fd62ea1a 86 {
NYX 0:85b3fd62ea1a 87 uint32_t page_size = get_page_size();
NYX 0:85b3fd62ea1a 88 uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
NYX 0:85b3fd62ea1a 89 // addr and size should be aligned to page size, and multiple of page size
NYX 0:85b3fd62ea1a 90 // page program should not cross sector boundaries
NYX 0:85b3fd62ea1a 91 if (!is_aligned(addr, page_size) ||
NYX 0:85b3fd62ea1a 92 !is_aligned(size, page_size) ||
NYX 0:85b3fd62ea1a 93 (size < page_size) ||
NYX 0:85b3fd62ea1a 94 (((addr % current_sector_size) + size) > current_sector_size)) {
NYX 0:85b3fd62ea1a 95 return -1;
NYX 0:85b3fd62ea1a 96 }
NYX 0:85b3fd62ea1a 97
NYX 0:85b3fd62ea1a 98 int ret = 0;
NYX 0:85b3fd62ea1a 99 _mutex->lock();
NYX 0:85b3fd62ea1a 100 if (flash_program_page(&_flash, addr, (const uint8_t *)buffer, size)) {
NYX 0:85b3fd62ea1a 101 ret = -1;
NYX 0:85b3fd62ea1a 102 }
NYX 0:85b3fd62ea1a 103 _mutex->unlock();
NYX 0:85b3fd62ea1a 104 return ret;
NYX 0:85b3fd62ea1a 105 }
NYX 0:85b3fd62ea1a 106
NYX 0:85b3fd62ea1a 107 bool FlashIAP::is_aligned_to_sector(uint32_t addr, uint32_t size)
NYX 0:85b3fd62ea1a 108 {
NYX 0:85b3fd62ea1a 109 uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
NYX 0:85b3fd62ea1a 110 if (!is_aligned(size, current_sector_size) ||
NYX 0:85b3fd62ea1a 111 !is_aligned(addr, current_sector_size)) {
NYX 0:85b3fd62ea1a 112 return false;
NYX 0:85b3fd62ea1a 113 } else {
NYX 0:85b3fd62ea1a 114 return true;
NYX 0:85b3fd62ea1a 115 }
NYX 0:85b3fd62ea1a 116 }
NYX 0:85b3fd62ea1a 117
NYX 0:85b3fd62ea1a 118 int FlashIAP::erase(uint32_t addr, uint32_t size)
NYX 0:85b3fd62ea1a 119 {
NYX 0:85b3fd62ea1a 120 uint32_t current_sector_size = 0UL;
NYX 0:85b3fd62ea1a 121
NYX 0:85b3fd62ea1a 122 if (!is_aligned_to_sector(addr, size)) {
NYX 0:85b3fd62ea1a 123 return -1;
NYX 0:85b3fd62ea1a 124 }
NYX 0:85b3fd62ea1a 125
NYX 0:85b3fd62ea1a 126 int32_t ret = 0;
NYX 0:85b3fd62ea1a 127 _mutex->lock();
NYX 0:85b3fd62ea1a 128 while (size) {
NYX 0:85b3fd62ea1a 129 ret = flash_erase_sector(&_flash, addr);
NYX 0:85b3fd62ea1a 130 if (ret != 0) {
NYX 0:85b3fd62ea1a 131 ret = -1;
NYX 0:85b3fd62ea1a 132 break;
NYX 0:85b3fd62ea1a 133 }
NYX 0:85b3fd62ea1a 134 current_sector_size = flash_get_sector_size(&_flash, addr);
NYX 0:85b3fd62ea1a 135 if (!is_aligned_to_sector(addr, size)) {
NYX 0:85b3fd62ea1a 136 ret = -1;
NYX 0:85b3fd62ea1a 137 break;
NYX 0:85b3fd62ea1a 138 }
NYX 0:85b3fd62ea1a 139 size -= current_sector_size;
NYX 0:85b3fd62ea1a 140 addr += current_sector_size;
NYX 0:85b3fd62ea1a 141 }
NYX 0:85b3fd62ea1a 142 _mutex->unlock();
NYX 0:85b3fd62ea1a 143 return ret;
NYX 0:85b3fd62ea1a 144 }
NYX 0:85b3fd62ea1a 145
NYX 0:85b3fd62ea1a 146 uint32_t FlashIAP::get_page_size() const
NYX 0:85b3fd62ea1a 147 {
NYX 0:85b3fd62ea1a 148 return flash_get_page_size(&_flash);
NYX 0:85b3fd62ea1a 149 }
NYX 0:85b3fd62ea1a 150
NYX 0:85b3fd62ea1a 151 uint32_t FlashIAP::get_sector_size(uint32_t addr) const
NYX 0:85b3fd62ea1a 152 {
NYX 0:85b3fd62ea1a 153 return flash_get_sector_size(&_flash, addr);
NYX 0:85b3fd62ea1a 154 }
NYX 0:85b3fd62ea1a 155
NYX 0:85b3fd62ea1a 156 uint32_t FlashIAP::get_flash_start() const
NYX 0:85b3fd62ea1a 157 {
NYX 0:85b3fd62ea1a 158 return flash_get_start_address(&_flash);
NYX 0:85b3fd62ea1a 159 }
NYX 0:85b3fd62ea1a 160
NYX 0:85b3fd62ea1a 161 uint32_t FlashIAP::get_flash_size() const
NYX 0:85b3fd62ea1a 162 {
NYX 0:85b3fd62ea1a 163 return flash_get_size(&_flash);
NYX 0:85b3fd62ea1a 164 }
NYX 0:85b3fd62ea1a 165
NYX 0:85b3fd62ea1a 166 }
NYX 0:85b3fd62ea1a 167
NYX 0:85b3fd62ea1a 168 #endif