Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FlashIAP.cpp Source File

FlashIAP.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017 ARM Limited
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, including without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00020  * SOFTWARE.
00021  */
00022 
00023 #include <string.h>
00024 #include "FlashIAP.h"
00025 #include "mbed_assert.h"
00026 
00027 
00028 #ifdef DEVICE_FLASH
00029 
00030 namespace mbed {
00031 
00032 SingletonPtr<PlatformMutex>  FlashIAP::_mutex;
00033 
00034 static inline bool is_aligned(uint32_t number, uint32_t alignment)
00035 {
00036     if ((number % alignment) != 0) {
00037         return false;
00038     } else {
00039         return true;
00040     }
00041 }
00042 
00043 FlashIAP::FlashIAP()
00044 {
00045 
00046 }
00047 
00048 FlashIAP::~FlashIAP()
00049 {
00050 
00051 }
00052 
00053 int FlashIAP::init()
00054 {
00055     int ret = 0;
00056     _mutex->lock();
00057     if (flash_init(&_flash)) {
00058         ret = -1; 
00059     }
00060     _mutex->unlock();
00061     return ret;
00062 }
00063 
00064 int FlashIAP::deinit()
00065 {
00066     int ret = 0;
00067     _mutex->lock();
00068     if (flash_free(&_flash)) {
00069         ret = -1; 
00070     }
00071     _mutex->unlock();
00072     return ret;
00073 }
00074 
00075 
00076 int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size)
00077 {
00078     _mutex->lock();
00079     memcpy(buffer, (const void *)addr, size);
00080     _mutex->unlock();
00081     return 0;
00082 }
00083 
00084 int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size)
00085 {
00086     uint32_t page_size = get_page_size();
00087     uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
00088     // addr and size should be aligned to page size, and multiple of page size
00089     // page program should not cross sector boundaries
00090     if (!is_aligned(addr, page_size) ||
00091         !is_aligned(size, page_size) ||
00092         (size < page_size) ||
00093         (((addr % current_sector_size) + size) > current_sector_size)) {
00094         return -1;
00095     }
00096 
00097     int ret = 0;
00098     _mutex->lock();
00099     if (flash_program_page(&_flash, addr, (const uint8_t *)buffer, size)) {
00100         ret = -1;
00101     }
00102     _mutex->unlock();
00103     return ret;
00104 }
00105 
00106 bool FlashIAP::is_aligned_to_sector(uint32_t addr, uint32_t size)
00107 {
00108     uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
00109     if (!is_aligned(size, current_sector_size) ||
00110         !is_aligned(addr, current_sector_size)) {
00111         return false;
00112     } else {
00113         return true;
00114     }
00115 }
00116 
00117 int FlashIAP::erase(uint32_t addr, uint32_t size)
00118 {
00119     uint32_t current_sector_size = 0UL;
00120 
00121     if (!is_aligned_to_sector(addr, size)) {
00122         return -1;
00123     }
00124 
00125     int32_t ret = 0;
00126     _mutex->lock();
00127     while (size) {
00128         ret = flash_erase_sector(&_flash, addr);
00129         if (ret != 0) {
00130             ret = -1;
00131             break;
00132         }
00133         current_sector_size = flash_get_sector_size(&_flash, addr);
00134         if (!is_aligned_to_sector(addr, size)) {
00135             ret = -1;
00136             break;
00137         }
00138         size -= current_sector_size;
00139         addr += current_sector_size;
00140     }
00141     _mutex->unlock();
00142     return ret;
00143 }
00144 
00145 uint32_t FlashIAP::get_page_size() const
00146 {
00147     return flash_get_page_size(&_flash);
00148 }
00149 
00150 uint32_t FlashIAP::get_sector_size(uint32_t addr) const
00151 {
00152     return flash_get_sector_size(&_flash, addr);
00153 }
00154 
00155 uint32_t FlashIAP::get_flash_start() const
00156 {
00157     return flash_get_start_address(&_flash);
00158 }
00159 
00160 uint32_t FlashIAP::get_flash_size() const
00161 {
00162     return flash_get_size(&_flash);
00163 }
00164 
00165 }
00166 
00167 #endif