A re-written SDFileSystem library with improved compatibility, CRC support, and card removal/replacement support.

Dependencies:   FATFileSystem

Dependents:   xadow_m0_SD_Hello roam_v1 roam_v2 Polytech_tours ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SDFileSystem.h Source File

SDFileSystem.h

00001 /* SD/MMC File System Library
00002  * Copyright (c) 2016 Neil Thiessen
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 SD_FILE_SYSTEM_H
00018 #define SD_FILE_SYSTEM_H
00019 
00020 #include "mbed.h"
00021 #include "FATFileSystem.h"
00022 
00023 /** SDFileSystem class.
00024  *  Used for creating a virtual file system for accessing SD/MMC cards via SPI.
00025  *
00026  * Example:
00027  * @code
00028  * #include "mbed.h"
00029  * #include "SDFileSystem.h"
00030  *
00031  * //Create an SDFileSystem object
00032  * SDFileSystem sd(p5, p6, p7, p20, "sd");
00033  *
00034  * int main()
00035  * {
00036  *     //Mount the filesystem
00037  *     sd.mount();
00038  *
00039  *     //Perform a write test
00040  *     printf("\nWriting to SD card...");
00041  *     FILE *fp = fopen("/sd/sdtest.txt", "w");
00042  *     if (fp != NULL) {
00043  *         fprintf(fp, "We're writing to an SD card!");
00044  *         fclose(fp);
00045  *         printf("success!\n");
00046  *     } else {
00047  *         printf("failed!\n");
00048  *     }
00049  *
00050  *     //Perform a read test
00051  *     printf("Reading from SD card...");
00052  *     fp = fopen("/sd/sdtest.txt", "r");
00053  *     if (fp != NULL) {
00054  *         char c = fgetc(fp);
00055  *         if (c == 'W')
00056  *             printf("success!\n");
00057  *         else
00058  *             printf("incorrect char (%c)!\n", c);
00059  *         fclose(fp);
00060  *     } else {
00061  *         printf("failed!\n");
00062  *     }
00063  *
00064  *     //Unmount the filesystem
00065  *     sd.unmount();
00066  * }
00067  * @endcode
00068  */
00069 class SDFileSystem : public FATFileSystem
00070 {
00071 public:
00072     /** Represents the different card detect switch types
00073      */
00074     enum SwitchType {
00075         SWITCH_NONE,    /**< No card detect switch (assumes socket is always occupied) */
00076         SWITCH_POS_NO,  /**< Switch shorts to VDD when the socket is occupied (positive logic, normally open) */
00077         SWITCH_POS_NC,  /**< Switch shorts to VDD when the socket is empty (positive logic, normally closed) */
00078         SWITCH_NEG_NO,  /**< Switch shorts to GND when the socket is occupied (negative logic, normally open) */
00079         SWITCH_NEG_NC   /**< Switch shorts to GND when the socket is empty (negative logic, normally closed) */
00080     };
00081 
00082     /** Represents the different SD/MMC card types
00083      */
00084     enum CardType {
00085         CARD_NONE,      /**< No card is present */
00086         CARD_MMC,       /**< MMC card */
00087         CARD_SD,        /**< Standard capacity SD card */
00088         CARD_SDHC,      /**< High capacity SD card */
00089         CARD_UNKNOWN    /**< Unknown or unsupported card */
00090     };
00091 
00092     /** Create a virtual file system for accessing SD/MMC cards via SPI
00093      *
00094      * @param mosi The SPI data out pin.
00095      * @param miso The SPI data in pin.
00096      * @param sclk The SPI clock pin.
00097      * @param cs The SPI chip select pin.
00098      * @param name The name used to access the virtual filesystem.
00099      * @param cd The card detect pin.
00100      * @param cdtype The type of card detect switch.
00101      * @param hz The SPI bus frequency (defaults to 1MHz).
00102      */
00103     SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name, PinName cd = NC, SwitchType cdtype = SWITCH_NONE, int hz = 1000000);
00104 
00105     /** Determine whether or not a card is present
00106      *
00107      * @returns
00108      *   'true' if a card is present,
00109      *   'false' if no card is present.
00110      */
00111     bool card_present();
00112 
00113     /** Get the detected SD/MMC card type
00114      *
00115      * @returns The detected card type as a CardType enum.
00116      *
00117      * @note Valid after the filesystem has been mounted.
00118      */
00119     SDFileSystem::CardType card_type();
00120 
00121     /** Get whether or not CRC is enabled for commands and data
00122      *
00123      * @returns
00124      *   'true' if CRC is enabled for commands and data,
00125      *   'false' if CRC is disabled for commands and data.
00126      */
00127     bool crc();
00128 
00129     /** Set whether or not CRC is enabled for commands and data
00130      *
00131      * @param enabled Whether or not to enable CRC for commands and data.
00132      */
00133     void crc(bool enabled);
00134 
00135     /** Get whether or not 16-bit frames are enabled for data read/write operations
00136      *
00137      * @returns
00138      *   'true' if 16-bit frames will be used during data read/write operations,
00139      *   'false' if 8-bit frames will be used during data read/write operations.
00140      */
00141     bool large_frames();
00142 
00143     /** Set whether or not 16-bit frames are enabled for data read/write operations
00144      *
00145      * @param enabled Whether or not 16-bit frames are enabled for data read/write operations.
00146      */
00147     void large_frames(bool enabled);
00148 
00149     /** Get whether or not write validation is enabled for data write operations
00150      *
00151      * @returns
00152      *   'true' if data writes will be verified using CMD13,
00153      *   'false' if data writes will not be verified.
00154      */
00155     bool write_validation();
00156 
00157     /** Set whether or not write validation is enabled for data write operations
00158      *
00159      * @param enabled Whether or not write validation is enabled for data write operations.
00160      */
00161     void write_validation(bool enabled);
00162 
00163     virtual int unmount();
00164     virtual int disk_initialize();
00165     virtual int disk_status();
00166     virtual int disk_read(uint8_t* buffer, uint32_t sector, uint32_t count);
00167     virtual int disk_write(const uint8_t* buffer, uint32_t sector, uint32_t count);
00168     virtual int disk_sync();
00169     virtual uint32_t disk_sectors();
00170 
00171 private:
00172     //Commands
00173     enum Command {
00174         CMD0 = (0x40 | 0),      /**< GO_IDLE_STATE */
00175         CMD1 = (0x40 | 1),      /**< SEND_OP_COND */
00176         CMD6 = (0x40 | 6),      /**< SWITCH_FUNC */
00177         CMD8 = (0x40 | 8),      /**< SEND_IF_COND */
00178         CMD9 = (0x40 | 9),      /**< SEND_CSD */
00179         CMD12 = (0x40 | 12),    /**< STOP_TRANSMISSION */
00180         CMD13 = (0x40 | 13),    /**< SEND_STATUS */
00181         CMD16 = (0x40 | 16),    /**< SET_BLOCKLEN */
00182         CMD17 = (0x40 | 17),    /**< READ_SINGLE_BLOCK */
00183         CMD18 = (0x40 | 18),    /**< READ_MULTIPLE_BLOCK */
00184         ACMD22 = (0x40 | 22),   /**< SEND_NUM_WR_BLOCKS */
00185         ACMD23 = (0x40 | 23),   /**< SET_WR_BLK_ERASE_COUNT */
00186         CMD24 = (0x40 | 24),    /**< WRITE_BLOCK */
00187         CMD25 = (0x40 | 25),    /**< WRITE_MULTIPLE_BLOCK */
00188         ACMD41 = (0x40 | 41),   /**< SD_SEND_OP_COND */
00189         ACMD42 = (0x40 | 42),   /**< SET_CLR_CARD_DETECT */
00190         CMD55 = (0x40 | 55),    /**< APP_CMD */
00191         CMD58 = (0x40 | 58),    /**< READ_OCR */
00192         CMD59 = (0x40 | 59)     /**< CRC_ON_OFF */
00193     };
00194 
00195     //Member variables
00196     Timer m_Timer;
00197     SPI m_Spi;
00198     DigitalOut m_Cs;
00199     InterruptIn m_Cd;
00200     int m_CdAssert;
00201     const int m_FREQ;
00202     SDFileSystem::CardType m_CardType;
00203     bool m_Crc;
00204     bool m_LargeFrames;
00205     bool m_WriteValidation;
00206     int m_Status;
00207 
00208     //Internal methods
00209     void onCardRemoval();
00210     void checkSocket();
00211     bool waitReady(int timeout);
00212     bool select();
00213     void deselect();
00214     char commandTransaction(char cmd, unsigned int arg, unsigned int* resp = NULL);
00215     char writeCommand(char cmd, unsigned int arg, unsigned int* resp = NULL);
00216     bool readData(char* buffer, int length);
00217     char writeData(const char* buffer, char token);
00218     bool readBlock(char* buffer, unsigned int lba);
00219     bool readBlocks(char* buffer, unsigned int lba, unsigned int count);
00220     bool writeBlock(const char* buffer, unsigned int lba);
00221     bool writeBlocks(const char* buffer, unsigned int lba, unsigned int count);
00222     bool enableHighSpeedMode();
00223 };
00224 
00225 #endif