takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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