Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SDFileSystem by
SDFileSystem.h@4:49b29888eca7, 2014-07-30 (annotated)
- 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?
User | Revision | Line number | New 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 |