Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
SDBlockDevice.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /* Introduction 00018 * ------------ 00019 * SD and MMC cards support a number of interfaces, but common to them all 00020 * is one based on SPI. Since we already have the mbed SPI Interface, it will 00021 * be used for SD cards. 00022 * 00023 * The main reference I'm using is Chapter 7, "SPI Mode" of: 00024 * http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf 00025 * 00026 * SPI Startup 00027 * ----------- 00028 * The SD card powers up in SD mode. The start-up procedure is complicated 00029 * by the requirement to support older SDCards in a backwards compatible 00030 * way with the new higher capacity variants SDHC and SDHC. 00031 * 00032 * The following figures from the specification with associated text describe 00033 * the SPI mode initialisation process: 00034 * - Figure 7-1: SD Memory Card State Diagram (SPI mode) 00035 * - Figure 7-2: SPI Mode Initialization Flow 00036 * 00037 * Firstly, a low initial clock should be selected (in the range of 100- 00038 * 400kHZ). After initialisation has been completed, the switch to a 00039 * higher clock speed can be made (e.g. 1MHz). Newer cards will support 00040 * higher speeds than the default _transfer_sck defined here. 00041 * 00042 * Next, note the following from the SDCard specification (note to 00043 * Figure 7-1): 00044 * 00045 * In any of the cases CMD1 is not recommended because it may be difficult for the host 00046 * to distinguish between MultiMediaCard and SD Memory Card 00047 * 00048 * Hence CMD1 is not used for the initialisation sequence. 00049 * 00050 * The SPI interface mode is selected by asserting CS low and sending the 00051 * reset command (CMD0). The card will respond with a (R1) response. 00052 * In practice many cards initially respond with 0xff or invalid data 00053 * which is ignored. Data is read until a valid response is received 00054 * or the number of re-reads has exceeded a maximim count. If a valid 00055 * response is not received then the CMD0 can be retried. This 00056 * has been found to successfully initialise cards where the SPI master 00057 * (on MCU) has been reset but the SDCard has not, so the first 00058 * CMD0 may be lost. 00059 * 00060 * CMD8 is optionally sent to determine the voltage range supported, and 00061 * indirectly determine whether it is a version 1.x SD/non-SD card or 00062 * version 2.x. I'll just ignore this for now. 00063 * 00064 * ACMD41 is repeatedly issued to initialise the card, until "in idle" 00065 * (bit 0) of the R1 response goes to '0', indicating it is initialised. 00066 * 00067 * You should also indicate whether the host supports High Capicity cards, 00068 * and check whether the card is high capacity - i'll also ignore this 00069 * 00070 * SPI Protocol 00071 * ------------ 00072 * The SD SPI protocol is based on transactions made up of 8-bit words, with 00073 * the host starting every bus transaction by asserting the CS signal low. The 00074 * card always responds to commands, data blocks and errors. 00075 * 00076 * The protocol supports a CRC, but by default it is off (except for the 00077 * first reset CMD0, where the CRC can just be pre-calculated, and CMD8) 00078 * I'll leave the CRC off I think! 00079 * 00080 * Standard capacity cards have variable data block sizes, whereas High 00081 * Capacity cards fix the size of data block to 512 bytes. I'll therefore 00082 * just always use the Standard Capacity cards with a block size of 512 bytes. 00083 * This is set with CMD16. 00084 * 00085 * You can read and write single blocks (CMD17, CMD25) or multiple blocks 00086 * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When 00087 * the card gets a read command, it responds with a response token, and then 00088 * a data token or an error. 00089 * 00090 * SPI Command Format 00091 * ------------------ 00092 * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC. 00093 * 00094 * +---------------+------------+------------+-----------+----------+--------------+ 00095 * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 | 00096 * +---------------+------------+------------+-----------+----------+--------------+ 00097 * 00098 * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95) 00099 * 00100 * All Application Specific commands shall be preceded with APP_CMD (CMD55). 00101 * 00102 * SPI Response Format 00103 * ------------------- 00104 * The main response format (R1) is a status byte (normally zero). Key flags: 00105 * idle - 1 if the card is in an idle state/initialising 00106 * cmd - 1 if an illegal command code was detected 00107 * 00108 * +-------------------------------------------------+ 00109 * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle | 00110 * +-------------------------------------------------+ 00111 * 00112 * R1b is the same, except it is followed by a busy signal (zeros) until 00113 * the first non-zero byte when it is ready again. 00114 * 00115 * Data Response Token 00116 * ------------------- 00117 * Every data block written to the card is acknowledged by a byte 00118 * response token 00119 * 00120 * +----------------------+ 00121 * | xxx | 0 | status | 1 | 00122 * +----------------------+ 00123 * 010 - OK! 00124 * 101 - CRC Error 00125 * 110 - Write Error 00126 * 00127 * Single Block Read and Write 00128 * --------------------------- 00129 * 00130 * Block transfers have a byte header, followed by the data, followed 00131 * by a 16-bit CRC. In our case, the data will always be 512 bytes. 00132 * 00133 * +------+---------+---------+- - - -+---------+-----------+----------+ 00134 * | 0xFE | data[0] | data[1] | | data[n] | crc[15:8] | crc[7:0] | 00135 * +------+---------+---------+- - - -+---------+-----------+----------+ 00136 */ 00137 00138 /* If the target has no SPI support then SDCard is not supported */ 00139 #if DEVICE_SPI 00140 00141 #include "SDBlockDevice.h" 00142 #include "rtos/ThisThread.h" 00143 #include "platform/mbed_debug.h" 00144 #ifndef __STDC_FORMAT_MACROS 00145 #define __STDC_FORMAT_MACROS 00146 #endif 00147 #include <inttypes.h> 00148 #include <errno.h> 00149 00150 using namespace mbed; 00151 00152 #ifndef MBED_CONF_SD_CMD_TIMEOUT 00153 #define MBED_CONF_SD_CMD_TIMEOUT 5000 /*!< Timeout in ms for response */ 00154 #endif 00155 00156 #ifndef MBED_CONF_SD_CMD0_IDLE_STATE_RETRIES 00157 #define MBED_CONF_SD_CMD0_IDLE_STATE_RETRIES 5 /*!< Number of retries for sending CMDO */ 00158 #endif 00159 00160 #ifndef MBED_CONF_SD_INIT_FREQUENCY 00161 #define MBED_CONF_SD_INIT_FREQUENCY 100000 /*!< Initialization frequency Range (100KHz-400KHz) */ 00162 #endif 00163 00164 00165 #define SD_COMMAND_TIMEOUT MBED_CONF_SD_CMD_TIMEOUT 00166 #define SD_CMD0_GO_IDLE_STATE_RETRIES MBED_CONF_SD_CMD0_IDLE_STATE_RETRIES 00167 #define SD_DBG 0 /*!< 1 - Enable debugging */ 00168 #define SD_CMD_TRACE 0 /*!< 1 - Enable SD command tracing */ 00169 00170 #define SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */ 00171 #define SD_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */ 00172 #define SD_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */ 00173 #define SD_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */ 00174 #define SD_BLOCK_DEVICE_ERROR_NO_DEVICE -5005 /*!< device is missing or not connected */ 00175 #define SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */ 00176 #define SD_BLOCK_DEVICE_ERROR_UNUSABLE -5007 /*!< unusable card */ 00177 #define SD_BLOCK_DEVICE_ERROR_NO_RESPONSE -5008 /*!< No response from device */ 00178 #define SD_BLOCK_DEVICE_ERROR_CRC -5009 /*!< CRC error */ 00179 #define SD_BLOCK_DEVICE_ERROR_ERASE -5010 /*!< Erase error: reset/sequence */ 00180 #define SD_BLOCK_DEVICE_ERROR_WRITE -5011 /*!< SPI Write error: !SPI_DATA_ACCEPTED */ 00181 00182 #define BLOCK_SIZE_HC 512 /*!< Block size supported for SD card is 512 bytes */ 00183 #define WRITE_BL_PARTIAL 0 /*!< Partial block write - Not supported */ 00184 #define SPI_CMD(x) (0x40 | (x & 0x3f)) 00185 00186 /* R1 Response Format */ 00187 #define R1_NO_RESPONSE (0xFF) 00188 #define R1_RESPONSE_RECV (0x80) 00189 #define R1_IDLE_STATE (1 << 0) 00190 #define R1_ERASE_RESET (1 << 1) 00191 #define R1_ILLEGAL_COMMAND (1 << 2) 00192 #define R1_COM_CRC_ERROR (1 << 3) 00193 #define R1_ERASE_SEQUENCE_ERROR (1 << 4) 00194 #define R1_ADDRESS_ERROR (1 << 5) 00195 #define R1_PARAMETER_ERROR (1 << 6) 00196 00197 // Types 00198 #define SDCARD_NONE 0 /**< No card is present */ 00199 #define SDCARD_V1 1 /**< v1.x Standard Capacity */ 00200 #define SDCARD_V2 2 /**< v2.x Standard capacity SD card */ 00201 #define SDCARD_V2HC 3 /**< v2.x High capacity SD card */ 00202 #define CARD_UNKNOWN 4 /**< Unknown or unsupported card */ 00203 00204 /* SIZE in Bytes */ 00205 #define PACKET_SIZE 6 /*!< SD Packet size CMD+ARG+CRC */ 00206 #define R1_RESPONSE_SIZE 1 /*!< Size of R1 response */ 00207 #define R2_RESPONSE_SIZE 2 /*!< Size of R2 response */ 00208 #define R3_R7_RESPONSE_SIZE 5 /*!< Size of R3/R7 response */ 00209 00210 /* R1b Response */ 00211 #define DEVICE_BUSY (0x00) 00212 00213 /* R2 Response Format */ 00214 #define R2_CARD_LOCKED (1 << 0) 00215 #define R2_CMD_FAILED (1 << 1) 00216 #define R2_ERROR (1 << 2) 00217 #define R2_CC_ERROR (1 << 3) 00218 #define R2_CC_FAILED (1 << 4) 00219 #define R2_WP_VIOLATION (1 << 5) 00220 #define R2_ERASE_PARAM (1 << 6) 00221 #define R2_OUT_OF_RANGE (1 << 7) 00222 00223 /* R3 Response : OCR Register */ 00224 #define OCR_HCS_CCS (0x1 << 30) 00225 #define OCR_LOW_VOLTAGE (0x01 << 24) 00226 #define OCR_3_3V (0x1 << 20) 00227 00228 /* R7 response pattern for CMD8 */ 00229 #define CMD8_PATTERN (0xAA) 00230 00231 /* CRC Enable */ 00232 #define CRC_ENABLE (0) /*!< CRC 1 - Enable 0 - Disable */ 00233 00234 /* Control Tokens */ 00235 #define SPI_DATA_RESPONSE_MASK (0x1F) 00236 #define SPI_DATA_ACCEPTED (0x05) 00237 #define SPI_DATA_CRC_ERROR (0x0B) 00238 #define SPI_DATA_WRITE_ERROR (0x0D) 00239 #define SPI_START_BLOCK (0xFE) /*!< For Single Block Read/Write and Multiple Block Read */ 00240 #define SPI_START_BLK_MUL_WRITE (0xFC) /*!< Start Multi-block write */ 00241 #define SPI_STOP_TRAN (0xFD) /*!< Stop Multi-block write */ 00242 00243 #define SPI_DATA_READ_ERROR_MASK (0xF) /*!< Data Error Token: 4 LSB bits */ 00244 #define SPI_READ_ERROR (0x1 << 0) /*!< Error */ 00245 #define SPI_READ_ERROR_CC (0x1 << 1) /*!< CC Error*/ 00246 #define SPI_READ_ERROR_ECC_C (0x1 << 2) /*!< Card ECC failed */ 00247 #define SPI_READ_ERROR_OFR (0x1 << 3) /*!< Out of Range */ 00248 00249 // Only HC block size is supported. Making this a static constant reduces code size. 00250 const uint32_t SDBlockDevice::_block_size = BLOCK_SIZE_HC; 00251 00252 #if MBED_CONF_SD_CRC_ENABLED 00253 SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on) 00254 : _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0), 00255 _init_ref_count(0), _crc_on(crc_on) 00256 #else 00257 SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on) 00258 : _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0), 00259 _init_ref_count(0) 00260 #endif 00261 { 00262 _cs = 1; 00263 _card_type = SDCARD_NONE; 00264 00265 // Set default to 100kHz for initialisation and 1MHz for data transfer 00266 MBED_STATIC_ASSERT(((MBED_CONF_SD_INIT_FREQUENCY >= 100000) && (MBED_CONF_SD_INIT_FREQUENCY <= 400000)), 00267 "Initialization frequency should be between 100KHz to 400KHz"); 00268 _init_sck = MBED_CONF_SD_INIT_FREQUENCY; 00269 _transfer_sck = hz; 00270 00271 _erase_size = BLOCK_SIZE_HC; 00272 } 00273 00274 #if MBED_CONF_SD_CRC_ENABLED 00275 SDBlockDevice::SDBlockDevice(const spi_pinmap_t &spi_pinmap, PinName cs, uint64_t hz, bool crc_on) 00276 : _sectors(0), _spi(spi_pinmap), _cs(cs), _is_initialized(0), 00277 _init_ref_count(0), _crc_on(crc_on) 00278 #else 00279 SDBlockDevice::SDBlockDevice(const spi_pinmap_t &spi_pinmap, PinName cs, uint64_t hz, bool crc_on) 00280 : _sectors(0), _spi(spi_pinmap), _cs(cs), _is_initialized(0), 00281 _init_ref_count(0) 00282 #endif 00283 { 00284 _cs = 1; 00285 _card_type = SDCARD_NONE; 00286 00287 // Set default to 100kHz for initialisation and 1MHz for data transfer 00288 MBED_STATIC_ASSERT(((MBED_CONF_SD_INIT_FREQUENCY >= 100000) && (MBED_CONF_SD_INIT_FREQUENCY <= 400000)), 00289 "Initialization frequency should be between 100KHz to 400KHz"); 00290 _init_sck = MBED_CONF_SD_INIT_FREQUENCY; 00291 _transfer_sck = hz; 00292 00293 _erase_size = BLOCK_SIZE_HC; 00294 } 00295 00296 SDBlockDevice::~SDBlockDevice() 00297 { 00298 if (_is_initialized) { 00299 deinit(); 00300 } 00301 } 00302 00303 int SDBlockDevice::_initialise_card() 00304 { 00305 // Detail debugging is for commands 00306 _dbg = SD_DBG ? SD_CMD_TRACE : 0; 00307 int32_t status = BD_ERROR_OK; 00308 uint32_t response, arg; 00309 00310 // Initialize the SPI interface: Card by default is in SD mode 00311 _spi_init(); 00312 00313 // The card is transitioned from SDCard mode to SPI mode by sending the CMD0 + CS Asserted("0") 00314 if (_go_idle_state() != R1_IDLE_STATE) { 00315 debug_if(SD_DBG, "No disk, or could not put SD card in to SPI idle state\n"); 00316 return SD_BLOCK_DEVICE_ERROR_NO_DEVICE; 00317 } 00318 00319 // Send CMD8, if the card rejects the command then it's probably using the 00320 // legacy protocol, or is a MMC, or just flat-out broken 00321 status = _cmd8(); 00322 if (BD_ERROR_OK != status && SD_BLOCK_DEVICE_ERROR_UNSUPPORTED != status) { 00323 return status; 00324 } 00325 00326 #if MBED_CONF_SD_CRC_ENABLED 00327 if (_crc_on) { 00328 // Enable CRC 00329 status = _cmd(CMD59_CRC_ON_OFF, _crc_on); 00330 } 00331 #endif 00332 00333 // Read OCR - CMD58 Response contains OCR register 00334 if (BD_ERROR_OK != (status = _cmd(CMD58_READ_OCR, 0x0, 0x0, &response))) { 00335 return status; 00336 } 00337 00338 // Check if card supports voltage range: 3.3V 00339 if (!(response & OCR_3_3V)) { 00340 _card_type = CARD_UNKNOWN; 00341 status = SD_BLOCK_DEVICE_ERROR_UNUSABLE; 00342 return status; 00343 } 00344 00345 // HCS is set 1 for HC/XC capacity cards for ACMD41, if supported 00346 arg = 0x0; 00347 if (SDCARD_V2 == _card_type) { 00348 arg |= OCR_HCS_CCS; 00349 } 00350 00351 /* Idle state bit in the R1 response of ACMD41 is used by the card to inform the host 00352 * if initialization of ACMD41 is completed. "1" indicates that the card is still initializing. 00353 * "0" indicates completion of initialization. The host repeatedly issues ACMD41 until 00354 * this bit is set to "0". 00355 */ 00356 _spi_timer.start(); 00357 do { 00358 status = _cmd(ACMD41_SD_SEND_OP_COND, arg, 1, &response); 00359 } while ((response & R1_IDLE_STATE) && (_spi_timer.read_ms() < SD_COMMAND_TIMEOUT)); 00360 _spi_timer.stop(); 00361 00362 // Initialization complete: ACMD41 successful 00363 if ((BD_ERROR_OK != status) || (0x00 != response)) { 00364 _card_type = CARD_UNKNOWN; 00365 debug_if(SD_DBG, "Timeout waiting for card\n"); 00366 return status; 00367 } 00368 00369 if (SDCARD_V2 == _card_type) { 00370 // Get the card capacity CCS: CMD58 00371 if (BD_ERROR_OK == (status = _cmd(CMD58_READ_OCR, 0x0, 0x0, &response))) { 00372 // High Capacity card 00373 if (response & OCR_HCS_CCS) { 00374 _card_type = SDCARD_V2HC; 00375 debug_if(SD_DBG, "Card Initialized: High Capacity Card \n"); 00376 } else { 00377 debug_if(SD_DBG, "Card Initialized: Standard Capacity Card: Version 2.x \n"); 00378 } 00379 } 00380 } else { 00381 _card_type = SDCARD_V1; 00382 debug_if(SD_DBG, "Card Initialized: Version 1.x Card\n"); 00383 } 00384 00385 #if MBED_CONF_SD_CRC_ENABLED 00386 if (!_crc_on) { 00387 // Disable CRC 00388 status = _cmd(CMD59_CRC_ON_OFF, _crc_on); 00389 } 00390 #else 00391 status = _cmd(CMD59_CRC_ON_OFF, 0); 00392 #endif 00393 00394 return status; 00395 } 00396 00397 00398 int SDBlockDevice::init() 00399 { 00400 int err; 00401 00402 lock(); 00403 00404 if (!_is_initialized) { 00405 _init_ref_count = 0; 00406 } 00407 00408 _init_ref_count++; 00409 00410 if (_init_ref_count != 1) { 00411 goto end; 00412 } 00413 00414 err = _initialise_card(); 00415 _is_initialized = (err == BD_ERROR_OK); 00416 if (!_is_initialized) { 00417 debug_if(SD_DBG, "Fail to initialize card\n"); 00418 unlock(); 00419 return err; 00420 } 00421 debug_if(SD_DBG, "init card = %d\n", _is_initialized); 00422 _sectors = _sd_sectors(); 00423 // CMD9 failed 00424 if (0 == _sectors) { 00425 unlock(); 00426 return BD_ERROR_DEVICE_ERROR; 00427 } 00428 00429 // Set block length to 512 (CMD16) 00430 if (_cmd(CMD16_SET_BLOCKLEN, _block_size) != 0) { 00431 debug_if(SD_DBG, "Set %" PRIu32 "-byte block timed out\n", _block_size); 00432 unlock(); 00433 return BD_ERROR_DEVICE_ERROR; 00434 } 00435 00436 // Set SCK for data transfer 00437 err = _freq(); 00438 if (err) { 00439 unlock(); 00440 return err; 00441 } 00442 00443 end: 00444 unlock(); 00445 return BD_ERROR_OK; 00446 } 00447 00448 int SDBlockDevice::deinit() 00449 { 00450 lock(); 00451 00452 if (!_is_initialized) { 00453 _init_ref_count = 0; 00454 goto end; 00455 } 00456 00457 _init_ref_count--; 00458 00459 if (_init_ref_count) { 00460 goto end; 00461 } 00462 00463 _is_initialized = false; 00464 _sectors = 0; 00465 00466 end: 00467 unlock(); 00468 return BD_ERROR_OK; 00469 } 00470 00471 00472 int SDBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size) 00473 { 00474 if (!is_valid_program(addr, size)) { 00475 return SD_BLOCK_DEVICE_ERROR_PARAMETER; 00476 } 00477 00478 lock(); 00479 if (!_is_initialized) { 00480 unlock(); 00481 return SD_BLOCK_DEVICE_ERROR_NO_INIT; 00482 } 00483 00484 const uint8_t *buffer = static_cast<const uint8_t *>(b); 00485 int status = BD_ERROR_OK; 00486 uint8_t response; 00487 00488 // Get block count 00489 size_t blockCnt = size / _block_size; 00490 00491 // SDSC Card (CCS=0) uses byte unit address 00492 // SDHC and SDXC Cards (CCS=1) use block unit address (512 Bytes unit) 00493 if (SDCARD_V2HC == _card_type) { 00494 addr = addr / _block_size; 00495 } 00496 00497 // Send command to perform write operation 00498 if (blockCnt == 1) { 00499 // Single block write command 00500 if (BD_ERROR_OK != (status = _cmd(CMD24_WRITE_BLOCK, addr))) { 00501 unlock(); 00502 return status; 00503 } 00504 00505 // Write data 00506 response = _write(buffer, SPI_START_BLOCK, _block_size); 00507 00508 // Only CRC and general write error are communicated via response token 00509 if (response != SPI_DATA_ACCEPTED) { 00510 debug_if(SD_DBG, "Single Block Write failed: 0x%x \n", response); 00511 status = SD_BLOCK_DEVICE_ERROR_WRITE; 00512 } 00513 } else { 00514 // Pre-erase setting prior to multiple block write operation 00515 _cmd(ACMD23_SET_WR_BLK_ERASE_COUNT, blockCnt, 1); 00516 00517 // Multiple block write command 00518 if (BD_ERROR_OK != (status = _cmd(CMD25_WRITE_MULTIPLE_BLOCK, addr))) { 00519 unlock(); 00520 return status; 00521 } 00522 00523 // Write the data: one block at a time 00524 do { 00525 response = _write(buffer, SPI_START_BLK_MUL_WRITE, _block_size); 00526 if (response != SPI_DATA_ACCEPTED) { 00527 debug_if(SD_DBG, "Multiple Block Write failed: 0x%x \n", response); 00528 break; 00529 } 00530 buffer += _block_size; 00531 } while (--blockCnt); // Receive all blocks of data 00532 00533 /* In a Multiple Block write operation, the stop transmission will be done by 00534 * sending 'Stop Tran' token instead of 'Start Block' token at the beginning 00535 * of the next block 00536 */ 00537 _spi.write(SPI_STOP_TRAN); 00538 } 00539 00540 _deselect(); 00541 unlock(); 00542 return status; 00543 } 00544 00545 int SDBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size) 00546 { 00547 if (!is_valid_read(addr, size)) { 00548 return SD_BLOCK_DEVICE_ERROR_PARAMETER; 00549 } 00550 00551 lock(); 00552 if (!_is_initialized) { 00553 unlock(); 00554 return SD_BLOCK_DEVICE_ERROR_PARAMETER; 00555 } 00556 00557 uint8_t *buffer = static_cast<uint8_t *>(b); 00558 int status = BD_ERROR_OK; 00559 size_t blockCnt = size / _block_size; 00560 00561 // SDSC Card (CCS=0) uses byte unit address 00562 // SDHC and SDXC Cards (CCS=1) use block unit address (512 Bytes unit) 00563 if (SDCARD_V2HC == _card_type) { 00564 addr = addr / _block_size; 00565 } 00566 00567 // Write command ro receive data 00568 if (blockCnt > 1) { 00569 status = _cmd(CMD18_READ_MULTIPLE_BLOCK, addr); 00570 } else { 00571 status = _cmd(CMD17_READ_SINGLE_BLOCK, addr); 00572 } 00573 if (BD_ERROR_OK != status) { 00574 unlock(); 00575 return status; 00576 } 00577 00578 // receive the data : one block at a time 00579 while (blockCnt) { 00580 if (0 != _read(buffer, _block_size)) { 00581 status = SD_BLOCK_DEVICE_ERROR_NO_RESPONSE; 00582 break; 00583 } 00584 buffer += _block_size; 00585 --blockCnt; 00586 } 00587 _deselect(); 00588 00589 // Send CMD12(0x00000000) to stop the transmission for multi-block transfer 00590 if (size > _block_size) { 00591 status = _cmd(CMD12_STOP_TRANSMISSION, 0x0); 00592 } 00593 unlock(); 00594 return status; 00595 } 00596 00597 bool SDBlockDevice::_is_valid_trim(bd_addr_t addr, bd_size_t size) 00598 { 00599 return ( 00600 addr % _erase_size == 0 && 00601 size % _erase_size == 0 && 00602 addr + size <= this->size()); 00603 } 00604 00605 int SDBlockDevice::trim(bd_addr_t addr, bd_size_t size) 00606 { 00607 if (!_is_valid_trim(addr, size)) { 00608 return SD_BLOCK_DEVICE_ERROR_PARAMETER; 00609 } 00610 00611 lock(); 00612 if (!_is_initialized) { 00613 unlock(); 00614 return SD_BLOCK_DEVICE_ERROR_NO_INIT; 00615 } 00616 int status = BD_ERROR_OK; 00617 00618 size -= _block_size; 00619 // SDSC Card (CCS=0) uses byte unit address 00620 // SDHC and SDXC Cards (CCS=1) use block unit address (512 Bytes unit) 00621 if (SDCARD_V2HC == _card_type) { 00622 size = size / _block_size; 00623 addr = addr / _block_size; 00624 } 00625 00626 // Start lba sent in start command 00627 if (BD_ERROR_OK != (status = _cmd(CMD32_ERASE_WR_BLK_START_ADDR, addr))) { 00628 unlock(); 00629 return status; 00630 } 00631 00632 // End lba = addr+size sent in end addr command 00633 if (BD_ERROR_OK != (status = _cmd(CMD33_ERASE_WR_BLK_END_ADDR, addr + size))) { 00634 unlock(); 00635 return status; 00636 } 00637 status = _cmd(CMD38_ERASE, 0x0); 00638 unlock(); 00639 return status; 00640 } 00641 00642 bd_size_t SDBlockDevice::get_read_size() const 00643 { 00644 return _block_size; 00645 } 00646 00647 bd_size_t SDBlockDevice::get_program_size() const 00648 { 00649 return _block_size; 00650 } 00651 00652 bd_size_t SDBlockDevice::size() const 00653 { 00654 return _block_size * _sectors; 00655 } 00656 00657 const char *SDBlockDevice::get_type() const 00658 { 00659 return "SD"; 00660 } 00661 00662 void SDBlockDevice::debug(bool dbg) 00663 { 00664 _dbg = dbg; 00665 } 00666 00667 int SDBlockDevice::frequency(uint64_t freq) 00668 { 00669 lock(); 00670 _transfer_sck = freq; 00671 int err = _freq(); 00672 unlock(); 00673 return err; 00674 } 00675 00676 // PRIVATE FUNCTIONS 00677 int SDBlockDevice::_freq(void) 00678 { 00679 // Max frequency supported is 25MHZ 00680 if (_transfer_sck <= 25000000) { 00681 _spi.frequency(_transfer_sck); 00682 return 0; 00683 } else { // TODO: Switch function to be implemented for higher frequency 00684 _transfer_sck = 25000000; 00685 _spi.frequency(_transfer_sck); 00686 return -EINVAL; 00687 } 00688 } 00689 00690 uint8_t SDBlockDevice::_cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg) 00691 { 00692 uint8_t response; 00693 char cmdPacket[PACKET_SIZE]; 00694 00695 // Prepare the command packet 00696 cmdPacket[0] = SPI_CMD(cmd); 00697 cmdPacket[1] = (arg >> 24); 00698 cmdPacket[2] = (arg >> 16); 00699 cmdPacket[3] = (arg >> 8); 00700 cmdPacket[4] = (arg >> 0); 00701 00702 #if MBED_CONF_SD_CRC_ENABLED 00703 if (_crc_on) { 00704 MbedCRC<POLY_7BIT_SD, 7> crc7; 00705 uint32_t crc; 00706 crc7.compute(cmdPacket, 5, &crc); 00707 cmdPacket[5] = ((uint8_t) crc << 1) | 0x01; 00708 } else 00709 #endif 00710 { 00711 // CMD0 is executed in SD mode, hence should have correct CRC 00712 // CMD8 CRC verification is always enabled 00713 switch (cmd) { 00714 case CMD0_GO_IDLE_STATE: 00715 cmdPacket[5] = 0x95; 00716 break; 00717 case CMD8_SEND_IF_COND: 00718 cmdPacket[5] = 0x87; 00719 break; 00720 default: 00721 cmdPacket[5] = 0xFF; // Make sure bit 0-End bit is high 00722 break; 00723 } 00724 } 00725 00726 // send a command 00727 for (int i = 0; i < PACKET_SIZE; i++) { 00728 _spi.write(cmdPacket[i]); 00729 } 00730 00731 // The received byte immediataly following CMD12 is a stuff byte, 00732 // it should be discarded before receive the response of the CMD12. 00733 if (CMD12_STOP_TRANSMISSION == cmd) { 00734 _spi.write(SPI_FILL_CHAR); 00735 } 00736 00737 // Loop for response: Response is sent back within command response time (NCR), 0 to 8 bytes for SDC 00738 for (int i = 0; i < 0x10; i++) { 00739 response = _spi.write(SPI_FILL_CHAR); 00740 // Got the response 00741 if (!(response & R1_RESPONSE_RECV)) { 00742 break; 00743 } 00744 } 00745 return response; 00746 } 00747 00748 int SDBlockDevice::_cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAcmd, uint32_t *resp) 00749 { 00750 int32_t status = BD_ERROR_OK; 00751 uint32_t response; 00752 00753 // Select card and wait for card to be ready before sending next command 00754 // Note: next command will fail if card is not ready 00755 _select(); 00756 00757 // No need to wait for card to be ready when sending the stop command 00758 if (CMD12_STOP_TRANSMISSION != cmd) { 00759 if (false == _wait_ready(SD_COMMAND_TIMEOUT)) { 00760 debug_if(SD_DBG, "Card not ready yet \n"); 00761 } 00762 } 00763 00764 // Re-try command 00765 for (int i = 0; i < 3; i++) { 00766 // Send CMD55 for APP command first 00767 if (isAcmd) { 00768 response = _cmd_spi(CMD55_APP_CMD, 0x0); 00769 // Wait for card to be ready after CMD55 00770 if (false == _wait_ready(SD_COMMAND_TIMEOUT)) { 00771 debug_if(SD_DBG, "Card not ready yet \n"); 00772 } 00773 } 00774 00775 // Send command over SPI interface 00776 response = _cmd_spi(cmd, arg); 00777 if (R1_NO_RESPONSE == response) { 00778 debug_if(SD_DBG, "No response CMD:%d \n", cmd); 00779 continue; 00780 } 00781 break; 00782 } 00783 00784 // Pass the response to the command call if required 00785 if (NULL != resp) { 00786 *resp = response; 00787 } 00788 00789 // Process the response R1 : Exit on CRC/Illegal command error/No response 00790 if (R1_NO_RESPONSE == response) { 00791 _deselect(); 00792 debug_if(SD_DBG, "No response CMD:%d response: 0x%" PRIx32 "\n", cmd, response); 00793 return SD_BLOCK_DEVICE_ERROR_NO_DEVICE; // No device 00794 } 00795 if (response & R1_COM_CRC_ERROR) { 00796 _deselect(); 00797 debug_if(SD_DBG, "CRC error CMD:%d response 0x%" PRIx32 "\n", cmd, response); 00798 return SD_BLOCK_DEVICE_ERROR_CRC; // CRC error 00799 } 00800 if (response & R1_ILLEGAL_COMMAND) { 00801 _deselect(); 00802 debug_if(SD_DBG, "Illegal command CMD:%d response 0x%" PRIx32 "\n", cmd, response); 00803 if (CMD8_SEND_IF_COND == cmd) { // Illegal command is for Ver1 or not SD Card 00804 _card_type = CARD_UNKNOWN; 00805 } 00806 return SD_BLOCK_DEVICE_ERROR_UNSUPPORTED; // Command not supported 00807 } 00808 00809 debug_if(_dbg, "CMD:%d \t arg:0x%" PRIx32 " \t Response:0x%" PRIx32 "\n", cmd, arg, response); 00810 // Set status for other errors 00811 if ((response & R1_ERASE_RESET) || (response & R1_ERASE_SEQUENCE_ERROR)) { 00812 status = SD_BLOCK_DEVICE_ERROR_ERASE; // Erase error 00813 } else if ((response & R1_ADDRESS_ERROR) || (response & R1_PARAMETER_ERROR)) { 00814 // Misaligned address / invalid address block length 00815 status = SD_BLOCK_DEVICE_ERROR_PARAMETER; 00816 } 00817 00818 // Get rest of the response part for other commands 00819 switch (cmd) { 00820 case CMD8_SEND_IF_COND: // Response R7 00821 debug_if(_dbg, "V2-Version Card\n"); 00822 _card_type = SDCARD_V2; // fallthrough 00823 // Note: No break here, need to read rest of the response 00824 case CMD58_READ_OCR: // Response R3 00825 response = (_spi.write(SPI_FILL_CHAR) << 24); 00826 response |= (_spi.write(SPI_FILL_CHAR) << 16); 00827 response |= (_spi.write(SPI_FILL_CHAR) << 8); 00828 response |= _spi.write(SPI_FILL_CHAR); 00829 debug_if(_dbg, "R3/R7: 0x%" PRIx32 "\n", response); 00830 break; 00831 00832 case CMD12_STOP_TRANSMISSION: // Response R1b 00833 case CMD38_ERASE: 00834 _wait_ready(SD_COMMAND_TIMEOUT); 00835 break; 00836 00837 case ACMD13_SD_STATUS: // Response R2 00838 response = _spi.write(SPI_FILL_CHAR); 00839 debug_if(_dbg, "R2: 0x%" PRIx32 "\n", response); 00840 break; 00841 00842 default: // Response R1 00843 break; 00844 } 00845 00846 // Pass the updated response to the command 00847 if (NULL != resp) { 00848 *resp = response; 00849 } 00850 00851 // Do not deselect card if read is in progress. 00852 if (((CMD9_SEND_CSD == cmd) || (ACMD22_SEND_NUM_WR_BLOCKS == cmd) || 00853 (CMD24_WRITE_BLOCK == cmd) || (CMD25_WRITE_MULTIPLE_BLOCK == cmd) || 00854 (CMD17_READ_SINGLE_BLOCK == cmd) || (CMD18_READ_MULTIPLE_BLOCK == cmd)) 00855 && (BD_ERROR_OK == status)) { 00856 return BD_ERROR_OK; 00857 } 00858 // Deselect card 00859 _deselect(); 00860 return status; 00861 } 00862 00863 int SDBlockDevice::_cmd8() 00864 { 00865 uint32_t arg = (CMD8_PATTERN << 0); // [7:0]check pattern 00866 uint32_t response = 0; 00867 int32_t status = BD_ERROR_OK; 00868 00869 arg |= (0x1 << 8); // 2.7-3.6V // [11:8]supply voltage(VHS) 00870 00871 status = _cmd(CMD8_SEND_IF_COND, arg, 0x0, &response); 00872 // Verify voltage and pattern for V2 version of card 00873 if ((BD_ERROR_OK == status) && (SDCARD_V2 == _card_type)) { 00874 // If check pattern is not matched, CMD8 communication is not valid 00875 if ((response & 0xFFF) != arg) { 00876 debug_if(SD_DBG, "CMD8 Pattern mismatch 0x%" PRIx32 " : 0x%" PRIx32 "\n", arg, response); 00877 _card_type = CARD_UNKNOWN; 00878 status = SD_BLOCK_DEVICE_ERROR_UNUSABLE; 00879 } 00880 } 00881 return status; 00882 } 00883 00884 uint32_t SDBlockDevice::_go_idle_state() 00885 { 00886 uint32_t response; 00887 00888 /* Reseting the MCU SPI master may not reset the on-board SDCard, in which 00889 * case when MCU power-on occurs the SDCard will resume operations as 00890 * though there was no reset. In this scenario the first CMD0 will 00891 * not be interpreted as a command and get lost. For some cards retrying 00892 * the command overcomes this situation. */ 00893 for (int i = 0; i < SD_CMD0_GO_IDLE_STATE_RETRIES; i++) { 00894 _cmd(CMD0_GO_IDLE_STATE, 0x0, 0x0, &response); 00895 if (R1_IDLE_STATE == response) { 00896 break; 00897 } 00898 rtos::ThisThread::sleep_for(1); 00899 } 00900 return response; 00901 } 00902 00903 int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length) 00904 { 00905 uint16_t crc; 00906 00907 // read until start byte (0xFE) 00908 if (false == _wait_token(SPI_START_BLOCK)) { 00909 debug_if(SD_DBG, "Read timeout\n"); 00910 _deselect(); 00911 return SD_BLOCK_DEVICE_ERROR_NO_RESPONSE; 00912 } 00913 00914 // read data 00915 for (uint32_t i = 0; i < length; i++) { 00916 buffer[i] = _spi.write(SPI_FILL_CHAR); 00917 } 00918 00919 // Read the CRC16 checksum for the data block 00920 crc = (_spi.write(SPI_FILL_CHAR) << 8); 00921 crc |= _spi.write(SPI_FILL_CHAR); 00922 00923 #if MBED_CONF_SD_CRC_ENABLED 00924 if (_crc_on) { 00925 mbed::MbedCRC<POLY_16BIT_CCITT, 16> crc16(0, 0, false, false); 00926 uint32_t crc_result; 00927 // Compute and verify checksum 00928 crc16.compute(buffer, length, &crc_result); 00929 if (crc_result != crc) { 00930 debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx32 "\n", 00931 crc, crc_result); 00932 _deselect(); 00933 return SD_BLOCK_DEVICE_ERROR_CRC; 00934 } 00935 } 00936 #endif 00937 00938 _deselect(); 00939 return 0; 00940 } 00941 00942 int SDBlockDevice::_read(uint8_t *buffer, uint32_t length) 00943 { 00944 uint16_t crc; 00945 00946 // read until start byte (0xFE) 00947 if (false == _wait_token(SPI_START_BLOCK)) { 00948 debug_if(SD_DBG, "Read timeout\n"); 00949 return SD_BLOCK_DEVICE_ERROR_NO_RESPONSE; 00950 } 00951 00952 // read data 00953 _spi.write(NULL, 0, (char *)buffer, length); 00954 00955 // Read the CRC16 checksum for the data block 00956 crc = (_spi.write(SPI_FILL_CHAR) << 8); 00957 crc |= _spi.write(SPI_FILL_CHAR); 00958 00959 #if MBED_CONF_SD_CRC_ENABLED 00960 if (_crc_on) { 00961 mbed::MbedCRC<POLY_16BIT_CCITT, 16> crc16(0, 0, false, false); 00962 uint32_t crc_result; 00963 // Compute and verify checksum 00964 crc16.compute((void *)buffer, length, &crc_result); 00965 if ((uint16_t)crc_result != crc) { 00966 debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx16 "\n", 00967 crc, (uint16_t)crc_result); 00968 return SD_BLOCK_DEVICE_ERROR_CRC; 00969 } 00970 } 00971 #endif 00972 00973 return 0; 00974 } 00975 00976 uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t length) 00977 { 00978 00979 uint32_t crc = (~0); 00980 uint8_t response = 0xFF; 00981 00982 // indicate start of block 00983 _spi.write(token); 00984 00985 // write the data 00986 _spi.write((char *)buffer, length, NULL, 0); 00987 00988 #if MBED_CONF_SD_CRC_ENABLED 00989 if (_crc_on) { 00990 mbed::MbedCRC<POLY_16BIT_CCITT, 16> crc16(0, 0, false, false); 00991 // Compute CRC 00992 crc16.compute(buffer, length, &crc); 00993 } 00994 #endif 00995 00996 // write the checksum CRC16 00997 _spi.write(crc >> 8); 00998 _spi.write(crc); 00999 01000 01001 // check the response token 01002 response = _spi.write(SPI_FILL_CHAR); 01003 01004 // Wait for last block to be written 01005 if (false == _wait_ready(SD_COMMAND_TIMEOUT)) { 01006 debug_if(SD_DBG, "Card not ready yet \n"); 01007 } 01008 01009 return (response & SPI_DATA_RESPONSE_MASK); 01010 } 01011 01012 static uint32_t ext_bits(unsigned char *data, int msb, int lsb) 01013 { 01014 uint32_t bits = 0; 01015 uint32_t size = 1 + msb - lsb; 01016 for (uint32_t i = 0; i < size; i++) { 01017 uint32_t position = lsb + i; 01018 uint32_t byte = 15 - (position >> 3); 01019 uint32_t bit = position & 0x7; 01020 uint32_t value = (data[byte] >> bit) & 1; 01021 bits |= value << i; 01022 } 01023 return bits; 01024 } 01025 01026 bd_size_t SDBlockDevice::_sd_sectors() 01027 { 01028 uint32_t c_size, c_size_mult, read_bl_len; 01029 uint32_t block_len, mult, blocknr; 01030 uint32_t hc_c_size; 01031 bd_size_t blocks = 0, capacity = 0; 01032 01033 // CMD9, Response R2 (R1 byte + 16-byte block read) 01034 if (_cmd(CMD9_SEND_CSD, 0x0) != 0x0) { 01035 debug_if(SD_DBG, "Didn't get a response from the disk\n"); 01036 return 0; 01037 } 01038 uint8_t csd[16]; 01039 if (_read_bytes(csd, 16) != 0) { 01040 debug_if(SD_DBG, "Couldn't read csd response from disk\n"); 01041 return 0; 01042 } 01043 01044 // csd_structure : csd[127:126] 01045 int csd_structure = ext_bits(csd, 127, 126); 01046 switch (csd_structure) { 01047 case 0: 01048 c_size = ext_bits(csd, 73, 62); // c_size : csd[73:62] 01049 c_size_mult = ext_bits(csd, 49, 47); // c_size_mult : csd[49:47] 01050 read_bl_len = ext_bits(csd, 83, 80); // read_bl_len : csd[83:80] - the *maximum* read block length 01051 block_len = 1 << read_bl_len; // BLOCK_LEN = 2^READ_BL_LEN 01052 mult = 1 << (c_size_mult + 2); // MULT = 2^C_SIZE_MULT+2 (C_SIZE_MULT < 8) 01053 blocknr = (c_size + 1) * mult; // BLOCKNR = (C_SIZE+1) * MULT 01054 capacity = (bd_size_t) blocknr * block_len; // memory capacity = BLOCKNR * BLOCK_LEN 01055 blocks = capacity / _block_size; 01056 debug_if(SD_DBG, "Standard Capacity: c_size: %" PRIu32 " \n", c_size); 01057 debug_if(SD_DBG, "Sectors: 0x%" PRIx64 " : %" PRIu64 "\n", blocks, blocks); 01058 debug_if(SD_DBG, "Capacity: 0x%" PRIx64 " : %" PRIu64 " MB\n", capacity, (capacity / (1024U * 1024U))); 01059 01060 // ERASE_BLK_EN = 1: Erase in multiple of 512 bytes supported 01061 if (ext_bits(csd, 46, 46)) { 01062 _erase_size = BLOCK_SIZE_HC; 01063 } else { 01064 // ERASE_BLK_EN = 1: Erase in multiple of SECTOR_SIZE supported 01065 _erase_size = BLOCK_SIZE_HC * (ext_bits(csd, 45, 39) + 1); 01066 } 01067 break; 01068 01069 case 1: 01070 hc_c_size = ext_bits(csd, 69, 48); // device size : C_SIZE : [69:48] 01071 blocks = (hc_c_size + 1) << 10; // block count = C_SIZE+1) * 1K byte (512B is block size) 01072 debug_if(SD_DBG, "SDHC/SDXC Card: hc_c_size: %" PRIu32 " \n", hc_c_size); 01073 debug_if(SD_DBG, "Sectors: 0x%" PRIx64 "x : %" PRIu64 "\n", blocks, blocks); 01074 debug_if(SD_DBG, "Capacity: %" PRIu64 " MB\n", (blocks / (2048U))); 01075 // ERASE_BLK_EN is fixed to 1, which means host can erase one or multiple of 512 bytes. 01076 _erase_size = BLOCK_SIZE_HC; 01077 break; 01078 01079 default: 01080 debug_if(SD_DBG, "CSD struct unsupported\r\n"); 01081 return 0; 01082 }; 01083 return blocks; 01084 } 01085 01086 // SPI function to wait till chip is ready and sends start token 01087 bool SDBlockDevice::_wait_token(uint8_t token) 01088 { 01089 _spi_timer.reset(); 01090 _spi_timer.start(); 01091 01092 do { 01093 if (token == _spi.write(SPI_FILL_CHAR)) { 01094 _spi_timer.stop(); 01095 return true; 01096 } 01097 } while (_spi_timer.read_ms() < 300); // Wait for 300 msec for start token 01098 _spi_timer.stop(); 01099 debug_if(SD_DBG, "_wait_token: timeout\n"); 01100 return false; 01101 } 01102 01103 // SPI function to wait till chip is ready 01104 // The host controller should wait for end of the process until DO goes high (a 0xFF is received). 01105 bool SDBlockDevice::_wait_ready(uint16_t ms) 01106 { 01107 uint8_t response; 01108 _spi_timer.reset(); 01109 _spi_timer.start(); 01110 do { 01111 response = _spi.write(SPI_FILL_CHAR); 01112 if (response == 0xFF) { 01113 _spi_timer.stop(); 01114 return true; 01115 } 01116 } while (_spi_timer.read_ms() < ms); 01117 _spi_timer.stop(); 01118 return false; 01119 } 01120 01121 // SPI function to wait for count 01122 void SDBlockDevice::_spi_wait(uint8_t count) 01123 { 01124 for (uint8_t i = 0; i < count; ++i) { 01125 _spi.write(SPI_FILL_CHAR); 01126 } 01127 } 01128 01129 void SDBlockDevice::_spi_init() 01130 { 01131 _spi.lock(); 01132 // Set to SCK for initialization, and clock card with cs = 1 01133 _spi.frequency(_init_sck); 01134 _spi.format(8, 0); 01135 _spi.set_default_write_value(SPI_FILL_CHAR); 01136 // Initial 74 cycles required for few cards, before selecting SPI mode 01137 _cs = 1; 01138 _spi_wait(10); 01139 _spi.unlock(); 01140 } 01141 01142 void SDBlockDevice::_select() 01143 { 01144 _spi.lock(); 01145 _spi.write(SPI_FILL_CHAR); 01146 _cs = 0; 01147 } 01148 01149 void SDBlockDevice::_deselect() 01150 { 01151 _cs = 1; 01152 _spi.write(SPI_FILL_CHAR); 01153 _spi.unlock(); 01154 } 01155 01156 #endif /* DEVICE_SPI */
Generated on Tue Jul 12 2022 13:54:49 by
1.7.2