SD + Bitmap

Dependencies:   TS_DISCO_F746NG LCD_DISCO_F746NG BSP_DISCO_F746NG

Committer:
iut_cachan01
Date:
Tue May 21 10:24:03 2019 +0000
Revision:
0:14e97aa401f3
SD + Bitmap

Who changed what in which revision?

UserRevisionLine numberNew contents of line
iut_cachan01 0:14e97aa401f3 1 /* SD/MMC Block device Library for MBED-OS
iut_cachan01 0:14e97aa401f3 2 * Copyright 2017 Roy Krikke
iut_cachan01 0:14e97aa401f3 3 *
iut_cachan01 0:14e97aa401f3 4 * Licensed under the Apache License, Version 2.0 (the "License");
iut_cachan01 0:14e97aa401f3 5 * you may not use this file except in compliance with the License.
iut_cachan01 0:14e97aa401f3 6 * You may obtain a copy of the License at
iut_cachan01 0:14e97aa401f3 7 *
iut_cachan01 0:14e97aa401f3 8 * http://www.apache.org/licenses/LICENSE-2.0
iut_cachan01 0:14e97aa401f3 9 *
iut_cachan01 0:14e97aa401f3 10 * Unless required by applicable law or agreed to in writing, software
iut_cachan01 0:14e97aa401f3 11 * distributed under the License is distributed on an "AS IS" BASIS,
iut_cachan01 0:14e97aa401f3 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
iut_cachan01 0:14e97aa401f3 13 * See the License for the specific language governing permissions and
iut_cachan01 0:14e97aa401f3 14 * limitations under the License.
iut_cachan01 0:14e97aa401f3 15 *
iut_cachan01 0:14e97aa401f3 16 */
iut_cachan01 0:14e97aa401f3 17
iut_cachan01 0:14e97aa401f3 18 #include "sd_bd_disco.h"
iut_cachan01 0:14e97aa401f3 19 #include "mbed_debug.h"
iut_cachan01 0:14e97aa401f3 20
iut_cachan01 0:14e97aa401f3 21 /* Required version: 5.5.0 and above */
iut_cachan01 0:14e97aa401f3 22 #if defined(MBED_MAJOR_VERSION) && MBED_MAJOR_VERSION >= 5
iut_cachan01 0:14e97aa401f3 23 #if (MBED_VERSION < MBED_ENCODE_VERSION(5,5,0))
iut_cachan01 0:14e97aa401f3 24 #error "Incompatible mbed-os version detected! Required 5.5.0 and above"
iut_cachan01 0:14e97aa401f3 25 #endif
iut_cachan01 0:14e97aa401f3 26 #else
iut_cachan01 0:14e97aa401f3 27 #warning "mbed-os version 5.5.0 or above required"
iut_cachan01 0:14e97aa401f3 28 #endif
iut_cachan01 0:14e97aa401f3 29
iut_cachan01 0:14e97aa401f3 30 /* Required version: 5.5.0 and above */
iut_cachan01 0:14e97aa401f3 31 #warning "Block device class BD_SD_DISCO_F746NG is depending on BSP_DISCO_F746NG libary (Revision 9:df2ea349c37a with date 06 Jul 2017)"
iut_cachan01 0:14e97aa401f3 32
iut_cachan01 0:14e97aa401f3 33 #define SD_DBG 0 /*!< 1 - Enable debugging */
iut_cachan01 0:14e97aa401f3 34
iut_cachan01 0:14e97aa401f3 35 /** Enum of standard error codes
iut_cachan01 0:14e97aa401f3 36 *
iut_cachan01 0:14e97aa401f3 37 * @enum bd_sd_error
iut_cachan01 0:14e97aa401f3 38 */
iut_cachan01 0:14e97aa401f3 39 enum bd_sd_error {
iut_cachan01 0:14e97aa401f3 40 SD_BLOCK_DEVICE_OK = 0, /*!< no error */
iut_cachan01 0:14e97aa401f3 41 SD_BLOCK_DEVICE_ERROR = -5000, /*!< device specific error */
iut_cachan01 0:14e97aa401f3 42 //SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK = -5001, /*!< operation would block */
iut_cachan01 0:14e97aa401f3 43 //SD_BLOCK_DEVICE_ERROR_UNSUPPORTED = -5002, /*!< unsupported operation */
iut_cachan01 0:14e97aa401f3 44 SD_BLOCK_DEVICE_ERROR_PARAMETER = -5003, /*!< invalid parameter */
iut_cachan01 0:14e97aa401f3 45 SD_BLOCK_DEVICE_ERROR_NO_INIT = -5004, /*!< uninitialized */
iut_cachan01 0:14e97aa401f3 46 SD_BLOCK_DEVICE_ERROR_NO_DEVICE = -5005, /*!< device is missing or not connected */
iut_cachan01 0:14e97aa401f3 47 //SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED = -5006, /*!< write protected */
iut_cachan01 0:14e97aa401f3 48 //SD_BLOCK_DEVICE_ERROR_UNUSABLE = -5007, /*!< unusable card */
iut_cachan01 0:14e97aa401f3 49 //SD_BLOCK_DEVICE_ERROR_NO_RESPONSE = -5008, /*!< No response from device */
iut_cachan01 0:14e97aa401f3 50 //SD_BLOCK_DEVICE_ERROR_CRC = -5009, /*!< CRC error */
iut_cachan01 0:14e97aa401f3 51 SD_BLOCK_DEVICE_ERROR_ERASE = -5010, /*!< Erase error */
iut_cachan01 0:14e97aa401f3 52 SD_BLOCK_DEVICE_ERROR_READ = -5011, /*!< Read error */
iut_cachan01 0:14e97aa401f3 53 SD_BLOCK_DEVICE_ERROR_PROGRAM = -5012, /*!< Program error */
iut_cachan01 0:14e97aa401f3 54 };
iut_cachan01 0:14e97aa401f3 55
iut_cachan01 0:14e97aa401f3 56 #define BLOCK_SIZE_HC 512 /*!< Block size supported for SD card is 512 bytes */
iut_cachan01 0:14e97aa401f3 57
iut_cachan01 0:14e97aa401f3 58 SDBlockDeviceDISCOF746NG::SDBlockDeviceDISCOF746NG() :
iut_cachan01 0:14e97aa401f3 59 _read_size (BLOCK_SIZE_HC), _program_size (BLOCK_SIZE_HC),
iut_cachan01 0:14e97aa401f3 60 _erase_size(BLOCK_SIZE_HC), _block_size (BLOCK_SIZE_HC),
iut_cachan01 0:14e97aa401f3 61 _capacity_in_blocks (0)
iut_cachan01 0:14e97aa401f3 62 {
iut_cachan01 0:14e97aa401f3 63 _timeout = 1000;
iut_cachan01 0:14e97aa401f3 64 }
iut_cachan01 0:14e97aa401f3 65
iut_cachan01 0:14e97aa401f3 66 SDBlockDeviceDISCOF746NG::~SDBlockDeviceDISCOF746NG()
iut_cachan01 0:14e97aa401f3 67 {
iut_cachan01 0:14e97aa401f3 68 if(_is_initialized) {
iut_cachan01 0:14e97aa401f3 69 deinit ();
iut_cachan01 0:14e97aa401f3 70 }
iut_cachan01 0:14e97aa401f3 71 }
iut_cachan01 0:14e97aa401f3 72
iut_cachan01 0:14e97aa401f3 73 int SDBlockDeviceDISCOF746NG::init()
iut_cachan01 0:14e97aa401f3 74 {
iut_cachan01 0:14e97aa401f3 75 lock();
iut_cachan01 0:14e97aa401f3 76 _sd_state = BSP_SD_Init();
iut_cachan01 0:14e97aa401f3 77
iut_cachan01 0:14e97aa401f3 78 if(_sd_state != MSD_OK) {
iut_cachan01 0:14e97aa401f3 79 if(_sd_state == MSD_ERROR_SD_NOT_PRESENT) {
iut_cachan01 0:14e97aa401f3 80 debug_if(SD_DBG, "SD card is missing or not connected\n");
iut_cachan01 0:14e97aa401f3 81 unlock ();
iut_cachan01 0:14e97aa401f3 82 return SD_BLOCK_DEVICE_ERROR_NO_DEVICE;
iut_cachan01 0:14e97aa401f3 83 } else {
iut_cachan01 0:14e97aa401f3 84 debug_if(SD_DBG, "SD card initialization failed\n");
iut_cachan01 0:14e97aa401f3 85 unlock();
iut_cachan01 0:14e97aa401f3 86 return SD_BLOCK_DEVICE_ERROR_NO_INIT;
iut_cachan01 0:14e97aa401f3 87 }
iut_cachan01 0:14e97aa401f3 88 }
iut_cachan01 0:14e97aa401f3 89 BSP_SD_GetCardInfo(&_current_card_info);
iut_cachan01 0:14e97aa401f3 90
iut_cachan01 0:14e97aa401f3 91 _card_type = _current_card_info.CardType;
iut_cachan01 0:14e97aa401f3 92 _read_size = _current_card_info.BlockSize;
iut_cachan01 0:14e97aa401f3 93 _program_size = _current_card_info.BlockSize;
iut_cachan01 0:14e97aa401f3 94 _erase_size = _current_card_info.BlockSize;
iut_cachan01 0:14e97aa401f3 95 _block_size = _current_card_info.BlockSize;
iut_cachan01 0:14e97aa401f3 96 _capacity_in_blocks = _current_card_info.BlockNbr;
iut_cachan01 0:14e97aa401f3 97
iut_cachan01 0:14e97aa401f3 98 debug_if(SD_DBG, "Card Type: %i\n", _current_card_info.CardType);
iut_cachan01 0:14e97aa401f3 99 debug_if(SD_DBG, "Card Version: %i\n", _current_card_info.CardVersion);
iut_cachan01 0:14e97aa401f3 100 debug_if(SD_DBG, "Class: %i\n", _current_card_info.Class);
iut_cachan01 0:14e97aa401f3 101 debug_if(SD_DBG, "Relative Card Address: %x\n", _current_card_info.RelCardAdd);
iut_cachan01 0:14e97aa401f3 102 debug_if(SD_DBG, "Card Capacity in blocks: %i\n", _current_card_info.BlockNbr);
iut_cachan01 0:14e97aa401f3 103 debug_if(SD_DBG, "One block size in bytes: %i\n", _current_card_info.BlockSize);
iut_cachan01 0:14e97aa401f3 104 debug_if(SD_DBG, "Card logical Capacity in blocks: %i\n", _current_card_info.LogBlockNbr);
iut_cachan01 0:14e97aa401f3 105 debug_if(SD_DBG, "Logical block size in bytes: %i\n", _current_card_info.LogBlockSize);
iut_cachan01 0:14e97aa401f3 106 debug_if(SD_DBG, "Timeout: %i\n", _timeout);
iut_cachan01 0:14e97aa401f3 107
iut_cachan01 0:14e97aa401f3 108 _is_initialized = true;
iut_cachan01 0:14e97aa401f3 109 unlock();
iut_cachan01 0:14e97aa401f3 110 return SD_BLOCK_DEVICE_OK;
iut_cachan01 0:14e97aa401f3 111 }
iut_cachan01 0:14e97aa401f3 112
iut_cachan01 0:14e97aa401f3 113 int SDBlockDeviceDISCOF746NG::deinit()
iut_cachan01 0:14e97aa401f3 114 {
iut_cachan01 0:14e97aa401f3 115 lock();
iut_cachan01 0:14e97aa401f3 116 _sd_state = BSP_SD_DeInit ();
iut_cachan01 0:14e97aa401f3 117 if(_sd_state != MSD_OK) {
iut_cachan01 0:14e97aa401f3 118 debug_if (SD_DBG, "SD card deinitialization failed\n");
iut_cachan01 0:14e97aa401f3 119 return SD_BLOCK_DEVICE_ERROR;
iut_cachan01 0:14e97aa401f3 120 }
iut_cachan01 0:14e97aa401f3 121 _is_initialized = false;
iut_cachan01 0:14e97aa401f3 122 unlock();
iut_cachan01 0:14e97aa401f3 123 return BD_ERROR_OK;
iut_cachan01 0:14e97aa401f3 124 }
iut_cachan01 0:14e97aa401f3 125
iut_cachan01 0:14e97aa401f3 126 int SDBlockDeviceDISCOF746NG::read(void *b, bd_addr_t addr, bd_size_t size)
iut_cachan01 0:14e97aa401f3 127 {
iut_cachan01 0:14e97aa401f3 128 if(!is_valid_read (addr, size)) {
iut_cachan01 0:14e97aa401f3 129 return SD_BLOCK_DEVICE_ERROR_PARAMETER;
iut_cachan01 0:14e97aa401f3 130 }
iut_cachan01 0:14e97aa401f3 131
iut_cachan01 0:14e97aa401f3 132 lock();
iut_cachan01 0:14e97aa401f3 133 if(!_is_initialized) {
iut_cachan01 0:14e97aa401f3 134 unlock();
iut_cachan01 0:14e97aa401f3 135 return SD_BLOCK_DEVICE_ERROR_NO_INIT;
iut_cachan01 0:14e97aa401f3 136 }
iut_cachan01 0:14e97aa401f3 137
iut_cachan01 0:14e97aa401f3 138 uint32_t *buffer = static_cast<uint32_t *> (b);
iut_cachan01 0:14e97aa401f3 139 int status = SD_BLOCK_DEVICE_OK;
iut_cachan01 0:14e97aa401f3 140
iut_cachan01 0:14e97aa401f3 141 // Get block address
iut_cachan01 0:14e97aa401f3 142 uint32_t block_addr = addr / _block_size;
iut_cachan01 0:14e97aa401f3 143 // Get block count
iut_cachan01 0:14e97aa401f3 144 uint32_t block_cnt = size / _block_size;
iut_cachan01 0:14e97aa401f3 145
iut_cachan01 0:14e97aa401f3 146 debug_if(
iut_cachan01 0:14e97aa401f3 147 SD_DBG,
iut_cachan01 0:14e97aa401f3 148 "BD_SD_DISCO_F746NG::read addr: 0x%x, block_addr: %i size: %lu block count: %i\n",
iut_cachan01 0:14e97aa401f3 149 addr, block_addr, size, block_cnt);
iut_cachan01 0:14e97aa401f3 150
iut_cachan01 0:14e97aa401f3 151 if(BSP_SD_ReadBlocks (buffer, block_addr, block_cnt, _timeout) != MSD_OK) {
iut_cachan01 0:14e97aa401f3 152 status = SD_BLOCK_DEVICE_ERROR_READ;
iut_cachan01 0:14e97aa401f3 153 }
iut_cachan01 0:14e97aa401f3 154
iut_cachan01 0:14e97aa401f3 155 // Wait until SD card is ready to use for new operation
iut_cachan01 0:14e97aa401f3 156 while(BSP_SD_GetCardState() != SD_TRANSFER_OK) {
iut_cachan01 0:14e97aa401f3 157 }
iut_cachan01 0:14e97aa401f3 158
iut_cachan01 0:14e97aa401f3 159 unlock ();
iut_cachan01 0:14e97aa401f3 160 return status;
iut_cachan01 0:14e97aa401f3 161 }
iut_cachan01 0:14e97aa401f3 162
iut_cachan01 0:14e97aa401f3 163 int SDBlockDeviceDISCOF746NG::program(const void *b, bd_addr_t addr, bd_size_t size)
iut_cachan01 0:14e97aa401f3 164 {
iut_cachan01 0:14e97aa401f3 165 if(!is_valid_program (addr, size)) {
iut_cachan01 0:14e97aa401f3 166 return SD_BLOCK_DEVICE_ERROR_PARAMETER;
iut_cachan01 0:14e97aa401f3 167 }
iut_cachan01 0:14e97aa401f3 168
iut_cachan01 0:14e97aa401f3 169 lock();
iut_cachan01 0:14e97aa401f3 170 if(!_is_initialized) {
iut_cachan01 0:14e97aa401f3 171 unlock ();
iut_cachan01 0:14e97aa401f3 172 return SD_BLOCK_DEVICE_ERROR_NO_INIT;
iut_cachan01 0:14e97aa401f3 173 }
iut_cachan01 0:14e97aa401f3 174
iut_cachan01 0:14e97aa401f3 175 uint32_t* buffer =
iut_cachan01 0:14e97aa401f3 176 const_cast<uint32_t*> (reinterpret_cast<const uint32_t*> (b));
iut_cachan01 0:14e97aa401f3 177 int status = SD_BLOCK_DEVICE_OK;
iut_cachan01 0:14e97aa401f3 178
iut_cachan01 0:14e97aa401f3 179 // Get block address
iut_cachan01 0:14e97aa401f3 180 uint32_t block_addr = addr / _block_size;
iut_cachan01 0:14e97aa401f3 181 // Get block count
iut_cachan01 0:14e97aa401f3 182 uint32_t block_cnt = size / _block_size;
iut_cachan01 0:14e97aa401f3 183
iut_cachan01 0:14e97aa401f3 184 debug_if (
iut_cachan01 0:14e97aa401f3 185 SD_DBG,
iut_cachan01 0:14e97aa401f3 186 "BD_SD_DISCO_F746NG::program addr: 0x%x, block_addr: %i size: %lu block count: %i\n",
iut_cachan01 0:14e97aa401f3 187 addr, block_addr, size, block_cnt);
iut_cachan01 0:14e97aa401f3 188
iut_cachan01 0:14e97aa401f3 189 if(BSP_SD_WriteBlocks (buffer, block_addr, block_cnt, _timeout) != MSD_OK) {
iut_cachan01 0:14e97aa401f3 190 status = SD_BLOCK_DEVICE_ERROR_PROGRAM;
iut_cachan01 0:14e97aa401f3 191 }
iut_cachan01 0:14e97aa401f3 192
iut_cachan01 0:14e97aa401f3 193 // Wait until SD card is ready to use for new operation
iut_cachan01 0:14e97aa401f3 194 while(BSP_SD_GetCardState() != SD_TRANSFER_OK) {
iut_cachan01 0:14e97aa401f3 195 }
iut_cachan01 0:14e97aa401f3 196
iut_cachan01 0:14e97aa401f3 197 unlock();
iut_cachan01 0:14e97aa401f3 198 return status;
iut_cachan01 0:14e97aa401f3 199 }
iut_cachan01 0:14e97aa401f3 200
iut_cachan01 0:14e97aa401f3 201 int SDBlockDeviceDISCOF746NG::erase(bd_addr_t addr, bd_size_t size)
iut_cachan01 0:14e97aa401f3 202 {
iut_cachan01 0:14e97aa401f3 203 if (!is_valid_erase(addr, size)) {
iut_cachan01 0:14e97aa401f3 204 return SD_BLOCK_DEVICE_ERROR_PARAMETER;
iut_cachan01 0:14e97aa401f3 205 }
iut_cachan01 0:14e97aa401f3 206
iut_cachan01 0:14e97aa401f3 207 lock();
iut_cachan01 0:14e97aa401f3 208 if(!_is_initialized) {
iut_cachan01 0:14e97aa401f3 209 unlock();
iut_cachan01 0:14e97aa401f3 210 return SD_BLOCK_DEVICE_ERROR_NO_INIT;
iut_cachan01 0:14e97aa401f3 211 }
iut_cachan01 0:14e97aa401f3 212
iut_cachan01 0:14e97aa401f3 213 size -= _block_size;
iut_cachan01 0:14e97aa401f3 214
iut_cachan01 0:14e97aa401f3 215 int status = SD_BLOCK_DEVICE_OK;
iut_cachan01 0:14e97aa401f3 216 uint32_t start_addr = addr;
iut_cachan01 0:14e97aa401f3 217 uint32_t end_addr = start_addr + size;
iut_cachan01 0:14e97aa401f3 218
iut_cachan01 0:14e97aa401f3 219 // Get block count
iut_cachan01 0:14e97aa401f3 220 uint32_t block_start_addr = start_addr / _block_size;
iut_cachan01 0:14e97aa401f3 221 // Get block address
iut_cachan01 0:14e97aa401f3 222 uint32_t block_end_addr = end_addr / _block_size;
iut_cachan01 0:14e97aa401f3 223
iut_cachan01 0:14e97aa401f3 224 debug_if(
iut_cachan01 0:14e97aa401f3 225 SD_DBG,
iut_cachan01 0:14e97aa401f3 226 "BD_SD_DISCO_F746NG::erase start_addr: 0x%x, block_start_addr: %i | end_addr: 0x%x, block_end_addr: %i size: %lu\n",
iut_cachan01 0:14e97aa401f3 227 start_addr, block_start_addr, end_addr, block_end_addr, size);
iut_cachan01 0:14e97aa401f3 228
iut_cachan01 0:14e97aa401f3 229 if(BSP_SD_Erase (block_start_addr, block_end_addr) != MSD_OK) {
iut_cachan01 0:14e97aa401f3 230 status = SD_BLOCK_DEVICE_ERROR_ERASE;
iut_cachan01 0:14e97aa401f3 231 }
iut_cachan01 0:14e97aa401f3 232
iut_cachan01 0:14e97aa401f3 233 /* Wait until SD card is ready to use for new operation */
iut_cachan01 0:14e97aa401f3 234 while(BSP_SD_GetCardState() != SD_TRANSFER_OK) {
iut_cachan01 0:14e97aa401f3 235 }
iut_cachan01 0:14e97aa401f3 236
iut_cachan01 0:14e97aa401f3 237 unlock();
iut_cachan01 0:14e97aa401f3 238 return status;
iut_cachan01 0:14e97aa401f3 239 }
iut_cachan01 0:14e97aa401f3 240
iut_cachan01 0:14e97aa401f3 241 bd_size_t SDBlockDeviceDISCOF746NG::get_read_size() const
iut_cachan01 0:14e97aa401f3 242 {
iut_cachan01 0:14e97aa401f3 243 return _read_size;
iut_cachan01 0:14e97aa401f3 244 }
iut_cachan01 0:14e97aa401f3 245
iut_cachan01 0:14e97aa401f3 246 bd_size_t SDBlockDeviceDISCOF746NG::get_program_size() const
iut_cachan01 0:14e97aa401f3 247 {
iut_cachan01 0:14e97aa401f3 248 return _program_size;
iut_cachan01 0:14e97aa401f3 249 }
iut_cachan01 0:14e97aa401f3 250
iut_cachan01 0:14e97aa401f3 251 bd_size_t SDBlockDeviceDISCOF746NG::get_erase_size() const
iut_cachan01 0:14e97aa401f3 252 {
iut_cachan01 0:14e97aa401f3 253 return _erase_size;
iut_cachan01 0:14e97aa401f3 254 }
iut_cachan01 0:14e97aa401f3 255
iut_cachan01 0:14e97aa401f3 256 bd_size_t SDBlockDeviceDISCOF746NG::size() const
iut_cachan01 0:14e97aa401f3 257 {
iut_cachan01 0:14e97aa401f3 258 return (_block_size * _capacity_in_blocks);
iut_cachan01 0:14e97aa401f3 259 }
iut_cachan01 0:14e97aa401f3 260
iut_cachan01 0:14e97aa401f3 261