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.h
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 #ifndef MBED_SD_BLOCK_DEVICE_H 00018 #define MBED_SD_BLOCK_DEVICE_H 00019 00020 /* If the target has no SPI support, then SD Card is not supported. */ 00021 #if DEVICE_SPI 00022 00023 #include "features/storage/blockdevice/BlockDevice.h" 00024 #include "drivers/SPI.h" 00025 #include "drivers/Timer.h" 00026 #include "drivers/MbedCRC.h" 00027 #include "drivers/DigitalOut.h" 00028 #include "platform/platform.h" 00029 #include "platform/PlatformMutex.h" 00030 #include "hal/static_pinmap.h" 00031 00032 /** SDBlockDevice class 00033 * 00034 * Access an SD Card using SPI bus 00035 */ 00036 class SDBlockDevice : public mbed::BlockDevice { 00037 public: 00038 /** Creates an SDBlockDevice on a SPI bus specified by pins (using dynamic pin-map) 00039 * 00040 * @param mosi SPI master out, slave in pin 00041 * @param miso SPI master in, slave out pin 00042 * @param sclk SPI clock pin 00043 * @param cs SPI chip select pin 00044 * @param hz Clock speed of the SPI bus (defaults to 1MHz) 00045 * @param crc_on Enable cyclic redundancy check (defaults to disabled) 00046 */ 00047 SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz = 1000000, bool crc_on = 0); 00048 00049 /** Creates an SDBlockDevice on a SPI bus specified by pins (using static pin-map) 00050 * 00051 * @param spi_pinmap Static SPI pin-map 00052 * @param hz Clock speed of the SPI bus (defaults to 1MHz) 00053 * @param crc_on Enable cyclic redundancy check (defaults to disabled) 00054 */ 00055 SDBlockDevice(const spi_pinmap_t &spi_pinmap, PinName cs, uint64_t hz = 1000000, bool crc_on = 0); 00056 00057 virtual ~SDBlockDevice(); 00058 00059 /** Initialize a block device 00060 * 00061 * @return BD_ERROR_OK(0) - success 00062 * BD_ERROR_DEVICE_ERROR - device driver transaction failed 00063 * SD_BLOCK_DEVICE_ERROR_NO_DEVICE - device (SD card) is missing or not connected 00064 * SD_BLOCK_DEVICE_ERROR_UNUSABLE - unusable card 00065 * SD_BLOCK_DEVICE_ERROR_CRC - crc error 00066 */ 00067 virtual int init(); 00068 00069 /** Deinitialize a block device 00070 * 00071 * @return BD_ERROR_OK(0) - success 00072 */ 00073 virtual int deinit(); 00074 00075 /** Read blocks from a block device 00076 * 00077 * @param buffer Buffer to write blocks to 00078 * @param addr Address of block to begin reading from 00079 * @param size Size to read in bytes, must be a multiple of read block size 00080 * @return BD_ERROR_OK(0) - success 00081 * SD_BLOCK_DEVICE_ERROR_NO_DEVICE - device (SD card) is missing or not connected 00082 * SD_BLOCK_DEVICE_ERROR_CRC - crc error 00083 * SD_BLOCK_DEVICE_ERROR_PARAMETER - invalid parameter 00084 * SD_BLOCK_DEVICE_ERROR_NO_RESPONSE - no response from device 00085 * SD_BLOCK_DEVICE_ERROR_UNSUPPORTED - unsupported command 00086 */ 00087 virtual int read(void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size); 00088 00089 /** Program blocks to a block device 00090 * 00091 * @note The blocks must be erased prior to programming 00092 * 00093 * @param buffer Buffer of data to write to blocks 00094 * @param addr Address of block to begin writing to 00095 * @param size Size to write in bytes. Must be a multiple of program block size 00096 * @return BD_ERROR_OK(0) - success 00097 * SD_BLOCK_DEVICE_ERROR_NO_DEVICE - device (SD card) is missing or not connected 00098 * SD_BLOCK_DEVICE_ERROR_CRC - crc error 00099 * SD_BLOCK_DEVICE_ERROR_PARAMETER - invalid parameter 00100 * SD_BLOCK_DEVICE_ERROR_UNSUPPORTED - unsupported command 00101 * SD_BLOCK_DEVICE_ERROR_NO_INIT - device is not initialized 00102 * SD_BLOCK_DEVICE_ERROR_WRITE - SPI write error 00103 * SD_BLOCK_DEVICE_ERROR_ERASE - erase error 00104 */ 00105 virtual int program(const void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size); 00106 00107 /** Mark blocks as no longer in use 00108 * 00109 * This function provides a hint to the underlying block device that a region of blocks 00110 * is no longer in use and may be erased without side effects. Erase must still be called 00111 * before programming, but trimming allows flash-translation-layers to schedule erases when 00112 * the device is not busy. 00113 * 00114 * @param addr Address of block to mark as unused 00115 * @param size Size to mark as unused in bytes, must be a multiple of erase block size 00116 * @return BD_ERROR_OK(0) - success 00117 * SD_BLOCK_DEVICE_ERROR_NO_DEVICE - device (SD card) is missing or not connected 00118 * SD_BLOCK_DEVICE_ERROR_CRC - crc error 00119 * SD_BLOCK_DEVICE_ERROR_PARAMETER - invalid parameter 00120 * SD_BLOCK_DEVICE_ERROR_UNSUPPORTED - unsupported command 00121 * SD_BLOCK_DEVICE_ERROR_NO_INIT - device is not initialized 00122 * SD_BLOCK_DEVICE_ERROR_ERASE - erase error 00123 */ 00124 virtual int trim(mbed::bd_addr_t addr, mbed::bd_size_t size); 00125 00126 /** Get the size of a readable block 00127 * 00128 * @return Size of a readable block in bytes 00129 */ 00130 virtual mbed::bd_size_t get_read_size() const; 00131 00132 /** Get the size of a programmable block 00133 * 00134 * @return Size of a programmable block in bytes 00135 * @note Must be a multiple of the read size 00136 */ 00137 virtual mbed::bd_size_t get_program_size() const; 00138 00139 /** Get the total size of the underlying device 00140 * 00141 * @return Size of the underlying device in bytes 00142 */ 00143 virtual mbed::bd_size_t size() const; 00144 00145 /** Enable or disable debugging 00146 * 00147 * @param dbg State of debugging 00148 */ 00149 virtual void debug(bool dbg); 00150 00151 /** Set the transfer frequency 00152 * 00153 * @param freq Transfer frequency 00154 * @note Max frequency supported is 25MHZ 00155 */ 00156 virtual int frequency(uint64_t freq); 00157 00158 /** Get the BlockDevice class type. 00159 * 00160 * @return A string representation of the BlockDevice class type. 00161 */ 00162 virtual const char *get_type() const; 00163 00164 private: 00165 /* Commands : Listed below are commands supported 00166 * in SPI mode for SD card : Only Mandatory ones 00167 */ 00168 enum cmdSupported { 00169 CMD_NOT_SUPPORTED = -1, /**< Command not supported error */ 00170 CMD0_GO_IDLE_STATE = 0, /**< Resets the SD Memory Card */ 00171 CMD1_SEND_OP_COND = 1, /**< Sends host capacity support */ 00172 CMD6_SWITCH_FUNC = 6, /**< Check and Switches card function */ 00173 CMD8_SEND_IF_COND = 8, /**< Supply voltage info */ 00174 CMD9_SEND_CSD = 9, /**< Provides Card Specific data */ 00175 CMD10_SEND_CID = 10, /**< Provides Card Identification */ 00176 CMD12_STOP_TRANSMISSION = 12, /**< Forces the card to stop transmission */ 00177 CMD13_SEND_STATUS = 13, /**< Card responds with status */ 00178 CMD16_SET_BLOCKLEN = 16, /**< Length for SC card is set */ 00179 CMD17_READ_SINGLE_BLOCK = 17, /**< Read single block of data */ 00180 CMD18_READ_MULTIPLE_BLOCK = 18, /**< Card transfers data blocks to host until interrupted 00181 by a STOP_TRANSMISSION command */ 00182 CMD24_WRITE_BLOCK = 24, /**< Write single block of data */ 00183 CMD25_WRITE_MULTIPLE_BLOCK = 25, /**< Continuously writes blocks of data until 00184 'Stop Tran' token is sent */ 00185 CMD27_PROGRAM_CSD = 27, /**< Programming bits of CSD */ 00186 CMD32_ERASE_WR_BLK_START_ADDR = 32, /**< Sets the address of the first write 00187 block to be erased. */ 00188 CMD33_ERASE_WR_BLK_END_ADDR = 33, /**< Sets the address of the last write 00189 block of the continuous range to be erased.*/ 00190 CMD38_ERASE = 38, /**< Erases all previously selected write blocks */ 00191 CMD55_APP_CMD = 55, /**< Extend to Applications specific commands */ 00192 CMD56_GEN_CMD = 56, /**< General Purpose Command */ 00193 CMD58_READ_OCR = 58, /**< Read OCR register of card */ 00194 CMD59_CRC_ON_OFF = 59, /**< Turns the CRC option on or off*/ 00195 // App Commands 00196 ACMD6_SET_BUS_WIDTH = 6, 00197 ACMD13_SD_STATUS = 13, 00198 ACMD22_SEND_NUM_WR_BLOCKS = 22, 00199 ACMD23_SET_WR_BLK_ERASE_COUNT = 23, 00200 ACMD41_SD_SEND_OP_COND = 41, 00201 ACMD42_SET_CLR_CARD_DETECT = 42, 00202 ACMD51_SEND_SCR = 51, 00203 }; 00204 00205 uint8_t _card_type; 00206 int _cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAcmd = 0, uint32_t *resp = NULL); 00207 int _cmd8(); 00208 00209 /* Move the SD Card into the SPI Mode idle state 00210 * 00211 * The card is transitioned from SD Card mode to SPI mode by sending the 00212 * CMD0 (GO_IDLE_STATE) command with CS asserted. See the notes in the 00213 * "SPI Startup" section of the comments at the head of the 00214 * implementation file for further details and specification references. 00215 * 00216 * @return Response form the card. R1_IDLE_STATE (0x1), the successful 00217 * response from CMD0. R1_XXX_XXX for more response 00218 */ 00219 uint32_t _go_idle_state(); 00220 int _initialise_card(); 00221 00222 mbed::bd_size_t _sectors; 00223 mbed::bd_size_t _sd_sectors(); 00224 00225 bool _is_valid_trim(mbed::bd_addr_t addr, mbed::bd_size_t size); 00226 00227 /* SPI functions */ 00228 mbed::Timer _spi_timer; /**< Timer Class object used for busy wait */ 00229 uint32_t _init_sck; /**< Initial SPI frequency */ 00230 uint32_t _transfer_sck; /**< SPI frequency during data transfer/after initialization */ 00231 mbed::SPI _spi; /**< SPI Class object */ 00232 00233 /* SPI initialization function */ 00234 void _spi_init(); 00235 uint8_t _cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg); 00236 void _spi_wait(uint8_t count); 00237 00238 bool _wait_token(uint8_t token); /**< Wait for token */ 00239 bool _wait_ready(uint16_t ms = 300); /**< 300ms default wait for card to be ready */ 00240 int _read(uint8_t *buffer, uint32_t length); 00241 int _read_bytes(uint8_t *buffer, uint32_t length); 00242 uint8_t _write(const uint8_t *buffer, uint8_t token, uint32_t length); 00243 int _freq(void); 00244 00245 /* Chip Select and SPI mode select */ 00246 mbed::DigitalOut _cs; 00247 void _select(); 00248 void _deselect(); 00249 00250 virtual void lock() 00251 { 00252 _mutex.lock(); 00253 } 00254 00255 virtual void unlock() 00256 { 00257 _mutex.unlock(); 00258 } 00259 00260 PlatformMutex _mutex; 00261 static const uint32_t _block_size; 00262 uint32_t _erase_size; 00263 bool _is_initialized; 00264 bool _dbg; 00265 uint32_t _init_ref_count; 00266 00267 #if MBED_CONF_SD_CRC_ENABLED 00268 bool _crc_on; 00269 #endif 00270 }; 00271 00272 #endif /* DEVICE_SPI */ 00273 00274 #endif /* MBED_SD_BLOCK_DEVICE_H */
Generated on Tue Jul 12 2022 13:54:49 by
