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.
Fork of Wio_3G-example-sd-driver by
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 SDCard is not supported */ 00021 #ifdef DEVICE_SPI 00022 00023 #include "BlockDevice.h" 00024 #include "mbed.h" 00025 #include "platform/PlatformMutex.h" 00026 00027 /** Access an SD Card using SPI 00028 * 00029 * @code 00030 * #include "mbed.h" 00031 * #include "SDBlockDevice.h" 00032 * 00033 * SDBlockDevice sd(p5, p6, p7, p12); // mosi, miso, sclk, cs 00034 * uint8_t block[512] = "Hello World!\n"; 00035 * 00036 * int main() { 00037 * sd.init(); 00038 * sd.write(block, 0, 512); 00039 * sd.read(block, 0, 512); 00040 * printf("%s", block); 00041 * sd.deinit(); 00042 * } 00043 */ 00044 class SDBlockDevice : public BlockDevice { 00045 public: 00046 /** Lifetime of an SD card 00047 */ 00048 SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz=1000000, bool crc_on=0); 00049 virtual ~SDBlockDevice(); 00050 00051 /** Initialize a block device 00052 * 00053 * @return 0 on success or a negative error code on failure 00054 */ 00055 virtual int init(); 00056 00057 /** Deinitialize a block device 00058 * 00059 * @return 0 on success or a negative error code on failure 00060 */ 00061 virtual int deinit(); 00062 00063 /** Read blocks from a block device 00064 * 00065 * @param buffer Buffer to write blocks to 00066 * @param addr Address of block to begin reading from 00067 * @param size Size to read in bytes, must be a multiple of read block size 00068 * @return 0 on success, negative error code on failure 00069 */ 00070 virtual int read(void *buffer, bd_addr_t addr, bd_size_t size); 00071 00072 /** Program blocks to a block device 00073 * 00074 * The blocks must have been erased prior to being programmed 00075 * 00076 * @param buffer Buffer of data to write to blocks 00077 * @param addr Address of block to begin writing to 00078 * @param size Size to write in bytes, must be a multiple of program block size 00079 * @return 0 on success, negative error code on failure 00080 */ 00081 virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size); 00082 00083 /** Mark blocks as no longer in use 00084 * 00085 * This function provides a hint to the underlying block device that a region of blocks 00086 * is no longer in use and may be erased without side effects. Erase must still be called 00087 * before programming, but trimming allows flash-translation-layers to schedule erases when 00088 * the device is not busy. 00089 * 00090 * @param addr Address of block to mark as unused 00091 * @param size Size to mark as unused in bytes, must be a multiple of erase block size 00092 * @return 0 on success, negative error code on failure 00093 */ 00094 virtual int trim(bd_addr_t addr, bd_size_t size); 00095 00096 /** Get the size of a readable block 00097 * 00098 * @return Size of a readable block in bytes 00099 */ 00100 virtual bd_size_t get_read_size() const; 00101 00102 /** Get the size of a programable block 00103 * 00104 * @return Size of a programable block in bytes 00105 * @note Must be a multiple of the read size 00106 */ 00107 virtual bd_size_t get_program_size() const; 00108 00109 /** Get the total size of the underlying device 00110 * 00111 * @return Size of the underlying device in bytes 00112 */ 00113 virtual bd_size_t size() const; 00114 00115 /** Enable or disable debugging 00116 * 00117 * @param State of debugging 00118 */ 00119 virtual void debug(bool dbg); 00120 00121 /** Set the transfer frequency 00122 * 00123 * @param Transfer frequency 00124 * @note Max frequency supported is 25MHZ 00125 */ 00126 virtual int frequency(uint64_t freq); 00127 00128 00129 private: 00130 /* Commands : Listed below are commands supported 00131 * in SPI mode for SD card : Only Mandatory ones 00132 */ 00133 enum cmdSupported { 00134 CMD_NOT_SUPPORTED = -1, /**< Command not supported error */ 00135 CMD0_GO_IDLE_STATE = 0, /**< Resets the SD Memory Card */ 00136 CMD1_SEND_OP_COND = 1, /**< Sends host capacity support */ 00137 CMD6_SWITCH_FUNC = 6, /**< Check and Switches card function */ 00138 CMD8_SEND_IF_COND = 8, /**< Supply voltage info */ 00139 CMD9_SEND_CSD = 9, /**< Provides Card Specific data */ 00140 CMD10_SEND_CID = 10, /**< Provides Card Identification */ 00141 CMD12_STOP_TRANSMISSION = 12, /**< Forces the card to stop transmission */ 00142 CMD13_SEND_STATUS = 13, /**< Card responds with status */ 00143 CMD16_SET_BLOCKLEN = 16, /**< Length for SC card is set */ 00144 CMD17_READ_SINGLE_BLOCK = 17, /**< Read single block of data */ 00145 CMD18_READ_MULTIPLE_BLOCK = 18, /**< Card transfers data blocks to host until interrupted 00146 by a STOP_TRANSMISSION command */ 00147 CMD24_WRITE_BLOCK = 24, /**< Write single block of data */ 00148 CMD25_WRITE_MULTIPLE_BLOCK = 25, /**< Continuously writes blocks of data until 00149 'Stop Tran' token is sent */ 00150 CMD27_PROGRAM_CSD = 27, /**< Programming bits of CSD */ 00151 CMD32_ERASE_WR_BLK_START_ADDR = 32, /**< Sets the address of the first write 00152 block to be erased. */ 00153 CMD33_ERASE_WR_BLK_END_ADDR = 33, /**< Sets the address of the last write 00154 block of the continuous range to be erased.*/ 00155 CMD38_ERASE = 38, /**< Erases all previously selected write blocks */ 00156 CMD55_APP_CMD = 55, /**< Extend to Applications specific commands */ 00157 CMD56_GEN_CMD = 56, /**< General Purpose Command */ 00158 CMD58_READ_OCR = 58, /**< Read OCR register of card */ 00159 CMD59_CRC_ON_OFF = 59, /**< Turns the CRC option on or off*/ 00160 // App Commands 00161 ACMD6_SET_BUS_WIDTH = 6, 00162 ACMD13_SD_STATUS = 13, 00163 ACMD22_SEND_NUM_WR_BLOCKS = 22, 00164 ACMD23_SET_WR_BLK_ERASE_COUNT = 23, 00165 ACMD41_SD_SEND_OP_COND = 41, 00166 ACMD42_SET_CLR_CARD_DETECT = 42, 00167 ACMD51_SEND_SCR = 51, 00168 }; 00169 00170 uint8_t _card_type; 00171 int _cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAcmd=0, uint32_t *resp=NULL); 00172 int _cmd8(); 00173 00174 /* Move the SDCard into the SPI Mode idle state 00175 * 00176 * The card is transitioned from SDCard mode to SPI mode by sending the 00177 * CMD0 (GO_IDLE_STATE) command with CS asserted. See the notes in the 00178 * "SPI Startup" section of the comments at the head of the 00179 * implementation file for further details and specification references. 00180 * 00181 * @return Response form the card. R1_IDLE_STATE (0x1), the successful 00182 * response from CMD0. R1_XXX_XXX for more response 00183 */ 00184 uint32_t _go_idle_state(); 00185 int _initialise_card(); 00186 00187 bd_size_t _sectors; 00188 bd_size_t _sd_sectors(); 00189 00190 bool _is_valid_trim(bd_addr_t addr, bd_size_t size); 00191 00192 /* SPI functions */ 00193 Timer _spi_timer; /**< Timer Class object used for busy wait */ 00194 uint32_t _init_sck; /**< Intial SPI frequency */ 00195 uint32_t _transfer_sck; /**< SPI frequency during data transfer/after initialization */ 00196 SPI _spi; /**< SPI Class object */ 00197 00198 /* SPI initialization function */ 00199 void _spi_init(); 00200 uint8_t _cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg); 00201 void _spi_wait(uint8_t count); 00202 00203 bool _wait_token(uint8_t token); /**< Wait for token */ 00204 bool _wait_ready(uint16_t ms=300); /**< 300ms default wait for card to be ready */ 00205 int _read(uint8_t * buffer, uint32_t length); 00206 int _read_bytes(uint8_t * buffer, uint32_t length); 00207 uint8_t _write(const uint8_t *buffer,uint8_t token, uint32_t length); 00208 int _freq(void); 00209 00210 /* Chip Select and SPI mode select */ 00211 DigitalOut _cs; 00212 void _select(); 00213 void _deselect(); 00214 00215 virtual void lock() { 00216 _mutex.lock(); 00217 } 00218 00219 virtual void unlock() { 00220 _mutex.unlock(); 00221 } 00222 00223 PlatformMutex _mutex; 00224 bd_size_t _block_size; 00225 bd_size_t _erase_size; 00226 bool _is_initialized; 00227 bool _dbg; 00228 bool _crc_on; 00229 00230 MbedCRC<POLY_7BIT_SD, 7> _crc7; 00231 MbedCRC<POLY_16BIT_CCITT, 16> _crc16; 00232 }; 00233 00234 #endif /* DEVICE_SPI */ 00235 00236 #endif /* MBED_SD_BLOCK_DEVICE_H */
Generated on Thu Jul 21 2022 12:40:42 by
1.7.2
