Roy Krikke / BD_SD_DISCO_F746NG

Dependencies:   BSP_DISCO_F746NG

Dependents:   DISCO-F746NG_BLOCK_DEVICE_SDCARD DISCO-F746NG_BLOCK_DEVICE_WITH_FAT_FILESYSTEM_ON_SDCARD SDReaderTest

Committer:
roykrikke
Date:
Sat Mar 24 16:27:20 2018 +0000
Revision:
0:131c3e1d831e
1.0.0 Release

Who changed what in which revision?

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