Example of using the SDFileSystem library on a K64F to write data to files and also read data into dynamically created arrays.

Dependencies:   mbed

Committer:
eencae
Date:
Mon Feb 03 12:06:21 2020 +0000
Revision:
1:caceb9d9d17a
Updated Mbed library. Removed serial. Confirmed working Jan 2020.

Who changed what in which revision?

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