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

Committer:
neilt6
Date:
Wed Jul 30 17:51:33 2014 +0000
Revision:
4:49b29888eca7
Parent:
3:7cf3d1835ef5
Child:
5:6befff2300d0
Added 0x40 to command definitions for (slightly) improved performance

Who changed what in which revision?

UserRevisionLine numberNew contents of line
neilt6 0:2a6d8a096edc 1 /* SD/MMC File System Library
neilt6 0:2a6d8a096edc 2 * Copyright (c) 2014 Neil Thiessen
neilt6 0:2a6d8a096edc 3 *
neilt6 0:2a6d8a096edc 4 * Licensed under the Apache License, Version 2.0 (the "License");
neilt6 0:2a6d8a096edc 5 * you may not use this file except in compliance with the License.
neilt6 0:2a6d8a096edc 6 * You may obtain a copy of the License at
neilt6 0:2a6d8a096edc 7 *
neilt6 0:2a6d8a096edc 8 * http://www.apache.org/licenses/LICENSE-2.0
neilt6 0:2a6d8a096edc 9 *
neilt6 0:2a6d8a096edc 10 * Unless required by applicable law or agreed to in writing, software
neilt6 0:2a6d8a096edc 11 * distributed under the License is distributed on an "AS IS" BASIS,
neilt6 0:2a6d8a096edc 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
neilt6 0:2a6d8a096edc 13 * See the License for the specific language governing permissions and
neilt6 0:2a6d8a096edc 14 * limitations under the License.
neilt6 0:2a6d8a096edc 15 */
neilt6 0:2a6d8a096edc 16
neilt6 0:2a6d8a096edc 17 #ifndef SD_FILE_SYSTEM_H
neilt6 0:2a6d8a096edc 18 #define SD_FILE_SYSTEM_H
neilt6 0:2a6d8a096edc 19
neilt6 0:2a6d8a096edc 20 #include "mbed.h"
neilt6 0:2a6d8a096edc 21 #include "FATFileSystem.h"
neilt6 0:2a6d8a096edc 22 #include <stdint.h>
neilt6 0:2a6d8a096edc 23
neilt6 0:2a6d8a096edc 24 /** SDFileSystem class.
neilt6 0:2a6d8a096edc 25 * Used for creating a virtual file system for accessing SD/MMC cards via SPI.
neilt6 0:2a6d8a096edc 26 *
neilt6 0:2a6d8a096edc 27 * Example:
neilt6 0:2a6d8a096edc 28 * @code
neilt6 0:2a6d8a096edc 29 * #include "mbed.h"
neilt6 0:2a6d8a096edc 30 * #include "SDFileSystem.h"
neilt6 0:2a6d8a096edc 31 *
neilt6 0:2a6d8a096edc 32 * //Create an SDFileSystem object
neilt6 0:2a6d8a096edc 33 * SDFileSystem sd(p5, p6, p7, p19, p20, "sd")
neilt6 0:2a6d8a096edc 34 *
neilt6 0:2a6d8a096edc 35 * int main()
neilt6 0:2a6d8a096edc 36 * {
neilt6 0:2a6d8a096edc 37 * //Perform a write test
neilt6 0:2a6d8a096edc 38 * printf("\nWriting to SD card...");
neilt6 0:2a6d8a096edc 39 * FILE *fp = fopen("/sd/sdtest.txt", "w");
neilt6 0:2a6d8a096edc 40 * if (fp != NULL) {
neilt6 0:2a6d8a096edc 41 * fprintf(fp, "We're writing to an SD card!");
neilt6 0:2a6d8a096edc 42 * fclose(fp);
neilt6 0:2a6d8a096edc 43 * printf("success!\n");
neilt6 0:2a6d8a096edc 44 * } else {
neilt6 0:2a6d8a096edc 45 * printf("failed!\n");
neilt6 0:2a6d8a096edc 46 * }
neilt6 0:2a6d8a096edc 47 *
neilt6 0:2a6d8a096edc 48 * //Perform a read test
neilt6 0:2a6d8a096edc 49 * printf("Reading from SD card...");
neilt6 0:2a6d8a096edc 50 * fp = fopen("/sd/sdtest.txt", "r");
neilt6 0:2a6d8a096edc 51 * if (fp != NULL) {
neilt6 0:2a6d8a096edc 52 * char c = fgetc(fp);
neilt6 0:2a6d8a096edc 53 * if (c == 'W')
neilt6 0:2a6d8a096edc 54 * printf("success!\n");
neilt6 0:2a6d8a096edc 55 * else
neilt6 0:2a6d8a096edc 56 * printf("incorrect char (%c)!\n", c);
neilt6 0:2a6d8a096edc 57 * fclose(fp);
neilt6 0:2a6d8a096edc 58 * } else {
neilt6 0:2a6d8a096edc 59 * printf("failed!\n");
neilt6 0:2a6d8a096edc 60 * }
neilt6 0:2a6d8a096edc 61 * }
neilt6 0:2a6d8a096edc 62 * @endcode
neilt6 0:2a6d8a096edc 63 */
neilt6 0:2a6d8a096edc 64 class SDFileSystem : public FATFileSystem
neilt6 0:2a6d8a096edc 65 {
neilt6 0:2a6d8a096edc 66 public:
neilt6 1:25f4ba436b81 67 /** Represents the different card detect switch types
neilt6 1:25f4ba436b81 68 */
neilt6 1:25f4ba436b81 69 enum SwitchType {
neilt6 1:25f4ba436b81 70 SWITCH_NO = 0, /**< Switch shorts to GND when the socket is occupied (normally open) */
neilt6 1:25f4ba436b81 71 SWITCH_NC = 1 /**< Switch shorts to GND when the socket is empty (normally closed) */
neilt6 1:25f4ba436b81 72 };
neilt6 1:25f4ba436b81 73
neilt6 0:2a6d8a096edc 74 /** Represents the different SD/MMC card types
neilt6 0:2a6d8a096edc 75 */
neilt6 0:2a6d8a096edc 76 enum CardType {
neilt6 0:2a6d8a096edc 77 CARD_NONE, /**< No card is present */
neilt6 0:2a6d8a096edc 78 CARD_MMC, /**< MMC card */
neilt6 0:2a6d8a096edc 79 CARD_SD, /**< Standard capacity SD card */
neilt6 0:2a6d8a096edc 80 CARD_SDHC, /**< High capacity SD card */
neilt6 0:2a6d8a096edc 81 CARD_UNKNOWN /**< Unknown or unsupported card */
neilt6 0:2a6d8a096edc 82 };
neilt6 0:2a6d8a096edc 83
neilt6 0:2a6d8a096edc 84 /** Create a virtual file system for accessing SD/MMC cards via SPI
neilt6 0:2a6d8a096edc 85 *
neilt6 0:2a6d8a096edc 86 * @param mosi The SPI data out pin.
neilt6 0:2a6d8a096edc 87 * @param miso The SPI data in pin.
neilt6 0:2a6d8a096edc 88 * @param sclk The SPI clock pin.
neilt6 0:2a6d8a096edc 89 * @param cs The SPI chip select pin.
neilt6 3:7cf3d1835ef5 90 * @param name The name used to access the virtual filesystem.
neilt6 1:25f4ba436b81 91 * @param cd The card detect pin.
neilt6 1:25f4ba436b81 92 * @param cdtype The type of card detect switch (defaults to SWITCH_NO).
neilt6 0:2a6d8a096edc 93 * @param hz The SPI bus frequency (defaults to 1MHz).
neilt6 0:2a6d8a096edc 94 */
neilt6 3:7cf3d1835ef5 95 SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name, PinName cd, SwitchType cdtype = SWITCH_NO, int hz = 1000000);
neilt6 0:2a6d8a096edc 96
neilt6 0:2a6d8a096edc 97 /** Get the detected SD/MMC card type
neilt6 0:2a6d8a096edc 98 *
neilt6 0:2a6d8a096edc 99 * @returns The detected card type as a CardType enum.
neilt6 0:2a6d8a096edc 100 */
neilt6 0:2a6d8a096edc 101 SDFileSystem::CardType card_type();
neilt6 0:2a6d8a096edc 102
neilt6 0:2a6d8a096edc 103 virtual int disk_initialize();
neilt6 0:2a6d8a096edc 104 virtual int disk_status();
neilt6 0:2a6d8a096edc 105 virtual int disk_read(uint8_t* buffer, uint64_t sector);
neilt6 0:2a6d8a096edc 106 virtual int disk_write(const uint8_t* buffer, uint64_t sector);
neilt6 0:2a6d8a096edc 107 virtual int disk_sync();
neilt6 0:2a6d8a096edc 108 virtual uint64_t disk_sectors();
neilt6 0:2a6d8a096edc 109
neilt6 0:2a6d8a096edc 110 private:
neilt6 0:2a6d8a096edc 111 //Commands
neilt6 0:2a6d8a096edc 112 enum Command {
neilt6 4:49b29888eca7 113 CMD0 = (0x40 | 0), /**< GO_IDLE_STATE */
neilt6 4:49b29888eca7 114 CMD1 = (0x40 | 1), /**< SEND_OP_COND */
neilt6 4:49b29888eca7 115 ACMD41 = (0x40 | 41), /**< APP_SEND_OP_COND */
neilt6 4:49b29888eca7 116 CMD8 = (0x40 | 8), /**< SEND_IF_COND */
neilt6 4:49b29888eca7 117 CMD9 = (0x40 | 9), /**< SEND_CSD */
neilt6 4:49b29888eca7 118 CMD16 = (0x40 | 16), /**< SET_BLOCKLEN */
neilt6 4:49b29888eca7 119 CMD17 = (0x40 | 17), /**< READ_SINGLE_BLOCK */
neilt6 4:49b29888eca7 120 CMD24 = (0x40 | 24), /**< WRITE_BLOCK */
neilt6 4:49b29888eca7 121 CMD55 = (0x40 | 55), /**< APP_CMD */
neilt6 4:49b29888eca7 122 CMD58 = (0x40 | 58), /**< READ_OCR */
neilt6 4:49b29888eca7 123 CMD59 = (0x40 | 59) /**< CRC_ON_OFF */
neilt6 0:2a6d8a096edc 124 };
neilt6 0:2a6d8a096edc 125
neilt6 0:2a6d8a096edc 126 //Member variables
neilt6 0:2a6d8a096edc 127 SPI m_SPI;
neilt6 0:2a6d8a096edc 128 DigitalOut m_CS;
neilt6 0:2a6d8a096edc 129 InterruptIn m_CD;
neilt6 1:25f4ba436b81 130 const int m_CD_ASSERT;
neilt6 0:2a6d8a096edc 131 int m_SpiFreq;
neilt6 0:2a6d8a096edc 132 int m_Status;
neilt6 0:2a6d8a096edc 133 SDFileSystem::CardType m_CardType;
neilt6 0:2a6d8a096edc 134
neilt6 0:2a6d8a096edc 135 //Internal methods
neilt6 0:2a6d8a096edc 136 void checkSocket();
neilt6 0:2a6d8a096edc 137 bool waitReady(int timeout);
neilt6 0:2a6d8a096edc 138 bool select();
neilt6 0:2a6d8a096edc 139 void deselect();
neilt6 0:2a6d8a096edc 140 char writeCommand(char cmd, unsigned int arg);
neilt6 0:2a6d8a096edc 141 unsigned int readReturn();
neilt6 0:2a6d8a096edc 142 bool readData(char* buffer, int length);
neilt6 0:2a6d8a096edc 143 };
neilt6 0:2a6d8a096edc 144
neilt6 0:2a6d8a096edc 145 #endif