Subdirectory provided by Embedded Artists
Dependencies: DM_FATFileSystem DM_HttpServer DM_USBHost EthernetInterface USBDevice mbed-rpc mbed-rtos mbed-src
Dependents: lpc4088_displaymodule_hello_world_Sept_2018
Fork of DMSupport by
FileSystems/MCIFileSystem.h@38:420cdc281467, 2015-04-15 (annotated)
- Committer:
- embeddedartists
- Date:
- Wed Apr 15 09:41:56 2015 +0200
- Revision:
- 38:420cdc281467
- Parent:
- 31:d47cffcb0a3e
- Added a new class GPDMA to allow multiple users of DMA
- Modified the MCI file system to use the new GPDMA class
- Updated ethernet/rtos/mbed/usbdevice library versions
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
embeddedartists | 0:6b68dac0d986 | 1 | /* |
embeddedartists | 9:a33326afd686 | 2 | * Copyright 2014 Embedded Artists AB |
embeddedartists | 0:6b68dac0d986 | 3 | * |
embeddedartists | 0:6b68dac0d986 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
embeddedartists | 0:6b68dac0d986 | 5 | * you may not use this file except in compliance with the License. |
embeddedartists | 0:6b68dac0d986 | 6 | * You may obtain a copy of the License at |
embeddedartists | 0:6b68dac0d986 | 7 | * |
embeddedartists | 0:6b68dac0d986 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
embeddedartists | 0:6b68dac0d986 | 9 | * |
embeddedartists | 0:6b68dac0d986 | 10 | * Unless required by applicable law or agreed to in writing, software |
embeddedartists | 0:6b68dac0d986 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
embeddedartists | 0:6b68dac0d986 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
embeddedartists | 0:6b68dac0d986 | 13 | * See the License for the specific language governing permissions and |
embeddedartists | 0:6b68dac0d986 | 14 | * limitations under the License. |
embeddedartists | 0:6b68dac0d986 | 15 | */ |
embeddedartists | 0:6b68dac0d986 | 16 | |
embeddedartists | 0:6b68dac0d986 | 17 | #ifndef MCIFILESYSTEM_H |
embeddedartists | 0:6b68dac0d986 | 18 | #define MCIFILESYSTEM_H |
embeddedartists | 0:6b68dac0d986 | 19 | |
embeddedartists | 0:6b68dac0d986 | 20 | #include "mbed.h" |
embeddedartists | 0:6b68dac0d986 | 21 | #include "FATFileSystem.h" |
embeddedartists | 38:420cdc281467 | 22 | #include "GPDMA.h" |
embeddedartists | 0:6b68dac0d986 | 23 | |
embeddedartists | 0:6b68dac0d986 | 24 | /** Access the filesystem on an SD Card using MCI |
embeddedartists | 0:6b68dac0d986 | 25 | * |
embeddedartists | 0:6b68dac0d986 | 26 | * @code |
embeddedartists | 0:6b68dac0d986 | 27 | * #include "mbed.h" |
embeddedartists | 0:6b68dac0d986 | 28 | * #include "MCIFileSystem.h" |
embeddedartists | 0:6b68dac0d986 | 29 | * |
embeddedartists | 0:6b68dac0d986 | 30 | * MCIFileSystem mcifs("mci"); |
embeddedartists | 0:6b68dac0d986 | 31 | * |
embeddedartists | 0:6b68dac0d986 | 32 | * int main() { |
embeddedartists | 0:6b68dac0d986 | 33 | * printf("Please insert a SD/MMC card\n"); |
embeddedartists | 0:6b68dac0d986 | 34 | * while(!mcifs.cardInserted()) { |
embeddedartists | 0:6b68dac0d986 | 35 | * wait(0.5); |
embeddedartists | 0:6b68dac0d986 | 36 | * } |
embeddedartists | 0:6b68dac0d986 | 37 | * |
embeddedartists | 0:6b68dac0d986 | 38 | * printf("Found SD/MMC card, writing to /mci/myfile.txt ...\n"); |
embeddedartists | 0:6b68dac0d986 | 39 | * |
embeddedartists | 0:6b68dac0d986 | 40 | * FILE *fp = fopen("/mci/myfile.txt", "w"); |
embeddedartists | 0:6b68dac0d986 | 41 | * if (fp != NULL) { |
embeddedartists | 0:6b68dac0d986 | 42 | * fprintf(fp, "Hello World!\n"); |
embeddedartists | 0:6b68dac0d986 | 43 | * fclose(fp); |
embeddedartists | 0:6b68dac0d986 | 44 | * printf("Wrote to /mci/myfile.txt\n"); |
embeddedartists | 0:6b68dac0d986 | 45 | * } else { |
embeddedartists | 0:6b68dac0d986 | 46 | * printf("Failed to open /mci/myfile.txt\n"); |
embeddedartists | 0:6b68dac0d986 | 47 | * } |
embeddedartists | 0:6b68dac0d986 | 48 | * } |
embeddedartists | 0:6b68dac0d986 | 49 | * @endcode |
embeddedartists | 0:6b68dac0d986 | 50 | */ |
embeddedartists | 0:6b68dac0d986 | 51 | class MCIFileSystem : public FATFileSystem { |
embeddedartists | 0:6b68dac0d986 | 52 | public: |
embeddedartists | 0:6b68dac0d986 | 53 | |
embeddedartists | 0:6b68dac0d986 | 54 | /** Create the File System for accessing an SD/MMC Card using MCI |
embeddedartists | 0:6b68dac0d986 | 55 | * |
embeddedartists | 0:6b68dac0d986 | 56 | * @param name The name used to access the virtual filesystem |
embeddedartists | 0:6b68dac0d986 | 57 | * @param cd The pin connected to the CardDetect line |
embeddedartists | 0:6b68dac0d986 | 58 | */ |
embeddedartists | 31:d47cffcb0a3e | 59 | MCIFileSystem(const char* name, PinName cd = P4_16); |
embeddedartists | 0:6b68dac0d986 | 60 | |
embeddedartists | 0:6b68dac0d986 | 61 | virtual ~MCIFileSystem(); |
embeddedartists | 0:6b68dac0d986 | 62 | |
embeddedartists | 0:6b68dac0d986 | 63 | virtual int disk_initialize(); |
embeddedartists | 0:6b68dac0d986 | 64 | virtual int disk_status(); |
embeddedartists | 0:6b68dac0d986 | 65 | virtual int disk_read(uint8_t * buffer, uint64_t block_number, uint8_t count); |
embeddedartists | 0:6b68dac0d986 | 66 | virtual int disk_write(const uint8_t * buffer, uint64_t block_number, uint8_t count); |
embeddedartists | 0:6b68dac0d986 | 67 | virtual int disk_sync(); |
embeddedartists | 0:6b68dac0d986 | 68 | virtual uint64_t disk_sectors(); |
embeddedartists | 0:6b68dac0d986 | 69 | |
embeddedartists | 0:6b68dac0d986 | 70 | void mci_MCIIRQHandler(); |
embeddedartists | 0:6b68dac0d986 | 71 | void mci_DMAIRQHandler(); |
embeddedartists | 0:6b68dac0d986 | 72 | |
embeddedartists | 0:6b68dac0d986 | 73 | /** Tests if a SD/MMC card is inserted or not. |
embeddedartists | 0:6b68dac0d986 | 74 | * |
embeddedartists | 0:6b68dac0d986 | 75 | * @returns |
embeddedartists | 0:6b68dac0d986 | 76 | * True if a card has been inserted, |
embeddedartists | 0:6b68dac0d986 | 77 | * False if no card is inserted or if the card detect pin is unavailable |
embeddedartists | 0:6b68dac0d986 | 78 | */ |
embeddedartists | 0:6b68dac0d986 | 79 | bool cardInserted() const; |
embeddedartists | 0:6b68dac0d986 | 80 | |
embeddedartists | 0:6b68dac0d986 | 81 | private: |
embeddedartists | 0:6b68dac0d986 | 82 | |
embeddedartists | 0:6b68dac0d986 | 83 | typedef enum { |
embeddedartists | 0:6b68dac0d986 | 84 | CardStatusNumBytes = 4, |
embeddedartists | 0:6b68dac0d986 | 85 | } Constants; |
embeddedartists | 0:6b68dac0d986 | 86 | |
embeddedartists | 0:6b68dac0d986 | 87 | typedef enum { |
embeddedartists | 0:6b68dac0d986 | 88 | PowerOff = 0, |
embeddedartists | 0:6b68dac0d986 | 89 | PowerUp = 2, |
embeddedartists | 0:6b68dac0d986 | 90 | PowerOn = 3, |
embeddedartists | 0:6b68dac0d986 | 91 | } power_ctrl_t; |
embeddedartists | 0:6b68dac0d986 | 92 | |
embeddedartists | 0:6b68dac0d986 | 93 | typedef enum { |
embeddedartists | 0:6b68dac0d986 | 94 | SDMMC_IDLE_ST = 0, /*!< Idle state */ |
embeddedartists | 0:6b68dac0d986 | 95 | SDMMC_READY_ST, /*!< Ready state */ |
embeddedartists | 0:6b68dac0d986 | 96 | SDMMC_IDENT_ST, /*!< Identification State */ |
embeddedartists | 0:6b68dac0d986 | 97 | SDMMC_STBY_ST, /*!< standby state */ |
embeddedartists | 0:6b68dac0d986 | 98 | SDMMC_TRAN_ST, /*!< transfer state */ |
embeddedartists | 0:6b68dac0d986 | 99 | SDMMC_DATA_ST, /*!< Sending-data State */ |
embeddedartists | 0:6b68dac0d986 | 100 | SDMMC_RCV_ST, /*!< Receive-data State */ |
embeddedartists | 0:6b68dac0d986 | 101 | SDMMC_PRG_ST, /*!< Programming State */ |
embeddedartists | 0:6b68dac0d986 | 102 | SDMMC_DIS_ST /*!< Disconnect State */ |
embeddedartists | 0:6b68dac0d986 | 103 | } CardState; |
embeddedartists | 0:6b68dac0d986 | 104 | |
embeddedartists | 0:6b68dac0d986 | 105 | |
embeddedartists | 0:6b68dac0d986 | 106 | typedef struct { |
embeddedartists | 0:6b68dac0d986 | 107 | uint8_t CmdIndex; |
embeddedartists | 0:6b68dac0d986 | 108 | uint32_t Data[CardStatusNumBytes]; |
embeddedartists | 0:6b68dac0d986 | 109 | } response_t; |
embeddedartists | 0:6b68dac0d986 | 110 | |
embeddedartists | 0:6b68dac0d986 | 111 | /** |
embeddedartists | 0:6b68dac0d986 | 112 | * @brief SDC Clock Control Options |
embeddedartists | 0:6b68dac0d986 | 113 | */ |
embeddedartists | 0:6b68dac0d986 | 114 | typedef enum { |
embeddedartists | 0:6b68dac0d986 | 115 | SDC_CLOCK_ENABLE = 8, /*!< Enable SD Card Bus Clock */ |
embeddedartists | 0:6b68dac0d986 | 116 | SDC_CLOCK_POWER_SAVE = 9, /*!< Disable SD_CLK output when bus is idle */ |
embeddedartists | 0:6b68dac0d986 | 117 | SDC_CLOCK_DIVIDER_BYPASS = 10, /*!< Enable bypass of clock divide logic */ |
embeddedartists | 0:6b68dac0d986 | 118 | SDC_CLOCK_WIDEBUS_MODE = 11, /*!< Enable wide bus mode (SD_DAT[3:0] is used instead of SD_DAT[0]) */ |
embeddedartists | 0:6b68dac0d986 | 119 | } ClockControl; |
embeddedartists | 0:6b68dac0d986 | 120 | |
embeddedartists | 0:6b68dac0d986 | 121 | /** |
embeddedartists | 0:6b68dac0d986 | 122 | * @brief SD/MMC Card specific setup data structure |
embeddedartists | 0:6b68dac0d986 | 123 | */ |
embeddedartists | 0:6b68dac0d986 | 124 | typedef struct { |
embeddedartists | 0:6b68dac0d986 | 125 | uint32_t response[4]; /*!< Most recent response */ |
embeddedartists | 0:6b68dac0d986 | 126 | uint32_t cid[4]; /*!< CID of acquired card */ |
embeddedartists | 0:6b68dac0d986 | 127 | uint32_t csd[4]; /*!< CSD of acquired card */ |
embeddedartists | 0:6b68dac0d986 | 128 | uint32_t ext_csd[512 / 4]; /*!< Ext CSD */ |
embeddedartists | 0:6b68dac0d986 | 129 | uint32_t card_type; /*!< Card Type */ |
embeddedartists | 0:6b68dac0d986 | 130 | uint16_t rca; /*!< Relative address assigned to card */ |
embeddedartists | 0:6b68dac0d986 | 131 | uint32_t speed; /*!< Speed */ |
embeddedartists | 0:6b68dac0d986 | 132 | uint32_t block_len; /*!< Card sector size */ |
embeddedartists | 0:6b68dac0d986 | 133 | uint32_t device_size; /*!< Device Size */ |
embeddedartists | 0:6b68dac0d986 | 134 | uint32_t blocknr; /*!< Block Number */ |
embeddedartists | 0:6b68dac0d986 | 135 | uint32_t clk_rate; /*!< Clock rate */ |
embeddedartists | 0:6b68dac0d986 | 136 | } SDMMC_CARD_T; |
embeddedartists | 0:6b68dac0d986 | 137 | |
embeddedartists | 0:6b68dac0d986 | 138 | typedef enum { |
embeddedartists | 0:6b68dac0d986 | 139 | SDC_RET_OK = 0, |
embeddedartists | 0:6b68dac0d986 | 140 | SDC_RET_CMD_FAILED = -1, |
embeddedartists | 0:6b68dac0d986 | 141 | SDC_RET_BAD_PARAMETERS = -2, |
embeddedartists | 0:6b68dac0d986 | 142 | SDC_RET_BUS_NOT_IDLE = -3, |
embeddedartists | 0:6b68dac0d986 | 143 | SDC_RET_TIMEOUT = -4, |
embeddedartists | 0:6b68dac0d986 | 144 | SDC_RET_ERR_STATE = -5, |
embeddedartists | 0:6b68dac0d986 | 145 | SDC_RET_NOT_READY = -6, |
embeddedartists | 0:6b68dac0d986 | 146 | SDC_RET_FAILED = -7, |
embeddedartists | 0:6b68dac0d986 | 147 | } ReturnCode; |
embeddedartists | 0:6b68dac0d986 | 148 | |
embeddedartists | 0:6b68dac0d986 | 149 | void initMCI(); |
embeddedartists | 0:6b68dac0d986 | 150 | |
embeddedartists | 0:6b68dac0d986 | 151 | int32_t mci_Acquire(); |
embeddedartists | 0:6b68dac0d986 | 152 | uint32_t mci_GetCardStatus() const; |
embeddedartists | 0:6b68dac0d986 | 153 | CardState mci_GetCardState() const; |
embeddedartists | 0:6b68dac0d986 | 154 | ReturnCode mci_ReadBlocks(void *buffer, int32_t startBlock, int32_t blockNum); |
embeddedartists | 0:6b68dac0d986 | 155 | ReturnCode mci_WriteBlocks(void *buffer, int32_t startBlock, int32_t blockNum); |
embeddedartists | 0:6b68dac0d986 | 156 | void mci_SetClock(uint32_t freq) const; |
embeddedartists | 0:6b68dac0d986 | 157 | void mci_ClockControl(ClockControl ctrlType, bool enable) const; |
embeddedartists | 0:6b68dac0d986 | 158 | void mci_PowerControl(power_ctrl_t powerMode, uint32_t flag) const; |
embeddedartists | 0:6b68dac0d986 | 159 | ReturnCode mci_ExecuteCmd(uint32_t Command, uint32_t Arg, response_t* pResp) const; |
embeddedartists | 0:6b68dac0d986 | 160 | ReturnCode mci_SendIfCond() const; |
embeddedartists | 0:6b68dac0d986 | 161 | ReturnCode mci_SendOpCond(uint32_t *pOCR) const; |
embeddedartists | 0:6b68dac0d986 | 162 | ReturnCode mci_SendAppOpCond(uint16_t rca, bool hcs, uint32_t *pOcr, bool *pCCS) const; |
embeddedartists | 0:6b68dac0d986 | 163 | ReturnCode mci_GetCID(uint32_t *pCID) const; |
embeddedartists | 0:6b68dac0d986 | 164 | ReturnCode mci_SetAddr(uint16_t addr) const; |
embeddedartists | 0:6b68dac0d986 | 165 | ReturnCode mci_GetAddr(uint16_t *pRCA) const; |
embeddedartists | 0:6b68dac0d986 | 166 | ReturnCode mci_GetCSD(uint16_t rca, uint32_t *pCSD) const; |
embeddedartists | 0:6b68dac0d986 | 167 | ReturnCode mci_SelectCard(uint16_t addr) const; |
embeddedartists | 0:6b68dac0d986 | 168 | ReturnCode mci_GetStatus(uint16_t rca, uint32_t *pStatus) const; |
embeddedartists | 0:6b68dac0d986 | 169 | void mci_ProcessCSD(); |
embeddedartists | 0:6b68dac0d986 | 170 | ReturnCode mci_SetBusWidth(uint16_t rca, uint8_t width) const; |
embeddedartists | 0:6b68dac0d986 | 171 | ReturnCode mci_SetTranState(uint16_t rca) const; |
embeddedartists | 0:6b68dac0d986 | 172 | ReturnCode mci_SetBlockLength(uint32_t rca, uint32_t block_len) const; |
embeddedartists | 0:6b68dac0d986 | 173 | ReturnCode mci_SetCardParams() const; |
embeddedartists | 0:6b68dac0d986 | 174 | ReturnCode mci_StopTransmission(uint32_t rca) const; |
embeddedartists | 0:6b68dac0d986 | 175 | bool mci_CheckR1Response(uint32_t resp, ReturnCode* pCheckResult) const; |
embeddedartists | 0:6b68dac0d986 | 176 | void mci_WriteDelay() const; |
embeddedartists | 0:6b68dac0d986 | 177 | ReturnCode mci_SendCmd(uint32_t Command, uint32_t Arg, uint32_t timeout) const; |
embeddedartists | 0:6b68dac0d986 | 178 | ReturnCode mci_SendAppCmd(uint16_t rca) const; |
embeddedartists | 0:6b68dac0d986 | 179 | void mci_SetDataTransfer(uint16_t BlockNum, bool DirFromCard, uint32_t Timeout) const; |
embeddedartists | 0:6b68dac0d986 | 180 | void mci_GetResp(response_t* pResp) const; |
embeddedartists | 0:6b68dac0d986 | 181 | uint32_t mci_GetBits(int32_t start, int32_t end, uint32_t *data) const; |
embeddedartists | 0:6b68dac0d986 | 182 | void mci_SetCommand(uint32_t Cmd, uint32_t Arg) const; |
embeddedartists | 0:6b68dac0d986 | 183 | void mci_ResetCommand() const; |
embeddedartists | 0:6b68dac0d986 | 184 | int32_t mci_IRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt); |
embeddedartists | 0:6b68dac0d986 | 185 | int32_t mci_FIFOIRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt); |
embeddedartists | 0:6b68dac0d986 | 186 | void mci_ReadFIFO(uint32_t *pDst, bool bFirstHalf) const; |
embeddedartists | 0:6b68dac0d986 | 187 | void mci_WriteFIFO(uint32_t *pSrc, bool bFirstHalf) const; |
embeddedartists | 0:6b68dac0d986 | 188 | |
embeddedartists | 38:420cdc281467 | 189 | void mci_SetupEventWakeup(); |
embeddedartists | 0:6b68dac0d986 | 190 | uint32_t mci_WaitForEvent() const; |
embeddedartists | 0:6b68dac0d986 | 191 | |
embeddedartists | 0:6b68dac0d986 | 192 | ReturnCode _readBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const; |
embeddedartists | 0:6b68dac0d986 | 193 | ReturnCode _writeBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const; |
embeddedartists | 0:6b68dac0d986 | 194 | |
embeddedartists | 0:6b68dac0d986 | 195 | |
embeddedartists | 0:6b68dac0d986 | 196 | uint32_t _Stat; |
embeddedartists | 0:6b68dac0d986 | 197 | SDMMC_CARD_T _sdCardInfo; |
embeddedartists | 0:6b68dac0d986 | 198 | |
embeddedartists | 0:6b68dac0d986 | 199 | DigitalIn* _cardDetect; |
embeddedartists | 0:6b68dac0d986 | 200 | |
embeddedartists | 38:420cdc281467 | 201 | GPDMA::DMAChannels _eventDmaChannel; /*!< DMA Channel used for transfer data */ |
embeddedartists | 0:6b68dac0d986 | 202 | volatile bool _eventReceived; |
embeddedartists | 0:6b68dac0d986 | 203 | volatile bool _eventSuccess; |
embeddedartists | 0:6b68dac0d986 | 204 | }; |
embeddedartists | 0:6b68dac0d986 | 205 | |
embeddedartists | 0:6b68dac0d986 | 206 | #endif |