Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

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