Kaif Kutchwala 201267448 ELEC2645 Project

Dependencies:   mbed

Committer:
KaifK
Date:
Tue May 26 15:50:46 2020 +0000
Revision:
31:e1f80d181779
Parent:
21:d5b1160f349f
Final Submission. I have read and agreed with Statement of Academic Integrity.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
KaifK 21:d5b1160f349f 1 /* SD/MMC File System Library
KaifK 21:d5b1160f349f 2 * Copyright (c) 2016 Neil Thiessen
KaifK 21:d5b1160f349f 3 *
KaifK 21:d5b1160f349f 4 * Licensed under the Apache License, Version 2.0 (the "License");
KaifK 21:d5b1160f349f 5 * you may not use this file except in compliance with the License.
KaifK 21:d5b1160f349f 6 * You may obtain a copy of the License at
KaifK 21:d5b1160f349f 7 *
KaifK 21:d5b1160f349f 8 * http://www.apache.org/licenses/LICENSE-2.0
KaifK 21:d5b1160f349f 9 *
KaifK 21:d5b1160f349f 10 * Unless required by applicable law or agreed to in writing, software
KaifK 21:d5b1160f349f 11 * distributed under the License is distributed on an "AS IS" BASIS,
KaifK 21:d5b1160f349f 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
KaifK 21:d5b1160f349f 13 * See the License for the specific language governing permissions and
KaifK 21:d5b1160f349f 14 * limitations under the License.
KaifK 21:d5b1160f349f 15 */
KaifK 21:d5b1160f349f 16
KaifK 21:d5b1160f349f 17 #ifndef SD_FILE_SYSTEM_H
KaifK 21:d5b1160f349f 18 #define SD_FILE_SYSTEM_H
KaifK 21:d5b1160f349f 19
KaifK 21:d5b1160f349f 20 #include "mbed.h"
KaifK 21:d5b1160f349f 21 #include "FATFileSystem.h"
KaifK 21:d5b1160f349f 22
KaifK 21:d5b1160f349f 23 /** SDFileSystem class.
KaifK 21:d5b1160f349f 24 * Used for creating a virtual file system for accessing SD/MMC cards via SPI.
KaifK 21:d5b1160f349f 25 *
KaifK 21:d5b1160f349f 26 * Example:
KaifK 21:d5b1160f349f 27 * @code
KaifK 21:d5b1160f349f 28 * #include "mbed.h"
KaifK 21:d5b1160f349f 29 * #include "SDFileSystem.h"
KaifK 21:d5b1160f349f 30 *
KaifK 21:d5b1160f349f 31 * //Create an SDFileSystem object
KaifK 21:d5b1160f349f 32 * SDFileSystem sd(p5, p6, p7, p20, "sd");
KaifK 21:d5b1160f349f 33 *
KaifK 21:d5b1160f349f 34 * int main()
KaifK 21:d5b1160f349f 35 * {
KaifK 21:d5b1160f349f 36 * //Mount the filesystem
KaifK 21:d5b1160f349f 37 * sd.mount();
KaifK 21:d5b1160f349f 38 *
KaifK 21:d5b1160f349f 39 * //Perform a write test
KaifK 21:d5b1160f349f 40 * printf("\nWriting to SD card...");
KaifK 21:d5b1160f349f 41 * FILE *fp = fopen("/sd/sdtest.txt", "w");
KaifK 21:d5b1160f349f 42 * if (fp != NULL) {
KaifK 21:d5b1160f349f 43 * fprintf(fp, "We're writing to an SD card!");
KaifK 21:d5b1160f349f 44 * fclose(fp);
KaifK 21:d5b1160f349f 45 * printf("success!\n");
KaifK 21:d5b1160f349f 46 * } else {
KaifK 21:d5b1160f349f 47 * printf("failed!\n");
KaifK 21:d5b1160f349f 48 * }
KaifK 21:d5b1160f349f 49 *
KaifK 21:d5b1160f349f 50 * //Perform a read test
KaifK 21:d5b1160f349f 51 * printf("Reading from SD card...");
KaifK 21:d5b1160f349f 52 * fp = fopen("/sd/sdtest.txt", "r");
KaifK 21:d5b1160f349f 53 * if (fp != NULL) {
KaifK 21:d5b1160f349f 54 * char c = fgetc(fp);
KaifK 21:d5b1160f349f 55 * if (c == 'W')
KaifK 21:d5b1160f349f 56 * printf("success!\n");
KaifK 21:d5b1160f349f 57 * else
KaifK 21:d5b1160f349f 58 * printf("incorrect char (%c)!\n", c);
KaifK 21:d5b1160f349f 59 * fclose(fp);
KaifK 21:d5b1160f349f 60 * } else {
KaifK 21:d5b1160f349f 61 * printf("failed!\n");
KaifK 21:d5b1160f349f 62 * }
KaifK 21:d5b1160f349f 63 *
KaifK 21:d5b1160f349f 64 * //Unmount the filesystem
KaifK 21:d5b1160f349f 65 * sd.unmount();
KaifK 21:d5b1160f349f 66 * }
KaifK 21:d5b1160f349f 67 * @endcode
KaifK 21:d5b1160f349f 68 */
KaifK 21:d5b1160f349f 69 class SDFileSystem : public FATFileSystem
KaifK 21:d5b1160f349f 70 {
KaifK 21:d5b1160f349f 71 public:
KaifK 21:d5b1160f349f 72 /** Represents the different card detect switch types
KaifK 21:d5b1160f349f 73 */
KaifK 21:d5b1160f349f 74 enum SwitchType {
KaifK 21:d5b1160f349f 75 SWITCH_NONE, /**< No card detect switch (assumes socket is always occupied) */
KaifK 21:d5b1160f349f 76 SWITCH_POS_NO, /**< Switch shorts to VDD when the socket is occupied (positive logic, normally open) */
KaifK 21:d5b1160f349f 77 SWITCH_POS_NC, /**< Switch shorts to VDD when the socket is empty (positive logic, normally closed) */
KaifK 21:d5b1160f349f 78 SWITCH_NEG_NO, /**< Switch shorts to GND when the socket is occupied (negative logic, normally open) */
KaifK 21:d5b1160f349f 79 SWITCH_NEG_NC /**< Switch shorts to GND when the socket is empty (negative logic, normally closed) */
KaifK 21:d5b1160f349f 80 };
KaifK 21:d5b1160f349f 81
KaifK 21:d5b1160f349f 82 /** Represents the different SD/MMC card types
KaifK 21:d5b1160f349f 83 */
KaifK 21:d5b1160f349f 84 enum CardType {
KaifK 21:d5b1160f349f 85 CARD_NONE, /**< No card is present */
KaifK 21:d5b1160f349f 86 CARD_MMC, /**< MMC card */
KaifK 21:d5b1160f349f 87 CARD_SD, /**< Standard capacity SD card */
KaifK 21:d5b1160f349f 88 CARD_SDHC, /**< High capacity SD card */
KaifK 21:d5b1160f349f 89 CARD_UNKNOWN /**< Unknown or unsupported card */
KaifK 21:d5b1160f349f 90 };
KaifK 21:d5b1160f349f 91
KaifK 21:d5b1160f349f 92 /** Create a virtual file system for accessing SD/MMC cards via SPI
KaifK 21:d5b1160f349f 93 *
KaifK 21:d5b1160f349f 94 * @param mosi The SPI data out pin.
KaifK 21:d5b1160f349f 95 * @param miso The SPI data in pin.
KaifK 21:d5b1160f349f 96 * @param sclk The SPI clock pin.
KaifK 21:d5b1160f349f 97 * @param cs The SPI chip select pin.
KaifK 21:d5b1160f349f 98 * @param name The name used to access the virtual filesystem.
KaifK 21:d5b1160f349f 99 * @param cd The card detect pin.
KaifK 21:d5b1160f349f 100 * @param cdtype The type of card detect switch.
KaifK 21:d5b1160f349f 101 * @param hz The SPI bus frequency (defaults to 1MHz).
KaifK 21:d5b1160f349f 102 */
KaifK 21:d5b1160f349f 103 SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name, PinName cd = NC, SwitchType cdtype = SWITCH_NONE, int hz = 1000000);
KaifK 21:d5b1160f349f 104
KaifK 21:d5b1160f349f 105 /** Determine whether or not a card is present
KaifK 21:d5b1160f349f 106 *
KaifK 21:d5b1160f349f 107 * @returns
KaifK 21:d5b1160f349f 108 * 'true' if a card is present,
KaifK 21:d5b1160f349f 109 * 'false' if no card is present.
KaifK 21:d5b1160f349f 110 */
KaifK 21:d5b1160f349f 111 bool card_present();
KaifK 21:d5b1160f349f 112
KaifK 21:d5b1160f349f 113 /** Get the detected SD/MMC card type
KaifK 21:d5b1160f349f 114 *
KaifK 21:d5b1160f349f 115 * @returns The detected card type as a CardType enum.
KaifK 21:d5b1160f349f 116 *
KaifK 21:d5b1160f349f 117 * @note Valid after the filesystem has been mounted.
KaifK 21:d5b1160f349f 118 */
KaifK 21:d5b1160f349f 119 SDFileSystem::CardType card_type();
KaifK 21:d5b1160f349f 120
KaifK 21:d5b1160f349f 121 /** Get whether or not CRC is enabled for commands and data
KaifK 21:d5b1160f349f 122 *
KaifK 21:d5b1160f349f 123 * @returns
KaifK 21:d5b1160f349f 124 * 'true' if CRC is enabled for commands and data,
KaifK 21:d5b1160f349f 125 * 'false' if CRC is disabled for commands and data.
KaifK 21:d5b1160f349f 126 */
KaifK 21:d5b1160f349f 127 bool crc();
KaifK 21:d5b1160f349f 128
KaifK 21:d5b1160f349f 129 /** Set whether or not CRC is enabled for commands and data
KaifK 21:d5b1160f349f 130 *
KaifK 21:d5b1160f349f 131 * @param enabled Whether or not to enable CRC for commands and data.
KaifK 21:d5b1160f349f 132 */
KaifK 21:d5b1160f349f 133 void crc(bool enabled);
KaifK 21:d5b1160f349f 134
KaifK 21:d5b1160f349f 135 /** Get whether or not 16-bit frames are enabled for data read/write operations
KaifK 21:d5b1160f349f 136 *
KaifK 21:d5b1160f349f 137 * @returns
KaifK 21:d5b1160f349f 138 * 'true' if 16-bit frames will be used during data read/write operations,
KaifK 21:d5b1160f349f 139 * 'false' if 8-bit frames will be used during data read/write operations.
KaifK 21:d5b1160f349f 140 */
KaifK 21:d5b1160f349f 141 bool large_frames();
KaifK 21:d5b1160f349f 142
KaifK 21:d5b1160f349f 143 /** Set whether or not 16-bit frames are enabled for data read/write operations
KaifK 21:d5b1160f349f 144 *
KaifK 21:d5b1160f349f 145 * @param enabled Whether or not 16-bit frames are enabled for data read/write operations.
KaifK 21:d5b1160f349f 146 */
KaifK 21:d5b1160f349f 147 void large_frames(bool enabled);
KaifK 21:d5b1160f349f 148
KaifK 21:d5b1160f349f 149 /** Get whether or not write validation is enabled for data write operations
KaifK 21:d5b1160f349f 150 *
KaifK 21:d5b1160f349f 151 * @returns
KaifK 21:d5b1160f349f 152 * 'true' if data writes will be verified using CMD13,
KaifK 21:d5b1160f349f 153 * 'false' if data writes will not be verified.
KaifK 21:d5b1160f349f 154 */
KaifK 21:d5b1160f349f 155 bool write_validation();
KaifK 21:d5b1160f349f 156
KaifK 21:d5b1160f349f 157 /** Set whether or not write validation is enabled for data write operations
KaifK 21:d5b1160f349f 158 *
KaifK 21:d5b1160f349f 159 * @param enabled Whether or not write validation is enabled for data write operations.
KaifK 21:d5b1160f349f 160 */
KaifK 21:d5b1160f349f 161 void write_validation(bool enabled);
KaifK 21:d5b1160f349f 162
KaifK 21:d5b1160f349f 163 virtual int unmount();
KaifK 21:d5b1160f349f 164 virtual int disk_initialize();
KaifK 21:d5b1160f349f 165 virtual int disk_status();
KaifK 21:d5b1160f349f 166 virtual int disk_read(uint8_t* buffer, uint32_t sector, uint32_t count);
KaifK 21:d5b1160f349f 167 virtual int disk_write(const uint8_t* buffer, uint32_t sector, uint32_t count);
KaifK 21:d5b1160f349f 168 virtual int disk_sync();
KaifK 21:d5b1160f349f 169 virtual uint32_t disk_sectors();
KaifK 21:d5b1160f349f 170
KaifK 21:d5b1160f349f 171 private:
KaifK 21:d5b1160f349f 172 //Commands
KaifK 21:d5b1160f349f 173 enum Command {
KaifK 21:d5b1160f349f 174 CMD0 = (0x40 | 0), /**< GO_IDLE_STATE */
KaifK 21:d5b1160f349f 175 CMD1 = (0x40 | 1), /**< SEND_OP_COND */
KaifK 21:d5b1160f349f 176 CMD6 = (0x40 | 6), /**< SWITCH_FUNC */
KaifK 21:d5b1160f349f 177 CMD8 = (0x40 | 8), /**< SEND_IF_COND */
KaifK 21:d5b1160f349f 178 CMD9 = (0x40 | 9), /**< SEND_CSD */
KaifK 21:d5b1160f349f 179 CMD12 = (0x40 | 12), /**< STOP_TRANSMISSION */
KaifK 21:d5b1160f349f 180 CMD13 = (0x40 | 13), /**< SEND_STATUS */
KaifK 21:d5b1160f349f 181 CMD16 = (0x40 | 16), /**< SET_BLOCKLEN */
KaifK 21:d5b1160f349f 182 CMD17 = (0x40 | 17), /**< READ_SINGLE_BLOCK */
KaifK 21:d5b1160f349f 183 CMD18 = (0x40 | 18), /**< READ_MULTIPLE_BLOCK */
KaifK 21:d5b1160f349f 184 ACMD22 = (0x40 | 22), /**< SEND_NUM_WR_BLOCKS */
KaifK 21:d5b1160f349f 185 ACMD23 = (0x40 | 23), /**< SET_WR_BLK_ERASE_COUNT */
KaifK 21:d5b1160f349f 186 CMD24 = (0x40 | 24), /**< WRITE_BLOCK */
KaifK 21:d5b1160f349f 187 CMD25 = (0x40 | 25), /**< WRITE_MULTIPLE_BLOCK */
KaifK 21:d5b1160f349f 188 ACMD41 = (0x40 | 41), /**< SD_SEND_OP_COND */
KaifK 21:d5b1160f349f 189 ACMD42 = (0x40 | 42), /**< SET_CLR_CARD_DETECT */
KaifK 21:d5b1160f349f 190 CMD55 = (0x40 | 55), /**< APP_CMD */
KaifK 21:d5b1160f349f 191 CMD58 = (0x40 | 58), /**< READ_OCR */
KaifK 21:d5b1160f349f 192 CMD59 = (0x40 | 59) /**< CRC_ON_OFF */
KaifK 21:d5b1160f349f 193 };
KaifK 21:d5b1160f349f 194
KaifK 21:d5b1160f349f 195 //Member variables
KaifK 21:d5b1160f349f 196 Timer m_Timer;
KaifK 21:d5b1160f349f 197 SPI m_Spi;
KaifK 21:d5b1160f349f 198 DigitalOut m_Cs;
KaifK 21:d5b1160f349f 199 InterruptIn m_Cd;
KaifK 21:d5b1160f349f 200 int m_CdAssert;
KaifK 21:d5b1160f349f 201 const int m_FREQ;
KaifK 21:d5b1160f349f 202 SDFileSystem::CardType m_CardType;
KaifK 21:d5b1160f349f 203 bool m_Crc;
KaifK 21:d5b1160f349f 204 bool m_LargeFrames;
KaifK 21:d5b1160f349f 205 bool m_WriteValidation;
KaifK 21:d5b1160f349f 206 int m_Status;
KaifK 21:d5b1160f349f 207
KaifK 21:d5b1160f349f 208 //Internal methods
KaifK 21:d5b1160f349f 209 void onCardRemoval();
KaifK 21:d5b1160f349f 210 void checkSocket();
KaifK 21:d5b1160f349f 211 bool waitReady(int timeout);
KaifK 21:d5b1160f349f 212 bool select();
KaifK 21:d5b1160f349f 213 void deselect();
KaifK 21:d5b1160f349f 214 char commandTransaction(char cmd, unsigned int arg, unsigned int* resp = NULL);
KaifK 21:d5b1160f349f 215 char writeCommand(char cmd, unsigned int arg, unsigned int* resp = NULL);
KaifK 21:d5b1160f349f 216 bool readData(char* buffer, int length);
KaifK 21:d5b1160f349f 217 char writeData(const char* buffer, char token);
KaifK 21:d5b1160f349f 218 bool readBlock(char* buffer, unsigned int lba);
KaifK 21:d5b1160f349f 219 bool readBlocks(char* buffer, unsigned int lba, unsigned int count);
KaifK 21:d5b1160f349f 220 bool writeBlock(const char* buffer, unsigned int lba);
KaifK 21:d5b1160f349f 221 bool writeBlocks(const char* buffer, unsigned int lba, unsigned int count);
KaifK 21:d5b1160f349f 222 bool enableHighSpeedMode();
KaifK 21:d5b1160f349f 223 };
KaifK 21:d5b1160f349f 224
KaifK 21:d5b1160f349f 225 #endif