L VD / sdio-glue

Dependents:   mbed-os-example-filesystem-sdio

Committer:
elelthvd
Date:
Wed Nov 11 03:05:14 2020 +0000
Revision:
0:d90c6c9a7600
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elelthvd 0:d90c6c9a7600 1 /* mbed Microcontroller Library
elelthvd 0:d90c6c9a7600 2 * Copyright (c) 2019 ARM Limited
elelthvd 0:d90c6c9a7600 3 * SPDX-License-Identifier: Apache-2.0
elelthvd 0:d90c6c9a7600 4 *
elelthvd 0:d90c6c9a7600 5 * Licensed under the Apache License, Version 2.0 (the "License");
elelthvd 0:d90c6c9a7600 6 * you may not use this file except in compliance with the License.
elelthvd 0:d90c6c9a7600 7 * You may obtain a copy of the License at
elelthvd 0:d90c6c9a7600 8 *
elelthvd 0:d90c6c9a7600 9 * http://www.apache.org/licenses/LICENSE-2.0
elelthvd 0:d90c6c9a7600 10 *
elelthvd 0:d90c6c9a7600 11 * Unless required by applicable law or agreed to in writing, software
elelthvd 0:d90c6c9a7600 12 * distributed under the License is distributed on an "AS IS" BASIS,
elelthvd 0:d90c6c9a7600 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
elelthvd 0:d90c6c9a7600 14 * See the License for the specific language governing permissions and
elelthvd 0:d90c6c9a7600 15 * limitations under the License.
elelthvd 0:d90c6c9a7600 16 */
elelthvd 0:d90c6c9a7600 17
elelthvd 0:d90c6c9a7600 18
elelthvd 0:d90c6c9a7600 19 #include "sdio_api.h"
elelthvd 0:d90c6c9a7600 20 #if DEVICE_SDIO_ASYNC
elelthvd 0:d90c6c9a7600 21 #include "us_ticker_api.h"
elelthvd 0:d90c6c9a7600 22 #endif
elelthvd 0:d90c6c9a7600 23 #include "SDIOBlockDevice.h"
elelthvd 0:d90c6c9a7600 24 #include "platform/mbed_debug.h"
elelthvd 0:d90c6c9a7600 25
elelthvd 0:d90c6c9a7600 26 using namespace mbed;
elelthvd 0:d90c6c9a7600 27
elelthvd 0:d90c6c9a7600 28 #if DEVICE_SDIO
elelthvd 0:d90c6c9a7600 29
elelthvd 0:d90c6c9a7600 30 /*
elelthvd 0:d90c6c9a7600 31 * defines
elelthvd 0:d90c6c9a7600 32 */
elelthvd 0:d90c6c9a7600 33
elelthvd 0:d90c6c9a7600 34 #define SDIO_DBG 1 /*!< 1 - Enable debugging */
elelthvd 0:d90c6c9a7600 35 #define SDIO_CMD_TRACE 0 /*!< 1 - Enable SD command tracing */
elelthvd 0:d90c6c9a7600 36
elelthvd 0:d90c6c9a7600 37 #define SDIO_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */
elelthvd 0:d90c6c9a7600 38 #define SDIO_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */
elelthvd 0:d90c6c9a7600 39 #define SDIO_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */
elelthvd 0:d90c6c9a7600 40 #define SDIO_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */
elelthvd 0:d90c6c9a7600 41 #define SDIO_BLOCK_DEVICE_ERROR_NO_DEVICE -5005 /*!< device is missing or not connected */
elelthvd 0:d90c6c9a7600 42 #define SDIO_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */
elelthvd 0:d90c6c9a7600 43 #define SDIO_BLOCK_DEVICE_ERROR_UNUSABLE -5007 /*!< unusable card */
elelthvd 0:d90c6c9a7600 44 #define SDIO_BLOCK_DEVICE_ERROR_NO_RESPONSE -5008 /*!< No response from device */
elelthvd 0:d90c6c9a7600 45 #define SDIO_BLOCK_DEVICE_ERROR_CRC -5009 /*!< CRC error */
elelthvd 0:d90c6c9a7600 46 #define SDIO_BLOCK_DEVICE_ERROR_ERASE -5010 /*!< Erase error: reset/sequence */
elelthvd 0:d90c6c9a7600 47 #define SDIO_BLOCK_DEVICE_ERROR_WRITE -5011 /*!< SPI Write error: !SPI_DATA_ACCEPTED */
elelthvd 0:d90c6c9a7600 48 #define SDIO_BLOCK_DEVICE_ERROR_UNSUPPORTED_BLOCKSIZE -5012 /*!< unsupported blocksize, only 512 byte supported */
elelthvd 0:d90c6c9a7600 49 #define SDIO_BLOCK_DEVICE_ERROR_READ_BLOCKS -5013 /*!< read data blocks from SD failed */
elelthvd 0:d90c6c9a7600 50 #define SDIO_BLOCK_DEVICE_ERROR_WRITE_BLOCKS -5014 /*!< write data blocks to SD failed */
elelthvd 0:d90c6c9a7600 51 #define SDIO_BLOCK_DEVICE_ERROR_ERASE_BLOCKS -5015 /*!< erase data blocks to SD failed */
elelthvd 0:d90c6c9a7600 52
elelthvd 0:d90c6c9a7600 53 #define BLOCK_SIZE_HC 512 /*!< Block size supported for SD card is 512 bytes */
elelthvd 0:d90c6c9a7600 54
elelthvd 0:d90c6c9a7600 55 // Types
elelthvd 0:d90c6c9a7600 56 #define SDCARD_NONE 0 /**< No card is present */
elelthvd 0:d90c6c9a7600 57 #define SDCARD_V1 1 /**< v1.x Standard Capacity */
elelthvd 0:d90c6c9a7600 58 #define SDCARD_V2 2 /**< v2.x Standard capacity SD card */
elelthvd 0:d90c6c9a7600 59 #define SDCARD_V2HC 3 /**< v2.x High capacity SD card */
elelthvd 0:d90c6c9a7600 60 #define CARD_UNKNOWN 4 /**< Unknown or unsupported card */
elelthvd 0:d90c6c9a7600 61
elelthvd 0:d90c6c9a7600 62 SDIOBlockDevice::SDIOBlockDevice(PinName card_detect) : _card_detect(card_detect),
elelthvd 0:d90c6c9a7600 63 _is_initialized(0),
elelthvd 0:d90c6c9a7600 64 _sectors(0),
elelthvd 0:d90c6c9a7600 65 _init_ref_count(0)
elelthvd 0:d90c6c9a7600 66 {
elelthvd 0:d90c6c9a7600 67 // Only HC block size is supported.
elelthvd 0:d90c6c9a7600 68 _block_size = BLOCK_SIZE_HC;
elelthvd 0:d90c6c9a7600 69 _erase_size = BLOCK_SIZE_HC;
elelthvd 0:d90c6c9a7600 70 }
elelthvd 0:d90c6c9a7600 71
elelthvd 0:d90c6c9a7600 72 SDIOBlockDevice::~SDIOBlockDevice()
elelthvd 0:d90c6c9a7600 73 {
elelthvd 0:d90c6c9a7600 74 if (_is_initialized) {
elelthvd 0:d90c6c9a7600 75 deinit();
elelthvd 0:d90c6c9a7600 76 }
elelthvd 0:d90c6c9a7600 77 }
elelthvd 0:d90c6c9a7600 78
elelthvd 0:d90c6c9a7600 79 int SDIOBlockDevice::init()
elelthvd 0:d90c6c9a7600 80 {
elelthvd 0:d90c6c9a7600 81 debug_if(SDIO_DBG, "init Card...\r\n");
elelthvd 0:d90c6c9a7600 82
elelthvd 0:d90c6c9a7600 83 lock();
elelthvd 0:d90c6c9a7600 84
elelthvd 0:d90c6c9a7600 85 if (!_is_initialized) {
elelthvd 0:d90c6c9a7600 86 _init_ref_count = 0;
elelthvd 0:d90c6c9a7600 87 }
elelthvd 0:d90c6c9a7600 88
elelthvd 0:d90c6c9a7600 89 _init_ref_count++;
elelthvd 0:d90c6c9a7600 90
elelthvd 0:d90c6c9a7600 91 if (_init_ref_count != 1) {
elelthvd 0:d90c6c9a7600 92 unlock();
elelthvd 0:d90c6c9a7600 93 return BD_ERROR_OK;
elelthvd 0:d90c6c9a7600 94 }
elelthvd 0:d90c6c9a7600 95
elelthvd 0:d90c6c9a7600 96 if (is_present() == false) {
elelthvd 0:d90c6c9a7600 97 unlock();
elelthvd 0:d90c6c9a7600 98 return SDIO_BLOCK_DEVICE_ERROR_NO_DEVICE;
elelthvd 0:d90c6c9a7600 99 }
elelthvd 0:d90c6c9a7600 100
elelthvd 0:d90c6c9a7600 101 int status = sdio_init();
elelthvd 0:d90c6c9a7600 102 if (BD_ERROR_OK != status) {
elelthvd 0:d90c6c9a7600 103 unlock();
elelthvd 0:d90c6c9a7600 104 return BD_ERROR_DEVICE_ERROR;
elelthvd 0:d90c6c9a7600 105 }
elelthvd 0:d90c6c9a7600 106
elelthvd 0:d90c6c9a7600 107 sdio_get_card_info(&_card_info);
elelthvd 0:d90c6c9a7600 108 _is_initialized = true;
elelthvd 0:d90c6c9a7600 109 debug_if(SDIO_DBG, "SDIO initialized: type: %lu version: %lu class: %lu\n",
elelthvd 0:d90c6c9a7600 110 _card_info.card_type, _card_info.card_version, _card_info.card_class);
elelthvd 0:d90c6c9a7600 111 debug_if(SDIO_DBG, "SDIO size: %lu MB\n",
elelthvd 0:d90c6c9a7600 112 _card_info.log_block_count / 2 / 1024);
elelthvd 0:d90c6c9a7600 113
elelthvd 0:d90c6c9a7600 114 // get sectors count from card_info
elelthvd 0:d90c6c9a7600 115 _sectors = _card_info.log_block_count;
elelthvd 0:d90c6c9a7600 116 if (BLOCK_SIZE_HC != _card_info.block_size) {
elelthvd 0:d90c6c9a7600 117 unlock();
elelthvd 0:d90c6c9a7600 118 return SDIO_BLOCK_DEVICE_ERROR_UNSUPPORTED_BLOCKSIZE;
elelthvd 0:d90c6c9a7600 119 }
elelthvd 0:d90c6c9a7600 120
elelthvd 0:d90c6c9a7600 121 unlock();
elelthvd 0:d90c6c9a7600 122 return status;
elelthvd 0:d90c6c9a7600 123 }
elelthvd 0:d90c6c9a7600 124
elelthvd 0:d90c6c9a7600 125 int SDIOBlockDevice::deinit()
elelthvd 0:d90c6c9a7600 126 {
elelthvd 0:d90c6c9a7600 127 debug_if(SDIO_DBG, "deinit SDIO Card...\r\n");
elelthvd 0:d90c6c9a7600 128 lock();
elelthvd 0:d90c6c9a7600 129
elelthvd 0:d90c6c9a7600 130 if (!_is_initialized) {
elelthvd 0:d90c6c9a7600 131 _init_ref_count = 0;
elelthvd 0:d90c6c9a7600 132 unlock();
elelthvd 0:d90c6c9a7600 133 return BD_ERROR_OK;
elelthvd 0:d90c6c9a7600 134 }
elelthvd 0:d90c6c9a7600 135
elelthvd 0:d90c6c9a7600 136 _init_ref_count--;
elelthvd 0:d90c6c9a7600 137
elelthvd 0:d90c6c9a7600 138 if (_init_ref_count) {
elelthvd 0:d90c6c9a7600 139 unlock();
elelthvd 0:d90c6c9a7600 140 return BD_ERROR_OK;
elelthvd 0:d90c6c9a7600 141 }
elelthvd 0:d90c6c9a7600 142
elelthvd 0:d90c6c9a7600 143 int status = sdio_deinit();
elelthvd 0:d90c6c9a7600 144 _is_initialized = false;
elelthvd 0:d90c6c9a7600 145
elelthvd 0:d90c6c9a7600 146 _sectors = 0;
elelthvd 0:d90c6c9a7600 147
elelthvd 0:d90c6c9a7600 148 unlock();
elelthvd 0:d90c6c9a7600 149 return status;
elelthvd 0:d90c6c9a7600 150 }
elelthvd 0:d90c6c9a7600 151
elelthvd 0:d90c6c9a7600 152 int SDIOBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
elelthvd 0:d90c6c9a7600 153 {
elelthvd 0:d90c6c9a7600 154 int status = 0;
elelthvd 0:d90c6c9a7600 155 lock();
elelthvd 0:d90c6c9a7600 156 if (is_present() == false) {
elelthvd 0:d90c6c9a7600 157 unlock();
elelthvd 0:d90c6c9a7600 158 return SDIO_BLOCK_DEVICE_ERROR_NO_DEVICE;
elelthvd 0:d90c6c9a7600 159 }
elelthvd 0:d90c6c9a7600 160
elelthvd 0:d90c6c9a7600 161 if (!_is_initialized) {
elelthvd 0:d90c6c9a7600 162 unlock();
elelthvd 0:d90c6c9a7600 163 return SDIO_BLOCK_DEVICE_ERROR_NO_INIT;
elelthvd 0:d90c6c9a7600 164 }
elelthvd 0:d90c6c9a7600 165
elelthvd 0:d90c6c9a7600 166 if (!is_valid_read(addr, size)) {
elelthvd 0:d90c6c9a7600 167 unlock();
elelthvd 0:d90c6c9a7600 168 return SDIO_BLOCK_DEVICE_ERROR_PARAMETER;
elelthvd 0:d90c6c9a7600 169 }
elelthvd 0:d90c6c9a7600 170
elelthvd 0:d90c6c9a7600 171 uint8_t *_buffer = static_cast<uint8_t *>(buffer);
elelthvd 0:d90c6c9a7600 172
elelthvd 0:d90c6c9a7600 173 // ReadBlocks uses byte unit address
elelthvd 0:d90c6c9a7600 174 // SDHC and SDXC Cards different addressing is handled in ReadBlocks()
elelthvd 0:d90c6c9a7600 175 bd_addr_t block_count = size / _block_size;
elelthvd 0:d90c6c9a7600 176 addr = addr / _block_size;
elelthvd 0:d90c6c9a7600 177
elelthvd 0:d90c6c9a7600 178 #if DEVICE_SDIO_ASYNC
elelthvd 0:d90c6c9a7600 179 // make sure card is ready
elelthvd 0:d90c6c9a7600 180 {
elelthvd 0:d90c6c9a7600 181 uint32_t tickstart = us_ticker_read();
elelthvd 0:d90c6c9a7600 182 while (sdio_get_card_state() != SD_TRANSFER_OK) {
elelthvd 0:d90c6c9a7600 183 // wait until SD ready
elelthvd 0:d90c6c9a7600 184 if ((us_ticker_read() - tickstart) >= MBED_CONF_SDIO_CMD_TIMEOUT) {
elelthvd 0:d90c6c9a7600 185 unlock();
elelthvd 0:d90c6c9a7600 186 return SDIO_BLOCK_DEVICE_ERROR_READ_BLOCKS;
elelthvd 0:d90c6c9a7600 187 }
elelthvd 0:d90c6c9a7600 188 }
elelthvd 0:d90c6c9a7600 189 }
elelthvd 0:d90c6c9a7600 190
elelthvd 0:d90c6c9a7600 191 // receive the data : one block/ multiple blocks is handled in ReadBlocks()
elelthvd 0:d90c6c9a7600 192 status = sdio_read_blocks_async(_buffer, addr, block_count);
elelthvd 0:d90c6c9a7600 193 debug_if(SDIO_DBG, "SDIO read blocks dbgtest addr: %lld block_count: %lld \n", addr, block_count);
elelthvd 0:d90c6c9a7600 194
elelthvd 0:d90c6c9a7600 195 if (status == MSD_OK) {
elelthvd 0:d90c6c9a7600 196 // wait until DMA finished
elelthvd 0:d90c6c9a7600 197 uint32_t tickstart = us_ticker_read();
elelthvd 0:d90c6c9a7600 198 while (sdio_read_pending() != SD_TRANSFER_OK) {
elelthvd 0:d90c6c9a7600 199 if ((us_ticker_read() - tickstart) >= MBED_CONF_SDIO_CMD_TIMEOUT) {
elelthvd 0:d90c6c9a7600 200 unlock();
elelthvd 0:d90c6c9a7600 201 return SDIO_BLOCK_DEVICE_ERROR_READ_BLOCKS;
elelthvd 0:d90c6c9a7600 202 }
elelthvd 0:d90c6c9a7600 203 }
elelthvd 0:d90c6c9a7600 204 // make sure card is ready
elelthvd 0:d90c6c9a7600 205 tickstart = us_ticker_read();
elelthvd 0:d90c6c9a7600 206 while (sdio_get_card_state() != SD_TRANSFER_OK) {
elelthvd 0:d90c6c9a7600 207 // wait until SD ready
elelthvd 0:d90c6c9a7600 208 if ((us_ticker_read() - tickstart) >= MBED_CONF_SDIO_CMD_TIMEOUT) {
elelthvd 0:d90c6c9a7600 209 unlock();
elelthvd 0:d90c6c9a7600 210 return SDIO_BLOCK_DEVICE_ERROR_READ_BLOCKS;
elelthvd 0:d90c6c9a7600 211 }
elelthvd 0:d90c6c9a7600 212 }
elelthvd 0:d90c6c9a7600 213 } else {
elelthvd 0:d90c6c9a7600 214 debug_if(SDIO_DBG, "SDIO read_blocks failed! addr: %lld block_count: %lld \n", addr, block_count);
elelthvd 0:d90c6c9a7600 215 unlock();
elelthvd 0:d90c6c9a7600 216 return SDIO_BLOCK_DEVICE_ERROR_READ_BLOCKS;
elelthvd 0:d90c6c9a7600 217 }
elelthvd 0:d90c6c9a7600 218 #else
elelthvd 0:d90c6c9a7600 219 status = sdio_read_blocks(_buffer, addr, block_count);
elelthvd 0:d90c6c9a7600 220 debug_if(SDIO_DBG, "SDIO read blocks dbgtest addr: %lld block_count: %lld \n", addr, block_count);
elelthvd 0:d90c6c9a7600 221
elelthvd 0:d90c6c9a7600 222 if (status != MSD_OK) {
elelthvd 0:d90c6c9a7600 223 debug_if(SDIO_DBG, "SDIO read blocks failed! addr: %lld block_count: %lld \n", addr, block_count);
elelthvd 0:d90c6c9a7600 224 status = SDIO_BLOCK_DEVICE_ERROR_READ_BLOCKS;
elelthvd 0:d90c6c9a7600 225 }
elelthvd 0:d90c6c9a7600 226 #endif
elelthvd 0:d90c6c9a7600 227
elelthvd 0:d90c6c9a7600 228 unlock();
elelthvd 0:d90c6c9a7600 229 return status;
elelthvd 0:d90c6c9a7600 230 }
elelthvd 0:d90c6c9a7600 231
elelthvd 0:d90c6c9a7600 232 int SDIOBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size)
elelthvd 0:d90c6c9a7600 233 {
elelthvd 0:d90c6c9a7600 234 int status = 0;
elelthvd 0:d90c6c9a7600 235 lock();
elelthvd 0:d90c6c9a7600 236
elelthvd 0:d90c6c9a7600 237 if (is_present() == false) {
elelthvd 0:d90c6c9a7600 238 unlock();
elelthvd 0:d90c6c9a7600 239 return SDIO_BLOCK_DEVICE_ERROR_NO_DEVICE;
elelthvd 0:d90c6c9a7600 240 }
elelthvd 0:d90c6c9a7600 241
elelthvd 0:d90c6c9a7600 242 if (!_is_initialized) {
elelthvd 0:d90c6c9a7600 243 unlock();
elelthvd 0:d90c6c9a7600 244 return SDIO_BLOCK_DEVICE_ERROR_NO_INIT;
elelthvd 0:d90c6c9a7600 245 }
elelthvd 0:d90c6c9a7600 246
elelthvd 0:d90c6c9a7600 247 if (!is_valid_program(addr, size)) {
elelthvd 0:d90c6c9a7600 248 unlock();
elelthvd 0:d90c6c9a7600 249 return SDIO_BLOCK_DEVICE_ERROR_PARAMETER;
elelthvd 0:d90c6c9a7600 250 }
elelthvd 0:d90c6c9a7600 251
elelthvd 0:d90c6c9a7600 252 uint8_t *_buffer = (uint8_t *)(buffer);
elelthvd 0:d90c6c9a7600 253
elelthvd 0:d90c6c9a7600 254 // Get block count
elelthvd 0:d90c6c9a7600 255 bd_size_t block_count = size / _block_size;
elelthvd 0:d90c6c9a7600 256 addr = addr / _block_size;
elelthvd 0:d90c6c9a7600 257
elelthvd 0:d90c6c9a7600 258 #if DEVICE_SDIO_ASYNC
elelthvd 0:d90c6c9a7600 259 // make sure card is ready
elelthvd 0:d90c6c9a7600 260 {
elelthvd 0:d90c6c9a7600 261 uint32_t tickstart = us_ticker_read();
elelthvd 0:d90c6c9a7600 262 while (sdio_get_card_state() != SD_TRANSFER_OK) {
elelthvd 0:d90c6c9a7600 263 // wait until SD ready
elelthvd 0:d90c6c9a7600 264 if ((us_ticker_read() - tickstart) >= MBED_CONF_SDIO_CMD_TIMEOUT) {
elelthvd 0:d90c6c9a7600 265 unlock();
elelthvd 0:d90c6c9a7600 266 return SDIO_BLOCK_DEVICE_ERROR_WRITE_BLOCKS;
elelthvd 0:d90c6c9a7600 267 }
elelthvd 0:d90c6c9a7600 268 }
elelthvd 0:d90c6c9a7600 269 }
elelthvd 0:d90c6c9a7600 270
elelthvd 0:d90c6c9a7600 271 status = sdio_write_blocks_async(_buffer, addr, block_count);
elelthvd 0:d90c6c9a7600 272 debug_if(SDIO_DBG, "SDIO write blocks async dbgtest addr: %lld block_count: %lld \n", addr, block_count);
elelthvd 0:d90c6c9a7600 273
elelthvd 0:d90c6c9a7600 274 if (status == MSD_OK) {
elelthvd 0:d90c6c9a7600 275 // wait until DMA finished
elelthvd 0:d90c6c9a7600 276 uint32_t tickstart = us_ticker_read();
elelthvd 0:d90c6c9a7600 277 while (sdio_write_pending() != SD_TRANSFER_OK) {
elelthvd 0:d90c6c9a7600 278 if ((us_ticker_read() - tickstart) >= MBED_CONF_SDIO_CMD_TIMEOUT) {
elelthvd 0:d90c6c9a7600 279 unlock();
elelthvd 0:d90c6c9a7600 280 return SDIO_BLOCK_DEVICE_ERROR_WRITE_BLOCKS;
elelthvd 0:d90c6c9a7600 281 }
elelthvd 0:d90c6c9a7600 282 }
elelthvd 0:d90c6c9a7600 283 // make sure card is ready
elelthvd 0:d90c6c9a7600 284 tickstart = us_ticker_read();
elelthvd 0:d90c6c9a7600 285 while (sdio_get_card_state() != SD_TRANSFER_OK) {
elelthvd 0:d90c6c9a7600 286 // wait until SD ready
elelthvd 0:d90c6c9a7600 287 if ((us_ticker_read() - tickstart) >= MBED_CONF_SDIO_CMD_TIMEOUT) {
elelthvd 0:d90c6c9a7600 288 unlock();
elelthvd 0:d90c6c9a7600 289 return SDIO_BLOCK_DEVICE_ERROR_WRITE_BLOCKS;
elelthvd 0:d90c6c9a7600 290 }
elelthvd 0:d90c6c9a7600 291 }
elelthvd 0:d90c6c9a7600 292 } else {
elelthvd 0:d90c6c9a7600 293 debug_if(SDIO_DBG, "SDIO write blocks async failed! addr: %lld block_count: %lld \n", addr, block_count);
elelthvd 0:d90c6c9a7600 294 unlock();
elelthvd 0:d90c6c9a7600 295 return SDIO_BLOCK_DEVICE_ERROR_WRITE_BLOCKS;
elelthvd 0:d90c6c9a7600 296 }
elelthvd 0:d90c6c9a7600 297 #else
elelthvd 0:d90c6c9a7600 298 status = sdio_write_blocks(_buffer, addr, block_count);
elelthvd 0:d90c6c9a7600 299
elelthvd 0:d90c6c9a7600 300 debug_if(SDIO_DBG, "SDIO write blocks dbgtest addr: %lld block_count: %lld \n", addr, block_count);
elelthvd 0:d90c6c9a7600 301
elelthvd 0:d90c6c9a7600 302 if (status != MSD_OK) {
elelthvd 0:d90c6c9a7600 303 debug_if(SDIO_DBG, "SDIO write blocks failed! addr: %lld block_count: %lld \n", addr, block_count);
elelthvd 0:d90c6c9a7600 304 status = SDIO_BLOCK_DEVICE_ERROR_WRITE_BLOCKS;
elelthvd 0:d90c6c9a7600 305 }
elelthvd 0:d90c6c9a7600 306 #endif
elelthvd 0:d90c6c9a7600 307
elelthvd 0:d90c6c9a7600 308 unlock();
elelthvd 0:d90c6c9a7600 309 return status;
elelthvd 0:d90c6c9a7600 310 }
elelthvd 0:d90c6c9a7600 311
elelthvd 0:d90c6c9a7600 312 int SDIOBlockDevice::trim(bd_addr_t addr, bd_size_t size)
elelthvd 0:d90c6c9a7600 313 {
elelthvd 0:d90c6c9a7600 314 debug_if(SDIO_DBG, "SDIO trim Card...\r\n");
elelthvd 0:d90c6c9a7600 315 lock();
elelthvd 0:d90c6c9a7600 316 if (is_present() == false) {
elelthvd 0:d90c6c9a7600 317 unlock();
elelthvd 0:d90c6c9a7600 318 return SDIO_BLOCK_DEVICE_ERROR_NO_DEVICE;
elelthvd 0:d90c6c9a7600 319 }
elelthvd 0:d90c6c9a7600 320
elelthvd 0:d90c6c9a7600 321 if (!_is_initialized) {
elelthvd 0:d90c6c9a7600 322 unlock();
elelthvd 0:d90c6c9a7600 323 return SDIO_BLOCK_DEVICE_ERROR_NO_INIT;
elelthvd 0:d90c6c9a7600 324 }
elelthvd 0:d90c6c9a7600 325
elelthvd 0:d90c6c9a7600 326 if (!_is_valid_trim(addr, size)) {
elelthvd 0:d90c6c9a7600 327 unlock();
elelthvd 0:d90c6c9a7600 328 return SDIO_BLOCK_DEVICE_ERROR_PARAMETER;
elelthvd 0:d90c6c9a7600 329 }
elelthvd 0:d90c6c9a7600 330
elelthvd 0:d90c6c9a7600 331 bd_size_t block_count = size / _block_size;
elelthvd 0:d90c6c9a7600 332 addr = addr / _block_size;
elelthvd 0:d90c6c9a7600 333
elelthvd 0:d90c6c9a7600 334 int status = sdio_erase(addr, block_count);
elelthvd 0:d90c6c9a7600 335 if (status != 0) {
elelthvd 0:d90c6c9a7600 336 debug_if(SDIO_DBG, "SDIO erase blocks failed! addr: %lld block_count: %lld \n", addr, block_count);
elelthvd 0:d90c6c9a7600 337 unlock();
elelthvd 0:d90c6c9a7600 338 return SDIO_BLOCK_DEVICE_ERROR_ERASE_BLOCKS;
elelthvd 0:d90c6c9a7600 339 #if DEVICE_SDIO_ASYNC
elelthvd 0:d90c6c9a7600 340 } else {
elelthvd 0:d90c6c9a7600 341 uint32_t tickstart = us_ticker_read();
elelthvd 0:d90c6c9a7600 342 while (sdio_get_card_state() != SD_TRANSFER_OK) {
elelthvd 0:d90c6c9a7600 343 // wait until SD ready
elelthvd 0:d90c6c9a7600 344 if ((us_ticker_read() - tickstart) >= MBED_CONF_SDIO_CMD_TIMEOUT) {
elelthvd 0:d90c6c9a7600 345 unlock();
elelthvd 0:d90c6c9a7600 346 return SDIO_BLOCK_DEVICE_ERROR_ERASE_BLOCKS;
elelthvd 0:d90c6c9a7600 347 }
elelthvd 0:d90c6c9a7600 348 }
elelthvd 0:d90c6c9a7600 349 #endif
elelthvd 0:d90c6c9a7600 350 }
elelthvd 0:d90c6c9a7600 351
elelthvd 0:d90c6c9a7600 352 unlock();
elelthvd 0:d90c6c9a7600 353 return status;
elelthvd 0:d90c6c9a7600 354 }
elelthvd 0:d90c6c9a7600 355
elelthvd 0:d90c6c9a7600 356 bd_size_t SDIOBlockDevice::get_read_size() const
elelthvd 0:d90c6c9a7600 357 {
elelthvd 0:d90c6c9a7600 358 return _block_size;
elelthvd 0:d90c6c9a7600 359 }
elelthvd 0:d90c6c9a7600 360
elelthvd 0:d90c6c9a7600 361 bd_size_t SDIOBlockDevice::get_program_size() const
elelthvd 0:d90c6c9a7600 362 {
elelthvd 0:d90c6c9a7600 363 return _block_size;
elelthvd 0:d90c6c9a7600 364 }
elelthvd 0:d90c6c9a7600 365
elelthvd 0:d90c6c9a7600 366 bd_size_t SDIOBlockDevice::size() const
elelthvd 0:d90c6c9a7600 367 {
elelthvd 0:d90c6c9a7600 368 return _block_size * _sectors;
elelthvd 0:d90c6c9a7600 369 }
elelthvd 0:d90c6c9a7600 370
elelthvd 0:d90c6c9a7600 371 void SDIOBlockDevice::debug(bool dbg)
elelthvd 0:d90c6c9a7600 372 {
elelthvd 0:d90c6c9a7600 373 }
elelthvd 0:d90c6c9a7600 374
elelthvd 0:d90c6c9a7600 375 bool SDIOBlockDevice::_is_valid_trim(bd_addr_t addr, bd_size_t size) const
elelthvd 0:d90c6c9a7600 376 {
elelthvd 0:d90c6c9a7600 377 return (
elelthvd 0:d90c6c9a7600 378 addr % _erase_size == 0 &&
elelthvd 0:d90c6c9a7600 379 size % _erase_size == 0 &&
elelthvd 0:d90c6c9a7600 380 addr + size <= this->size());
elelthvd 0:d90c6c9a7600 381 }
elelthvd 0:d90c6c9a7600 382
elelthvd 0:d90c6c9a7600 383 bool SDIOBlockDevice::is_present(void)
elelthvd 0:d90c6c9a7600 384 {
elelthvd 0:d90c6c9a7600 385 if (_card_detect.is_connected()) {
elelthvd 0:d90c6c9a7600 386 return (_card_detect.read() == 0);
elelthvd 0:d90c6c9a7600 387 } else {
elelthvd 0:d90c6c9a7600 388 return true;
elelthvd 0:d90c6c9a7600 389 }
elelthvd 0:d90c6c9a7600 390 }
elelthvd 0:d90c6c9a7600 391
elelthvd 0:d90c6c9a7600 392 const char *SDIOBlockDevice::get_type() const
elelthvd 0:d90c6c9a7600 393 {
elelthvd 0:d90c6c9a7600 394 return "SDIO";
elelthvd 0:d90c6c9a7600 395 }
elelthvd 0:d90c6c9a7600 396
elelthvd 0:d90c6c9a7600 397 #endif //DEVICE_SDIO