Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SDBlockDevice.h Source File

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 */