Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / sdcard / sdmmc_sdio_f4xx.c
blob592ce4cf6411513473ad5f24197ec4a5016f002a
1 /*
2 * This file is part of INAV, Cleanflight and Betaflight.
4 * INAV, Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
22 * Original author: Alain (https://github.com/aroyer-qc)
23 * Modified for F4 and BF source: Chris Hockuba (https://github.com/conkerkh)
24 * Modified for INAV: Konstantin (https://github.com/digitalentity)
26 * Note: On F4 due to DMA issues it is recommended that motor timers don't run on DMA2.
27 * Therefore avoid using TIM1/TIM8, use TIM2/TIM3/TIM4/TIM5/TIM6/TIM7
30 /* Include(s) -------------------------------------------------------------------------------------------------------*/
32 #include "stdbool.h"
33 #include <string.h>
35 #include "platform.h"
37 #ifdef USE_SDCARD_SDIO
39 #include "sdmmc_sdio.h"
40 #include "stm32f4xx_gpio.h"
42 #include "drivers/io.h"
43 #include "drivers/io_impl.h"
44 #include "drivers/nvic.h"
45 #include "drivers/time.h"
46 #include "drivers/rcc.h"
47 #include "drivers/dma.h"
49 #include "build/debug.h"
52 /* Define(s) --------------------------------------------------------------------------------------------------------*/
54 #define DMA_CHANNEL_4 ((uint32_t)0x08000000)
55 #define DMA_MEMORY_TO_PERIPH ((uint32_t)DMA_SxCR_DIR_0)
56 #define DMA_PERIPH_TO_MEMORY ((uint32_t)0x00)
57 #define DMA_MINC_ENABLE ((uint32_t)DMA_SxCR_MINC)
58 #define DMA_MDATAALIGN_WORD ((uint32_t)DMA_SxCR_MSIZE_1)
59 #define DMA_PDATAALIGN_WORD ((uint32_t)DMA_SxCR_PSIZE_1)
60 #define DMA_PRIORITY_MEDIUM ((uint32_t)DMA_Priority_Medium)
61 #define DMA_PRIORITY_HIGH ((uint32_t)DMA_Priority_High)
62 #define DMA_PRIORITY_VERY_HIGH ((uint32_t)DMA_Priority_VeryHigh)
63 #define DMA_MBURST_INC4 ((uint32_t)DMA_SxCR_MBURST_0)
64 #define DMA_PBURST_INC4 ((uint32_t)DMA_SxCR_PBURST_0)
66 #define BLOCK_SIZE ((uint32_t)(512))
68 #define IFCR_CLEAR_MASK_STREAM3 (DMA_LIFCR_CTCIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CTEIF3 | DMA_LIFCR_CDMEIF3 | DMA_LIFCR_CFEIF3)
69 #define IFCR_CLEAR_MASK_STREAM6 (DMA_HIFCR_CTCIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 | DMA_HIFCR_CFEIF6)
71 #define SDIO_ICR_STATIC_FLAGS ((uint32_t)(SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | SDIO_ICR_CTIMEOUTC |\
72 SDIO_ICR_DTIMEOUTC | SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC |\
73 SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | SDIO_ICR_DATAENDC |\
74 SDIO_ICR_DBCKENDC))
76 #define SD_SOFTWARE_COMMAND_TIMEOUT ((uint32_t)0x00020000)
78 #define SD_OCR_ADDR_OUT_OF_RANGE ((uint32_t)0x80000000)
79 #define SD_OCR_ADDR_MISALIGNED ((uint32_t)0x40000000)
80 #define SD_OCR_BLOCK_LEN_ERR ((uint32_t)0x20000000)
81 #define SD_OCR_ERASE_SEQ_ERR ((uint32_t)0x10000000)
82 #define SD_OCR_BAD_ERASE_PARAM ((uint32_t)0x08000000)
83 #define SD_OCR_WRITE_PROT_VIOLATION ((uint32_t)0x04000000)
84 #define SD_OCR_LOCK_UNLOCK_FAILED ((uint32_t)0x01000000)
85 #define SD_OCR_COM_CRC_FAILED ((uint32_t)0x00800000)
86 #define SD_OCR_ILLEGAL_CMD ((uint32_t)0x00400000)
87 #define SD_OCR_CARD_ECC_FAILED ((uint32_t)0x00200000)
88 #define SD_OCR_CC_ERROR ((uint32_t)0x00100000)
89 #define SD_OCR_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00080000)
90 #define SD_OCR_STREAM_READ_UNDERRUN ((uint32_t)0x00040000)
91 #define SD_OCR_STREAM_WRITE_OVERRUN ((uint32_t)0x00020000)
92 #define SD_OCR_CID_CSD_OVERWRITE ((uint32_t)0x00010000)
93 #define SD_OCR_WP_ERASE_SKIP ((uint32_t)0x00008000)
94 #define SD_OCR_CARD_ECC_DISABLED ((uint32_t)0x00004000)
95 #define SD_OCR_ERASE_RESET ((uint32_t)0x00002000)
96 #define SD_OCR_AKE_SEQ_ERROR ((uint32_t)0x00000008)
97 #define SD_OCR_ERRORBITS ((uint32_t)0xFDFFE008)
99 #define SD_R6_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00002000)
100 #define SD_R6_ILLEGAL_CMD ((uint32_t)0x00004000)
101 #define SD_R6_COM_CRC_FAILED ((uint32_t)0x00008000)
103 #define SD_VOLTAGE_WINDOW_SD ((uint32_t)0x80100000)
104 #define SD_RESP_HIGH_CAPACITY ((uint32_t)0x40000000)
105 #define SD_RESP_STD_CAPACITY ((uint32_t)0x00000000)
106 #define SD_CHECK_PATTERN ((uint32_t)0x000001AA)
108 #define SD_MAX_VOLT_TRIAL ((uint32_t)0x0000FFFF)
109 #define SD_ALLZERO ((uint32_t)0x00000000)
111 #define SD_WIDE_BUS_SUPPORT ((uint32_t)0x00040000)
112 #define SD_SINGLE_BUS_SUPPORT ((uint32_t)0x00010000)
113 #define SD_CARD_LOCKED ((uint32_t)0x02000000)
115 #define SD_0TO7BITS ((uint32_t)0x000000FF)
116 #define SD_8TO15BITS ((uint32_t)0x0000FF00)
117 #define SD_16TO23BITS ((uint32_t)0x00FF0000)
118 #define SD_24TO31BITS ((uint32_t)0xFF000000)
119 #define SD_MAX_DATA_LENGTH ((uint32_t)0x01FFFFFF)
121 #define SD_CCCC_ERASE ((uint32_t)0x00000020)
123 #define SD_SDIO_SEND_IF_COND ((uint32_t)SD_CMD_HS_SEND_EXT_CSD)
127 #define SD_BUS_WIDE_1B ((uint32_t)0x00000000)
128 #define SD_BUS_WIDE_4B SDIO_CLKCR_WIDBUS_0
129 #define SD_BUS_WIDE_8B SDIO_CLKCR_WIDBUS_1
131 #define SD_CMD_RESPONSE_SHORT SDIO_CMD_WAITRESP_0
132 #define SD_CMD_RESPONSE_LONG SDIO_CMD_WAITRESP
134 #define SD_DATABLOCK_SIZE_8B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_1)
135 #define SD_DATABLOCK_SIZE_64B (SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_2)
136 #define SD_DATABLOCK_SIZE_512B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_3)
138 #define CLKCR_CLEAR_MASK ((uint32_t)(SDIO_CLKCR_CLKDIV | SDIO_CLKCR_PWRSAV |\
139 SDIO_CLKCR_BYPASS | SDIO_CLKCR_WIDBUS |\
140 SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN))
142 #define DCTRL_CLEAR_MASK ((uint32_t)(SDIO_DCTRL_DTEN | SDIO_DCTRL_DTDIR |\
143 SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE))
145 #define CMD_CLEAR_MASK ((uint32_t)(SDIO_CMD_CMDINDEX | SDIO_CMD_WAITRESP |\
146 SDIO_CMD_WAITINT | SDIO_CMD_WAITPEND |\
147 SDIO_CMD_CPSMEN | SDIO_CMD_SDIOSUSPEND))
149 #define SDIO_INIT_CLK_DIV ((uint8_t)0x76)
150 #define SDIO_CLK_DIV ((uint8_t)0x00)
153 #define SD_CMD_GO_IDLE_STATE ((uint8_t)0) // Resets the SD memory card.
154 #define SD_CMD_SEND_OP_COND ((uint8_t)1) // Sends host capacity support information and activates the card's initialization process.
155 #define SD_CMD_ALL_SEND_CID ((uint8_t)2) // Asks any card connected to the host to send the CID numbers on the CMD line.
156 #define SD_CMD_SET_REL_ADDR ((uint8_t)3) // Asks the card to publish a new relative address (RCA).
157 #define SD_CMD_HS_SWITCH ((uint8_t)6) // Checks switchable function (mode 0) and switch card function (mode 1).
158 #define SD_CMD_SEL_DESEL_CARD ((uint8_t)7) // Selects the card by its own relative address and gets deselected by any other address
159 #define SD_CMD_HS_SEND_EXT_CSD ((uint8_t)8) // Sends SD Memory Card interface condition, which includes host supply voltage information
160 // and asks the card whether card supports voltage.
161 #define SD_CMD_SEND_CSD ((uint8_t)9) // Addressed card sends its card specific data (CSD) on the CMD line.
162 #define SD_CMD_SEND_CID ((uint8_t)10) // Addressed card sends its card identification (CID) on the CMD line.
163 #define SD_CMD_STOP_TRANSMISSION ((uint8_t)12) // Forces the card to stop transmission.
164 #define SD_CMD_SEND_STATUS ((uint8_t)13) // Addressed card sends its status register.
165 #define SD_CMD_SET_BLOCKLEN ((uint8_t)16) // Sets the block length (in bytes for SDSC) for all following block commands
166 // (read, write, lock). Default block length is fixed to 512 Bytes. Not effective
167 // for SDHS and SDXC.
168 #define SD_CMD_READ_SINGLE_BLOCK ((uint8_t)17) // Reads single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of
169 // fixed 512 bytes in case of SDHC and SDXC.
170 #define SD_CMD_READ_MULT_BLOCK ((uint8_t)18) // Continuously transfers data blocks from card to host until interrupted by
171 // STOP_TRANSMISSION command.
172 #define SD_CMD_WRITE_SINGLE_BLOCK ((uint8_t)24) // Writes single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of
173 // fixed 512 bytes in case of SDHC and SDXC.
174 #define SD_CMD_WRITE_MULT_BLOCK ((uint8_t)25) // Continuously writes blocks of data until a STOP_TRANSMISSION follows.
175 #define SD_CMD_SD_ERASE_GRP_START ((uint8_t)32) // Sets the address of the first write block to be erased. (For SD card only).
176 #define SD_CMD_SD_ERASE_GRP_END ((uint8_t)33) // Sets the address of the last write block of the continuous range to be erased.
177 // system set by switch function command (CMD6).
178 #define SD_CMD_ERASE ((uint8_t)38) // Reserved for SD security applications.
179 #define SD_CMD_FAST_IO ((uint8_t)39) // SD card doesn't support it (Reserved).
180 #define SD_CMD_APP_CMD ((uint8_t)55) // Indicates to the card that the next command is an application specific command rather
181 // than a standard command.
183 /* Following commands are SD Card Specific commands.
184 SDIO_APP_CMD should be sent before sending these commands. */
185 #define SD_CMD_APP_SD_SET_BUSWIDTH ((uint8_t)6) // (ACMD6) Defines the data bus width to be used for data transfer. The allowed data bus
186 // widths are given in SCR register.
187 #define SD_CMD_SD_APP_STATUS ((uint8_t)13) // (ACMD13) Sends the SD status.
188 #define SD_CMD_SD_APP_OP_COND ((uint8_t)41) // (ACMD41) Sends host capacity support information (HCS) and asks the accessed card to
189 // send its operating condition register (OCR) content in the response on the CMD line.
190 #define SD_CMD_SD_APP_SEND_SCR ((uint8_t)51) // Reads the SD Configuration Register (SCR).
192 #define SDIO_DIR_TX 1
193 #define SDIO_DIR_RX 0
195 #define SDIO_DMA_ST3 1
198 /* Typedef(s) -------------------------------------------------------------------------------------------------------*/
200 typedef enum
202 SD_SINGLE_BLOCK = 0, // Single block operation
203 SD_MULTIPLE_BLOCK = 1, // Multiple blocks operation
204 } SD_Operation_t;
206 typedef struct
208 uint32_t CSD[4]; // SD card specific data table
209 uint32_t CID[4]; // SD card identification number table
210 volatile uint32_t TransferComplete; // SD transfer complete flag in non blocking mode
211 volatile uint32_t TransferError; // SD transfer error flag in non blocking mode
212 volatile uint32_t RXCplt; // SD RX Complete is equal 0 when no transfer
213 volatile uint32_t TXCplt; // SD TX Complete is equal 0 when no transfer
214 volatile uint32_t Operation; // SD transfer operation (read/write)
215 } SD_Handle_t;
217 typedef enum
219 SD_CARD_READY = ((uint32_t)0x00000001), // Card state is ready
220 SD_CARD_IDENTIFICATION = ((uint32_t)0x00000002), // Card is in identification state
221 SD_CARD_STANDBY = ((uint32_t)0x00000003), // Card is in standby state
222 SD_CARD_TRANSFER = ((uint32_t)0x00000004), // Card is in transfer state
223 SD_CARD_SENDING = ((uint32_t)0x00000005), // Card is sending an operation
224 SD_CARD_RECEIVING = ((uint32_t)0x00000006), // Card is receiving operation information
225 SD_CARD_PROGRAMMING = ((uint32_t)0x00000007), // Card is in programming state
226 SD_CARD_DISCONNECTED = ((uint32_t)0x00000008), // Card is disconnected
227 SD_CARD_ERROR = ((uint32_t)0x000000FF) // Card is in error state
228 } SD_CardState_t;
230 /* Variable(s) ------------------------------------------------------------------------------------------------------*/
232 static SD_Handle_t SD_Handle;
233 SD_CardInfo_t SD_CardInfo;
234 static uint32_t SD_Status;
235 static uint32_t SD_CardRCA;
236 SD_CardType_t SD_CardType;
237 static volatile uint32_t TimeOut;
238 DMA_Stream_TypeDef *dma_stream;
240 /* Private function(s) ----------------------------------------------------------------------------------------------*/
242 static void SD_DataTransferInit (uint32_t Size, uint32_t DataBlockSize, bool IsItReadFromCard);
243 static SD_Error_t SD_TransmitCommand (uint32_t Command, uint32_t Argument, int8_t ResponseType);
244 static SD_Error_t SD_CmdResponse (uint8_t SD_CMD, int8_t ResponseType);
245 static void SD_GetResponse (uint32_t* pResponse);
246 static SD_Error_t CheckOCR_Response (uint32_t Response_R1);
247 static void SD_DMA_Complete (DMA_Stream_TypeDef* pDMA_Stream);
248 static SD_Error_t SD_InitializeCard (void);
250 static SD_Error_t SD_PowerON (void);
251 static SD_Error_t SD_WideBusOperationConfig (uint32_t WideMode);
252 static SD_Error_t SD_FindSCR (uint32_t *pSCR);
254 void SDIO_DMA_ST3_IRQHandler(dmaChannelDescriptor_t *dma);
255 void SDIO_DMA_ST6_IRQHandler(dmaChannelDescriptor_t *dma);
257 /** -----------------------------------------------------------------------------------------------------------------*/
258 /** DataTransferInit
260 * @brief Prepare the state machine for transfer
261 * @param SD_TransferType_e TransfertDir
262 * @param SD_CARD_BlockSize_e Size
264 static void SD_DataTransferInit(uint32_t Size, uint32_t DataBlockSize, bool IsItReadFromCard)
266 uint32_t Direction;
268 SDIO->DTIMER = SD_DATATIMEOUT; // Set the SDIO Data TimeOut value
269 SDIO->DLEN = Size; // Set the SDIO DataLength value
270 Direction = (IsItReadFromCard == true) ? SDIO_DCTRL_DTDIR : 0;
271 SDIO->DCTRL |= (uint32_t)(DataBlockSize | Direction | SDIO_DCTRL_DTEN | 0x01);
272 return;
275 /** -----------------------------------------------------------------------------------------------------------------*/
276 /** SD_TransmitCommand
278 * @brief Send the commande to SDIO
279 * @param uint32_t Command
280 * @param uint32_t Argument Must provide the response size
281 * @param uint8_t ResponseType
282 * @retval SD Card error state
284 static SD_Error_t SD_TransmitCommand(uint32_t Command, uint32_t Argument, int8_t ResponseType)
286 SD_Error_t ErrorState;
288 WRITE_REG(SDIO->ICR, SDIO_ICR_STATIC_FLAGS); // Clear the Command Flags
289 WRITE_REG(SDIO->ARG, (uint32_t)Argument); // Set the SDIO Argument value
290 WRITE_REG(SDIO->CMD, (uint32_t)(Command | SDIO_CMD_CPSMEN)); // Set SDIO command parameters
292 if ((Argument == 0) && (ResponseType == 0)) {
293 ResponseType = -1; // Go idle command
296 ErrorState = SD_CmdResponse(Command & SDIO_CMD_CMDINDEX, ResponseType);
297 WRITE_REG(SDIO->ICR, SDIO_ICR_STATIC_FLAGS); // Clear the Command Flags
299 return ErrorState;
302 /** -----------------------------------------------------------------------------------------------------------------*/
304 * @brief Checks for error conditions for any response.
305 * - R2 (CID or CSD) response.
306 * - R3 (OCR) response.
308 * @param SD_CMD: The sent command Index
309 * @retval SD Card error state
311 static SD_Error_t SD_CmdResponse(uint8_t SD_CMD, int8_t ResponseType)
313 uint32_t Response_R1;
314 uint32_t TimeOut;
315 uint32_t Flag;
317 if (ResponseType == -1) {
318 Flag = SDIO_STA_CMDSENT;
319 } else {
320 Flag = SDIO_STA_CCRCFAIL | SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT;
323 TimeOut = SD_SOFTWARE_COMMAND_TIMEOUT;
324 do {
325 SD_Status = SDIO->STA;
326 TimeOut--;
327 } while (((SD_Status & Flag) == 0) && (TimeOut > 0));
329 if (ResponseType <= 0) {
330 if (TimeOut == 0) {
331 return SD_CMD_RSP_TIMEOUT;
333 else {
334 return SD_OK;
338 if ((SDIO->STA & SDIO_STA_CTIMEOUT) != 0) {
339 return SD_CMD_RSP_TIMEOUT;
342 if (ResponseType == 3) {
343 if (TimeOut == 0) {
344 return SD_CMD_RSP_TIMEOUT; // Card is not V2.0 compliant or card does not support the set voltage range
346 else {
347 return SD_OK; // Card is SD V2.0 compliant
351 if ((SDIO->STA & SDIO_STA_CCRCFAIL) != 0) {
352 return SD_CMD_CRC_FAIL;
355 if (ResponseType == 2) {
356 return SD_OK;
359 if ((uint8_t)SDIO->RESPCMD != SD_CMD) {
360 return SD_ILLEGAL_CMD; // Check if response is of desired command
363 Response_R1 = SDIO->RESP1; // We have received response, retrieve it for analysis
365 if (ResponseType == 1) {
366 return CheckOCR_Response(Response_R1);
368 else if (ResponseType == 6) {
369 if ((Response_R1 & (SD_R6_GENERAL_UNKNOWN_ERROR | SD_R6_ILLEGAL_CMD | SD_R6_COM_CRC_FAILED)) == SD_ALLZERO) {
370 SD_CardRCA = Response_R1;
373 if ((Response_R1 & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR) {
374 return SD_GENERAL_UNKNOWN_ERROR;
377 if ((Response_R1 & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD) {
378 return SD_ILLEGAL_CMD;
381 if ((Response_R1 & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED) {
382 return SD_COM_CRC_FAILED;
386 return SD_OK;
390 /** -----------------------------------------------------------------------------------------------------------------*/
392 * @brief Analyze the OCR response and return the appropriate error code
393 * @param Response_R1: OCR Response code
394 * @retval SD Card error state
396 static SD_Error_t CheckOCR_Response(uint32_t Response_R1)
398 if ((Response_R1 & SD_OCR_ERRORBITS) == SD_ALLZERO) return SD_OK;
399 if ((Response_R1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE) return SD_ADDR_OUT_OF_RANGE;
400 if ((Response_R1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED) return SD_ADDR_MISALIGNED;
401 if ((Response_R1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR) return SD_BLOCK_LEN_ERR;
402 if ((Response_R1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR) return SD_ERASE_SEQ_ERR;
403 if ((Response_R1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM) return SD_BAD_ERASE_PARAM;
404 if ((Response_R1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION) return SD_WRITE_PROT_VIOLATION;
405 if ((Response_R1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED) return SD_LOCK_UNLOCK_FAILED;
406 if ((Response_R1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED) return SD_COM_CRC_FAILED;
407 if ((Response_R1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD) return SD_ILLEGAL_CMD;
408 if ((Response_R1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED) return SD_CARD_ECC_FAILED;
409 if ((Response_R1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR) return SD_CC_ERROR;
410 if ((Response_R1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR)return SD_GENERAL_UNKNOWN_ERROR;
411 if ((Response_R1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN) return SD_STREAM_READ_UNDERRUN;
412 if ((Response_R1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN) return SD_STREAM_WRITE_OVERRUN;
413 if ((Response_R1 & SD_OCR_CID_CSD_OVERWRITE) == SD_OCR_CID_CSD_OVERWRITE) return SD_CID_CSD_OVERWRITE;
414 if ((Response_R1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP) return SD_WP_ERASE_SKIP;
415 if ((Response_R1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED) return SD_CARD_ECC_DISABLED;
416 if ((Response_R1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET) return SD_ERASE_RESET;
417 if ((Response_R1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR) return SD_AKE_SEQ_ERROR;
419 return SD_OK;
423 /** -----------------------------------------------------------------------------------------------------------------*/
424 /** GetResponse
426 * @brief Get response from SD device
427 * @param uint32_t* pResponse
429 static void SD_GetResponse(uint32_t* pResponse)
431 pResponse[0] = SDIO->RESP1;
432 pResponse[1] = SDIO->RESP2;
433 pResponse[2] = SDIO->RESP3;
434 pResponse[3] = SDIO->RESP4;
438 /** -----------------------------------------------------------------------------------------------------------------*/
440 * @brief SD DMA transfer complete RX and TX callback.
441 * @param DMA_Stream_TypeDef* pDMA_Stream
443 static void SD_DMA_Complete(DMA_Stream_TypeDef* pDMA_Stream)
445 if (SD_Handle.RXCplt) {
446 if (SD_Handle.Operation == ((SDIO_DIR_RX << 1) | SD_MULTIPLE_BLOCK)) {
447 /* Send stop command in multiblock write */
448 SD_TransmitCommand((SD_CMD_STOP_TRANSMISSION | SD_CMD_RESPONSE_SHORT), 0, 1);
451 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
452 in the SD DCTRL register */
453 SDIO->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
455 /* Clear all the static flags */
456 SDIO->ICR = SDIO_ICR_STATIC_FLAGS;
458 /* Clear flag */
459 SD_Handle.RXCplt = 0;
461 /* Disable the stream */
462 pDMA_Stream->CR &= ~DMA_SxCR_EN;
464 else {
465 /* Enable Dataend IE */
466 SDIO->MASK |= SDIO_MASK_DATAENDIE;
471 /** -----------------------------------------------------------------------------------------------------------------*/
473 * @brief Initializes all cards or single card as the case may be Card(s) come
474 * into standby state.
475 * @retval SD Card error state
477 static SD_Error_t SD_InitializeCard(void)
479 SD_Error_t ErrorState = SD_OK;
481 if ((SDIO->POWER & SDIO_POWER_PWRCTRL) != 0) {
482 if (SD_CardType != SD_SECURE_DIGITAL_IO) {
483 // Send CMD2 ALL_SEND_CID
484 if ((ErrorState = SD_TransmitCommand((SD_CMD_ALL_SEND_CID | SD_CMD_RESPONSE_LONG), 0, 2)) != SD_OK) {
485 return ErrorState;
488 // Get Card identification number data
489 SD_GetResponse(SD_Handle.CID);
492 if ((SD_CardType == SD_STD_CAPACITY_V1_1) || (SD_CardType == SD_STD_CAPACITY_V2_0) ||
493 (SD_CardType == SD_SECURE_DIGITAL_IO_COMBO) || (SD_CardType == SD_HIGH_CAPACITY)) {
494 // Send CMD3 SET_REL_ADDR with argument 0
495 // SD Card publishes its RCA.
496 if ((ErrorState = SD_TransmitCommand((SD_CMD_SET_REL_ADDR | SD_CMD_RESPONSE_SHORT), 0, 6)) != SD_OK) {
497 return ErrorState;
501 if (SD_CardType != SD_SECURE_DIGITAL_IO) {
502 // Send CMD9 SEND_CSD with argument as card's RCA
503 if ((ErrorState = SD_TransmitCommand((SD_CMD_SEND_CSD | SD_CMD_RESPONSE_LONG), SD_CardRCA, 2)) == SD_OK) {
504 // Get Card Specific Data
505 SD_GetResponse(SD_Handle.CSD);
509 else {
510 ErrorState = SD_REQUEST_NOT_APPLICABLE;
513 return ErrorState;
517 /** -----------------------------------------------------------------------------------------------------------------*/
519 * @brief Prepre the DMA transfer
520 * @param pDMA: DMA Stream to use for the DMA operation
521 * @param pBuffer: Pointer to the buffer that will contain the data to transmit
522 * @param BlockSize: The SD card Data block size
523 * @note BlockSize must be 512 bytes.
524 * @param NumberOfBlocks: Number of blocks to write
525 * @retval SD Card error state
527 static void SD_StartBlockTransfert(uint32_t* pBuffer, uint32_t BlockSize, uint32_t NumberOfBlocks, uint8_t dir)
529 DMA_Stream_TypeDef *pDMA = dma_stream;
531 SDIO->DCTRL = 0; // Initialize data control register
532 SD_Handle.TransferComplete = 0; // Initialize handle flags
533 SD_Handle.TransferError = SD_OK;
534 SD_Handle.Operation = (NumberOfBlocks > 1) ? SD_MULTIPLE_BLOCK : SD_SINGLE_BLOCK; // Initialize SD Read operation
535 SD_Handle.Operation |= dir << 1;
536 SDIO->MASK = 0;
538 if (dir == SDIO_DIR_RX) {
539 SDIO->MASK |= (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | // Enable transfer interrupts
540 SDIO_MASK_DATAENDIE | SDIO_MASK_RXOVERRIE);
542 else {
543 SDIO->MASK |= (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | // Enable transfer interrupts
544 SDIO_MASK_TXUNDERRIE);
547 if (dir == SDIO_DIR_TX) {
548 SDIO->DCTRL |= SDIO_DCTRL_DMAEN; // Enable SDIO DMA transfer
551 pDMA->CR &= ~DMA_SxCR_EN; // Disable the Peripheral
552 while (pDMA->CR & DMA_SxCR_EN);
554 pDMA->NDTR = (uint32_t) (BlockSize * NumberOfBlocks) / 4; // Configure DMA Stream data length
555 pDMA->M0AR = (uint32_t) pBuffer; // Configure DMA Stream memory address
557 if (dir == SDIO_DIR_RX) {
558 pDMA->CR &= ~(0x01U << 6U); // Sets peripheral to memory
559 } else {
560 pDMA->CR |= DMA_MEMORY_TO_PERIPH; // Sets memory to peripheral
563 // Clear the transfer error flag
564 if (dma_stream == DMA2_Stream3) {
565 DMA2->LIFCR = DMA_LIFCR_CTEIF3 | DMA_LIFCR_CDMEIF3 | DMA_LIFCR_CFEIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CTCIF3;
566 } else {
567 DMA2->HIFCR = DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 | DMA_HIFCR_CFEIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTCIF6;
570 pDMA->CR |= DMA_SxCR_TCIE | DMA_SxCR_HTIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE; // Enable all interrupts
571 pDMA->FCR |= DMA_SxFCR_FEIE;
572 pDMA->CR |= DMA_SxCR_EN; // Enable the Peripheral
574 if (dir == SDIO_DIR_RX) {
575 SDIO->DCTRL |= SDIO_DCTRL_DMAEN;
580 /** -----------------------------------------------------------------------------------------------------------------*/
582 * @brief Reads block(s) from a specified address in a card. The Data transfer
583 * is managed by DMA mode.
584 * @note This API should be followed by the function SD_CheckOperation()
585 * to check the completion of the read process
586 * @param pReadBuffer: Pointer to the buffer that will contain the received data
587 * @param ReadAddr: Address from where data is to be read
588 * @param BlockSize: SD card Data block size
589 * @note BlockSize must be 512 bytes.
590 * @param NumberOfBlocks: Number of blocks to read.
591 * @retval SD Card error state
593 SD_Error_t SD_ReadBlocks_DMA(uint64_t ReadAddress, uint32_t *buffer, uint32_t BlockSize, uint32_t NumberOfBlocks)
595 SD_Error_t ErrorState;
596 uint32_t CmdIndex;
597 SD_Handle.RXCplt = 1;
599 //printf("Reading at %ld into %p %ld blocks\n", (uint32_t)ReadAddress, (void*)buffer, NumberOfBlocks);
601 if (SD_CardType != SD_HIGH_CAPACITY) {
602 ReadAddress *= 512;
605 SD_StartBlockTransfert(buffer, BlockSize, NumberOfBlocks, SDIO_DIR_RX);
607 // Configure the SD DPSM (Data Path State Machine)
608 SD_DataTransferInit(BlockSize * NumberOfBlocks, SD_DATABLOCK_SIZE_512B, true);
610 // Set Block Size for Card
611 ErrorState = SD_TransmitCommand((SD_CMD_SET_BLOCKLEN | SD_CMD_RESPONSE_SHORT), BlockSize, 1);
613 // Send CMD18 READ_MULT_BLOCK with argument data address
614 // or send CMD17 READ_SINGLE_BLOCK depending on number of block
615 uint8_t retries = 10;
616 CmdIndex = (NumberOfBlocks > 1) ? SD_CMD_READ_MULT_BLOCK : SD_CMD_READ_SINGLE_BLOCK;
617 do {
618 ErrorState = SD_TransmitCommand((CmdIndex | SD_CMD_RESPONSE_SHORT), (uint32_t)ReadAddress, 1);
619 if (ErrorState != SD_OK && retries--) {
620 ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1);
622 } while (ErrorState != SD_OK && retries);
624 if (ErrorState != SD_OK) {
625 SD_Handle.RXCplt = 0;
628 // Update the SD transfer error in SD handle
629 SD_Handle.TransferError = ErrorState;
631 return ErrorState;
635 /** -----------------------------------------------------------------------------------------------------------------*/
637 * @brief Writes block(s) to a specified address in a card. The Data transfer
638 * is managed by DMA mode.
639 * @note This API should be followed by the function SD_CheckOperation()
640 * to check the completion of the write process (by SD current status polling).
641 * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit
642 * @param WriteAddress: Address from where data is to be read
643 * @param BlockSize: the SD card Data block size
644 * @note BlockSize must be 512 bytes.
645 * @param NumberOfBlocks: Number of blocks to write
646 * @retval SD Card error state
648 SD_Error_t SD_WriteBlocks_DMA(uint64_t WriteAddress, uint32_t *buffer, uint32_t BlockSize, uint32_t NumberOfBlocks)
650 SD_Error_t ErrorState;
651 uint32_t CmdIndex;
652 SD_Handle.TXCplt = 1;
654 //printf("Reading at %ld into %p %ld blocks\n", (uint32_t)WriteAddress, (void*)buffer, NumberOfBlocks);
656 if (SD_CardType != SD_HIGH_CAPACITY) {
657 WriteAddress *= 512;
660 // Check number of blocks command
661 // Send CMD24 WRITE_SINGLE_BLOCK
662 // Send CMD25 WRITE_MULT_BLOCK with argument data address
663 CmdIndex = (NumberOfBlocks > 1) ? SD_CMD_WRITE_MULT_BLOCK : SD_CMD_WRITE_SINGLE_BLOCK;
665 // Set Block Size for Card
666 uint8_t retries = 10;
667 do {
668 ErrorState = SD_TransmitCommand((CmdIndex | SD_CMD_RESPONSE_SHORT), (uint32_t)WriteAddress, 1);
669 if (ErrorState != SD_OK && retries--) {
670 ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1);
672 } while (ErrorState != SD_OK && retries);
674 if (ErrorState != SD_OK) {
675 SD_Handle.TXCplt = 0;
676 return ErrorState;
679 SD_StartBlockTransfert(buffer, BlockSize, NumberOfBlocks, SDIO_DIR_TX);
681 // Configure the SD DPSM (Data Path State Machine)
682 SD_DataTransferInit(BlockSize * NumberOfBlocks, SD_DATABLOCK_SIZE_512B, false);
684 SD_Handle.TransferError = ErrorState;
686 return ErrorState;
689 SD_Error_t SD_CheckWrite(void)
691 if (SD_Handle.TXCplt != 0) return SD_BUSY;
692 return SD_OK;
695 SD_Error_t SD_CheckRead(void)
697 if (SD_Handle.RXCplt != 0) return SD_BUSY;
698 return SD_OK;
702 /** -----------------------------------------------------------------------------------------------------------------*/
704 * @brief Returns information about specific card.
705 * contains all SD cardinformation
706 * @retval SD Card error state
708 SD_Error_t SD_GetCardInfo(void)
710 SD_Error_t ErrorState = SD_OK;
711 uint32_t Temp = 0;
713 // Byte 0
714 Temp = (SD_Handle.CSD[0] & 0xFF000000) >> 24;
715 SD_CardInfo.SD_csd.CSDStruct = (uint8_t)((Temp & 0xC0) >> 6);
716 SD_CardInfo.SD_csd.SysSpecVersion = (uint8_t)((Temp & 0x3C) >> 2);
717 SD_CardInfo.SD_csd.Reserved1 = Temp & 0x03;
719 // Byte 1
720 Temp = (SD_Handle.CSD[0] & 0x00FF0000) >> 16;
721 SD_CardInfo.SD_csd.TAAC = (uint8_t)Temp;
723 // Byte 2
724 Temp = (SD_Handle.CSD[0] & 0x0000FF00) >> 8;
725 SD_CardInfo.SD_csd.NSAC = (uint8_t)Temp;
727 // Byte 3
728 Temp = SD_Handle.CSD[0] & 0x000000FF;
729 SD_CardInfo.SD_csd.MaxBusClkFrec = (uint8_t)Temp;
731 // Byte 4
732 Temp = (SD_Handle.CSD[1] & 0xFF000000) >> 24;
733 SD_CardInfo.SD_csd.CardComdClasses = (uint16_t)(Temp << 4);
735 // Byte 5
736 Temp = (SD_Handle.CSD[1] & 0x00FF0000) >> 16;
737 SD_CardInfo.SD_csd.CardComdClasses |= (uint16_t)((Temp & 0xF0) >> 4);
738 SD_CardInfo.SD_csd.RdBlockLen = (uint8_t)(Temp & 0x0F);
740 // Byte 6
741 Temp = (SD_Handle.CSD[1] & 0x0000FF00) >> 8;
742 SD_CardInfo.SD_csd.PartBlockRead = (uint8_t)((Temp & 0x80) >> 7);
743 SD_CardInfo.SD_csd.WrBlockMisalign = (uint8_t)((Temp & 0x40) >> 6);
744 SD_CardInfo.SD_csd.RdBlockMisalign = (uint8_t)((Temp & 0x20) >> 5);
745 SD_CardInfo.SD_csd.DSRImpl = (uint8_t)((Temp & 0x10) >> 4);
746 SD_CardInfo.SD_csd.Reserved2 = 0; /*!< Reserved */
748 if ((SD_CardType == SD_STD_CAPACITY_V1_1) || (SD_CardType == SD_STD_CAPACITY_V2_0)) {
749 SD_CardInfo.SD_csd.DeviceSize = (Temp & 0x03) << 10;
751 // Byte 7
752 Temp = (uint8_t)(SD_Handle.CSD[1] & 0x000000FF);
753 SD_CardInfo.SD_csd.DeviceSize |= (Temp) << 2;
755 // Byte 8
756 Temp = (uint8_t)((SD_Handle.CSD[2] & 0xFF000000) >> 24);
757 SD_CardInfo.SD_csd.DeviceSize |= (Temp & 0xC0) >> 6;
759 SD_CardInfo.SD_csd.MaxRdCurrentVDDMin = (Temp & 0x38) >> 3;
760 SD_CardInfo.SD_csd.MaxRdCurrentVDDMax = (Temp & 0x07);
762 // Byte 9
763 Temp = (uint8_t)((SD_Handle.CSD[2] & 0x00FF0000) >> 16);
764 SD_CardInfo.SD_csd.MaxWrCurrentVDDMin = (Temp & 0xE0) >> 5;
765 SD_CardInfo.SD_csd.MaxWrCurrentVDDMax = (Temp & 0x1C) >> 2;
766 SD_CardInfo.SD_csd.DeviceSizeMul = (Temp & 0x03) << 1;
768 // Byte 10
769 Temp = (uint8_t)((SD_Handle.CSD[2] & 0x0000FF00) >> 8);
770 SD_CardInfo.SD_csd.DeviceSizeMul |= (Temp & 0x80) >> 7;
772 SD_CardInfo.CardCapacity = (SD_CardInfo.SD_csd.DeviceSize + 1) ;
773 SD_CardInfo.CardCapacity *= (1 << (SD_CardInfo.SD_csd.DeviceSizeMul + 2));
774 SD_CardInfo.CardBlockSize = 1 << (SD_CardInfo.SD_csd.RdBlockLen);
775 SD_CardInfo.CardCapacity *= SD_CardInfo.CardBlockSize;
777 else if (SD_CardType == SD_HIGH_CAPACITY) {
778 // Byte 7
779 Temp = (uint8_t)(SD_Handle.CSD[1] & 0x000000FF);
780 SD_CardInfo.SD_csd.DeviceSize = (Temp & 0x3F) << 16;
782 // Byte 8
783 Temp = (uint8_t)((SD_Handle.CSD[2] & 0xFF000000) >> 24);
785 SD_CardInfo.SD_csd.DeviceSize |= (Temp << 8);
787 // Byte 9
788 Temp = (uint8_t)((SD_Handle.CSD[2] & 0x00FF0000) >> 16);
790 SD_CardInfo.SD_csd.DeviceSize |= (Temp);
792 // Byte 10
793 Temp = (uint8_t)((SD_Handle.CSD[2] & 0x0000FF00) >> 8);
795 SD_CardInfo.CardCapacity = ((uint64_t)SD_CardInfo.SD_csd.DeviceSize + 1) * 1024;
796 SD_CardInfo.CardBlockSize = 512;
798 else {
799 // Not supported card type
800 ErrorState = SD_ERROR;
803 SD_CardInfo.SD_csd.EraseGrSize = (Temp & 0x40) >> 6;
804 SD_CardInfo.SD_csd.EraseGrMul = (Temp & 0x3F) << 1;
806 // Byte 11
807 Temp = (uint8_t)(SD_Handle.CSD[2] & 0x000000FF);
808 SD_CardInfo.SD_csd.EraseGrMul |= (Temp & 0x80) >> 7;
809 SD_CardInfo.SD_csd.WrProtectGrSize = (Temp & 0x7F);
811 // Byte 12
812 Temp = (uint8_t)((SD_Handle.CSD[3] & 0xFF000000) >> 24);
813 SD_CardInfo.SD_csd.WrProtectGrEnable = (Temp & 0x80) >> 7;
814 SD_CardInfo.SD_csd.ManDeflECC = (Temp & 0x60) >> 5;
815 SD_CardInfo.SD_csd.WrSpeedFact = (Temp & 0x1C) >> 2;
816 SD_CardInfo.SD_csd.MaxWrBlockLen = (Temp & 0x03) << 2;
818 // Byte 13
819 Temp = (uint8_t)((SD_Handle.CSD[3] & 0x00FF0000) >> 16);
820 SD_CardInfo.SD_csd.MaxWrBlockLen |= (Temp & 0xC0) >> 6;
821 SD_CardInfo.SD_csd.WriteBlockPaPartial = (Temp & 0x20) >> 5;
822 SD_CardInfo.SD_csd.Reserved3 = 0;
823 SD_CardInfo.SD_csd.ContentProtectAppli = (Temp & 0x01);
825 // Byte 14
826 Temp = (uint8_t)((SD_Handle.CSD[3] & 0x0000FF00) >> 8);
827 SD_CardInfo.SD_csd.FileFormatGrouop = (Temp & 0x80) >> 7;
828 SD_CardInfo.SD_csd.CopyFlag = (Temp & 0x40) >> 6;
829 SD_CardInfo.SD_csd.PermWrProtect = (Temp & 0x20) >> 5;
830 SD_CardInfo.SD_csd.TempWrProtect = (Temp & 0x10) >> 4;
831 SD_CardInfo.SD_csd.FileFormat = (Temp & 0x0C) >> 2;
832 SD_CardInfo.SD_csd.ECC = (Temp & 0x03);
834 // Byte 15
835 Temp = (uint8_t)(SD_Handle.CSD[3] & 0x000000FF);
836 SD_CardInfo.SD_csd.CSD_CRC = (Temp & 0xFE) >> 1;
837 SD_CardInfo.SD_csd.Reserved4 = 1;
839 // Byte 0
840 Temp = (uint8_t)((SD_Handle.CID[0] & 0xFF000000) >> 24);
841 SD_CardInfo.SD_cid.ManufacturerID = Temp;
843 // Byte 1
844 Temp = (uint8_t)((SD_Handle.CID[0] & 0x00FF0000) >> 16);
845 SD_CardInfo.SD_cid.OEM_AppliID = Temp << 8;
847 // Byte 2
848 Temp = (uint8_t)((SD_Handle.CID[0] & 0x000000FF00) >> 8);
849 SD_CardInfo.SD_cid.OEM_AppliID |= Temp;
851 // Byte 3
852 Temp = (uint8_t)(SD_Handle.CID[0] & 0x000000FF);
853 SD_CardInfo.SD_cid.ProdName1 = Temp << 24;
855 // Byte 4
856 Temp = (uint8_t)((SD_Handle.CID[1] & 0xFF000000) >> 24);
857 SD_CardInfo.SD_cid.ProdName1 |= Temp << 16;
859 // Byte 5
860 Temp = (uint8_t)((SD_Handle.CID[1] & 0x00FF0000) >> 16);
861 SD_CardInfo.SD_cid.ProdName1 |= Temp << 8;
863 // Byte 6
864 Temp = (uint8_t)((SD_Handle.CID[1] & 0x0000FF00) >> 8);
865 SD_CardInfo.SD_cid.ProdName1 |= Temp;
867 // Byte 7
868 Temp = (uint8_t)(SD_Handle.CID[1] & 0x000000FF);
869 SD_CardInfo.SD_cid.ProdName2 = Temp;
871 // Byte 8
872 Temp = (uint8_t)((SD_Handle.CID[2] & 0xFF000000) >> 24);
873 SD_CardInfo.SD_cid.ProdRev = Temp;
875 // Byte 9
876 Temp = (uint8_t)((SD_Handle.CID[2] & 0x00FF0000) >> 16);
877 SD_CardInfo.SD_cid.ProdSN = Temp << 24;
879 // Byte 10
880 Temp = (uint8_t)((SD_Handle.CID[2] & 0x0000FF00) >> 8);
881 SD_CardInfo.SD_cid.ProdSN |= Temp << 16;
883 // Byte 11
884 Temp = (uint8_t)(SD_Handle.CID[2] & 0x000000FF);
885 SD_CardInfo.SD_cid.ProdSN |= Temp << 8;
887 // Byte 12
888 Temp = (uint8_t)((SD_Handle.CID[3] & 0xFF000000) >> 24);
889 SD_CardInfo.SD_cid.ProdSN |= Temp;
891 // Byte 13
892 Temp = (uint8_t)((SD_Handle.CID[3] & 0x00FF0000) >> 16);
893 SD_CardInfo.SD_cid.Reserved1 |= (Temp & 0xF0) >> 4;
894 SD_CardInfo.SD_cid.ManufactDate = (Temp & 0x0F) << 8;
896 // Byte 14
897 Temp = (uint8_t)((SD_Handle.CID[3] & 0x0000FF00) >> 8);
898 SD_CardInfo.SD_cid.ManufactDate |= Temp;
900 // Byte 15
901 Temp = (uint8_t)(SD_Handle.CID[3] & 0x000000FF);
902 SD_CardInfo.SD_cid.CID_CRC = (Temp & 0xFE) >> 1;
903 SD_CardInfo.SD_cid.Reserved2 = 1;
905 return ErrorState;
909 /** -----------------------------------------------------------------------------------------------------------------*/
911 * @brief Enables wide bus operation for the requested card if supported by
912 * card.
913 * @param WideMode: Specifies the SD card wide bus mode
914 * This parameter can be one of the following values:
915 * @arg SD_BUS_WIDE_8B: 8-bit data transfer (Only for MMC)
916 * @arg SD_BUS_WIDE_4B: 4-bit data transfer
917 * @arg SD_BUS_WIDE_1B: 1-bit data transfer
918 * @retval SD Card error state
920 static SD_Error_t SD_WideBusOperationConfig(uint32_t WideMode)
922 SD_Error_t ErrorState = SD_OK;
923 uint32_t Temp;
924 uint32_t SCR[2] = {0, 0};
926 if ((SD_CardType == SD_STD_CAPACITY_V1_1) || (SD_CardType == SD_STD_CAPACITY_V2_0) || (SD_CardType == SD_HIGH_CAPACITY)) {
927 if (WideMode == SD_BUS_WIDE_8B) {
928 ErrorState = SD_UNSUPPORTED_FEATURE;
930 else if ((WideMode == SD_BUS_WIDE_4B) || (WideMode == SD_BUS_WIDE_1B)) {
931 if ((SDIO->RESP1 & SD_CARD_LOCKED) != SD_CARD_LOCKED) {
932 // Get SCR Register
933 ErrorState = SD_FindSCR(SCR);
934 if (ErrorState == SD_OK) {
935 Temp = (WideMode == SD_BUS_WIDE_4B) ? SD_WIDE_BUS_SUPPORT : SD_SINGLE_BUS_SUPPORT;
937 // If requested card supports wide bus operation
938 if ((SCR[1] & Temp) != SD_ALLZERO) {
939 // Send CMD55 APP_CMD with argument as card's RCA.
940 ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), SD_CardRCA, 1);
941 if (ErrorState == SD_OK) {
942 Temp = (WideMode == SD_BUS_WIDE_4B) ? 2 : 0;
944 // Send ACMD6 APP_CMD with argument as 2 for wide bus mode
945 ErrorState = SD_TransmitCommand((SD_CMD_APP_SD_SET_BUSWIDTH | SD_CMD_RESPONSE_SHORT), Temp, 1);
948 else {
949 ErrorState = SD_REQUEST_NOT_APPLICABLE;
953 else {
954 ErrorState = SD_LOCK_UNLOCK_FAILED;
957 else {
958 ErrorState = SD_INVALID_PARAMETER; // WideMode is not a valid argument
961 if (ErrorState == SD_OK) {
962 // Configure the SDIO peripheral, we need this delay for some reason...
963 while ((READ_REG(SDIO->CLKCR) & 0x800) != WideMode) {
964 MODIFY_REG(SDIO->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) WideMode);
968 else {
969 ErrorState = SD_UNSUPPORTED_FEATURE;
973 return ErrorState;
977 /** -----------------------------------------------------------------------------------------------------------------*/
979 * @brief Switches the SD card to High Speed mode.
980 * This API must be used after "Transfer State"
981 * @retval SD Card error state
983 SD_Error_t SD_HighSpeed(void)
985 SD_Error_t ErrorState;
986 uint8_t SD_hs[64] = {0};
987 uint32_t SD_scr[2] = {0, 0};
988 uint32_t SD_SPEC = 0;
989 uint32_t Count = 0;
990 uint32_t* Buffer = (uint32_t *)SD_hs;
992 // Initialize the Data control register
993 SDIO->DCTRL = 0;
995 // Get SCR Register
996 if ((ErrorState = SD_FindSCR(SD_scr)) != SD_OK) {
997 return ErrorState;
1000 // Test the Version supported by the card
1001 SD_SPEC = (SD_scr[1] & 0x01000000) | (SD_scr[1] & 0x02000000);
1003 if (SD_SPEC != SD_ALLZERO) {
1004 // Set Block Size for Card
1005 if ((ErrorState = SD_TransmitCommand((SD_CMD_SET_BLOCKLEN | SD_CMD_RESPONSE_SHORT), 64, 1)) != SD_OK) {
1006 return ErrorState;
1009 // Configure the SD DPSM (Data Path State Machine)
1010 SD_DataTransferInit(64, SD_DATABLOCK_SIZE_64B, true);
1012 // Send CMD6 switch mode
1013 if ((ErrorState =SD_TransmitCommand((SD_CMD_HS_SWITCH | SD_CMD_RESPONSE_SHORT), 0x80FFFF01, 1)) != SD_OK) {
1014 return ErrorState;
1017 while ((SDIO->STA & (SDIO_STA_RXOVERR | SDIO_STA_DCRCFAIL | SDIO_STA_DTIMEOUT | SDIO_STA_DBCKEND)) == 0) {
1018 if ((SDIO->STA & SDIO_STA_RXFIFOHF) != 0) {
1019 for(Count = 0; Count < 8; Count++) {
1020 *(Buffer + Count) = SDIO->FIFO;
1023 Buffer += 8;
1027 if ((SDIO->STA & SDIO_STA_DTIMEOUT) != 0) {
1028 return SD_DATA_TIMEOUT;
1030 else if ((SDIO->STA & SDIO_STA_DCRCFAIL) != 0) {
1031 return SD_DATA_CRC_FAIL;
1033 else if ((SDIO->STA & SDIO_STA_RXOVERR) != 0) {
1034 return SD_RX_OVERRUN;
1037 Count = SD_DATATIMEOUT;
1039 while (((SDIO->STA & SDIO_STA_RXDAVL) != 0) && (Count > 0)) {
1040 *Buffer = SDIO->FIFO;
1041 Buffer++;
1042 Count--;
1045 // Test if the switch mode HS is ok
1046 if ((SD_hs[13] & 2) != 2) {
1047 ErrorState = SD_UNSUPPORTED_FEATURE;
1051 return ErrorState;
1055 /** -----------------------------------------------------------------------------------------------------------------*/
1057 * @brief Gets the current card's data status.
1058 * @retval Data Transfer state
1060 SD_Error_t SD_GetStatus(void)
1062 SD_Error_t ErrorState;
1063 uint32_t Response1;
1064 SD_CardState_t CardState;
1067 // Send Status command
1068 if ((ErrorState = SD_TransmitCommand((SD_CMD_SEND_STATUS | SD_CMD_RESPONSE_SHORT), SD_CardRCA, 1)) == SD_OK) {
1069 Response1 = SDIO->RESP1;
1070 CardState = (SD_CardState_t)((Response1 >> 9) & 0x0F);
1072 // Find SD status according to card state
1073 if (CardState == SD_CARD_TRANSFER) {
1074 ErrorState = SD_OK;
1076 else if (CardState == SD_CARD_ERROR) {
1077 ErrorState = SD_ERROR;
1079 else {
1080 ErrorState = SD_BUSY;
1083 else {
1084 ErrorState = SD_ERROR;
1087 return ErrorState;
1091 /** -----------------------------------------------------------------------------------------------------------------*/
1093 * @brief Gets the SD card status.
1094 * @retval SD Card error state
1096 SD_Error_t SD_GetCardStatus(SD_CardStatus_t* pCardStatus)
1098 SD_Error_t ErrorState;
1099 uint32_t Temp = 0;
1100 uint32_t Status[16];
1101 uint32_t Count;
1103 // Check SD response
1104 if ((SDIO->RESP1 & SD_CARD_LOCKED) == SD_CARD_LOCKED) {
1105 return SD_LOCK_UNLOCK_FAILED;
1108 // Set block size for card if it is not equal to current block size for card
1109 if ((ErrorState = SD_TransmitCommand((SD_CMD_SET_BLOCKLEN | SD_CMD_RESPONSE_SHORT), 64, 1)) != SD_OK) {
1110 return ErrorState;
1113 // Send CMD55
1114 if ((ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), SD_CardRCA, 1)) != SD_OK) {
1115 return ErrorState;
1118 // Configure the SD DPSM (Data Path State Machine)
1119 SD_DataTransferInit(64, SD_DATABLOCK_SIZE_64B, true);
1121 // Send ACMD13 (SD_APP_STAUS) with argument as card's RCA
1122 if ((ErrorState = SD_TransmitCommand((SD_CMD_SD_APP_STATUS | SD_CMD_RESPONSE_SHORT), 0, 1)) != SD_OK) {
1123 return ErrorState;
1126 // Get status data
1127 while ((SDIO->STA & (SDIO_STA_RXOVERR | SDIO_STA_DCRCFAIL | SDIO_STA_DTIMEOUT | SDIO_STA_DBCKEND)) == 0) {
1128 if ((SDIO->STA & SDIO_STA_RXFIFOHF) != 0) {
1129 for(Count = 0; Count < 8; Count++) {
1130 Status[Count] = SDIO->FIFO;
1135 if ((SDIO->STA & SDIO_STA_DTIMEOUT) != 0) {
1136 return SD_DATA_TIMEOUT;
1138 else if ((SDIO->STA & SDIO_STA_DCRCFAIL) != 0) {
1139 return SD_DATA_CRC_FAIL;
1141 else if ((SDIO->STA & SDIO_STA_RXOVERR) != 0) {
1142 return SD_RX_OVERRUN;
1144 else {
1145 Count = SD_DATATIMEOUT;
1146 while (((SDIO->STA & SDIO_STA_RXDAVL) != 0) && (Count > 0)) {
1147 volatile uint8_t tmp = SDIO->FIFO;
1148 (void)tmp;
1149 Count--;
1153 // Byte 0
1154 Temp = (Status[0] & 0xC0) >> 6;
1155 pCardStatus->DAT_BUS_WIDTH = (uint8_t)Temp;
1157 // Byte 0
1158 Temp = (Status[0] & 0x20) >> 5;
1159 pCardStatus->SECURED_MODE = (uint8_t)Temp;
1161 // Byte 2
1162 Temp = (Status[2] & 0xFF);
1163 pCardStatus->SD_CARD_TYPE = (uint8_t)(Temp << 8);
1165 // Byte 3
1166 Temp = (Status[3] & 0xFF);
1167 pCardStatus->SD_CARD_TYPE |= (uint8_t)Temp;
1169 // Byte 4
1170 Temp = (Status[4] & 0xFF);
1171 pCardStatus->SIZE_OF_PROTECTED_AREA = (uint8_t)(Temp << 24);
1173 // Byte 5
1174 Temp = (Status[5] & 0xFF);
1175 pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(Temp << 16);
1177 // Byte 6
1178 Temp = (Status[6] & 0xFF);
1179 pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(Temp << 8);
1181 // Byte 7
1182 Temp = (Status[7] & 0xFF);
1183 pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)Temp;
1185 // Byte 8
1186 Temp = (Status[8] & 0xFF);
1187 pCardStatus->SPEED_CLASS = (uint8_t)Temp;
1189 // Byte 9
1190 Temp = (Status[9] & 0xFF);
1191 pCardStatus->PERFORMANCE_MOVE = (uint8_t)Temp;
1193 // Byte 10
1194 Temp = (Status[10] & 0xF0) >> 4;
1195 pCardStatus->AU_SIZE = (uint8_t)Temp;
1197 // Byte 11
1198 Temp = (Status[11] & 0xFF);
1199 pCardStatus->ERASE_SIZE = (uint8_t)(Temp << 8);
1201 // Byte 12
1202 Temp = (Status[12] & 0xFF);
1203 pCardStatus->ERASE_SIZE |= (uint8_t)Temp;
1205 // Byte 13
1206 Temp = (Status[13] & 0xFC) >> 2;
1207 pCardStatus->ERASE_TIMEOUT = (uint8_t)Temp;
1209 // Byte 13
1210 Temp = (Status[13] & 0x3);
1211 pCardStatus->ERASE_OFFSET = (uint8_t)Temp;
1213 return SD_OK;
1217 /** -----------------------------------------------------------------------------------------------------------------*/
1219 * @brief Enquires cards about their operating voltage and configures clock
1220 * controls and stores SD information that will be needed in future
1221 * in the SD handle.
1222 * @retval SD Card error state
1224 static SD_Error_t SD_PowerON(void)
1226 SD_Error_t ErrorState;
1227 uint32_t Response;
1228 uint32_t Count;
1229 uint32_t ValidVoltage;
1230 uint32_t SD_Type;
1231 //uint32_t TickStart;
1233 Count = 0;
1234 ValidVoltage = 0;
1235 SD_Type = SD_RESP_STD_CAPACITY;
1237 // Power ON Sequence -------------------------------------------------------
1238 SDIO->CLKCR &= ~SDIO_CLKCR_CLKEN; // Disable SDIO Clock
1239 SDIO->POWER = SDIO_POWER_PWRCTRL; // Set Power State to ON
1241 // 1ms: required power up waiting time before starting the SD initialization sequence (make it 2 to be safe)
1242 delay(2);
1244 SDIO->CLKCR |= SDIO_CLKCR_CLKEN; // Enable SDIO Clock
1246 // CMD0: GO_IDLE_STATE -----------------------------------------------------
1247 // No CMD response required
1248 if ((ErrorState = SD_TransmitCommand(SD_CMD_GO_IDLE_STATE, 0, 0)) != SD_OK) {
1249 // CMD Response Timeout (wait for CMDSENT flag)
1250 return ErrorState;
1253 // CMD8: SEND_IF_COND ------------------------------------------------------
1254 // Send CMD8 to verify SD card interface operating condition
1255 // Argument: - [31:12]: Reserved (shall be set to '0')
1256 //- [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
1257 //- [7:0]: Check Pattern (recommended 0xAA)
1258 // CMD Response: R7 */
1259 if ((ErrorState = SD_TransmitCommand((SD_SDIO_SEND_IF_COND | SD_CMD_RESPONSE_SHORT), SD_CHECK_PATTERN, 7)) == SD_OK) {
1260 // SD Card 2.0
1261 SD_CardType = SD_STD_CAPACITY_V2_0;
1262 SD_Type = SD_RESP_HIGH_CAPACITY;
1265 // Send CMD55
1266 // If ErrorState is Command Timeout, it is a MMC card
1267 // If ErrorState is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch) or SD card 1.x
1268 if ((ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1)) == SD_OK) {
1269 // SD CARD
1270 // Send ACMD41 SD_APP_OP_COND with Argument 0x80100000
1271 while ((ValidVoltage == 0) && (Count < SD_MAX_VOLT_TRIAL)) {
1272 // SEND CMD55 APP_CMD with RCA as 0
1273 if ((ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), 0, 1)) != SD_OK) {
1274 return ErrorState;
1277 // Send CMD41
1278 if ((ErrorState = SD_TransmitCommand((SD_CMD_SD_APP_OP_COND | SD_CMD_RESPONSE_SHORT), SD_VOLTAGE_WINDOW_SD | SD_Type, 3)) != SD_OK) {
1279 return ErrorState;
1282 Response = SDIO->RESP1; // Get command response
1283 ValidVoltage = (((Response >> 31) == 1) ? 1 : 0); // Get operating voltage
1284 Count++;
1287 if (Count >= SD_MAX_VOLT_TRIAL) {
1288 return SD_INVALID_VOLTRANGE;
1291 if ((Response & SD_RESP_HIGH_CAPACITY) == SD_RESP_HIGH_CAPACITY) {
1292 SD_CardType = SD_HIGH_CAPACITY;
1294 } // else MMC Card
1296 return ErrorState;
1300 /** -----------------------------------------------------------------------------------------------------------------*/
1302 * @brief Finds the SD card SCR register value.
1303 * @param pSCR: pointer to the buffer that will contain the SCR value
1304 * @retval SD Card error state
1306 static SD_Error_t SD_FindSCR(uint32_t *pSCR)
1308 SD_Error_t ErrorState;
1309 uint32_t Index = 0;
1310 uint32_t tempscr[2] = {0, 0};
1312 // Set Block Size To 8 Bytes
1313 // Send CMD55 APP_CMD with argument as card's RCA
1314 if ((ErrorState = SD_TransmitCommand((SD_CMD_SET_BLOCKLEN | SD_CMD_RESPONSE_SHORT), 8, 1)) == SD_OK) {
1315 // Send CMD55 APP_CMD with argument as card's RCA
1316 if ((ErrorState = SD_TransmitCommand((SD_CMD_APP_CMD | SD_CMD_RESPONSE_SHORT), SD_CardRCA, 1)) == SD_OK) {
1317 SD_DataTransferInit(8, SD_DATABLOCK_SIZE_8B, true);
1319 // Send ACMD51 SD_APP_SEND_SCR with argument as 0
1320 if ((ErrorState = SD_TransmitCommand((SD_CMD_SD_APP_SEND_SCR | SD_CMD_RESPONSE_SHORT), 0, 1)) == SD_OK) {
1321 while ((SDIO->STA & (SDIO_STA_RXOVERR | SDIO_STA_DCRCFAIL | SDIO_STA_DTIMEOUT | SDIO_STA_DBCKEND)) == 0) {
1322 if ((SDIO->STA & SDIO_STA_RXDAVL) != 0) {
1323 *(tempscr + Index) = SDIO->FIFO;
1324 Index++;
1328 if ((SDIO->STA & SDIO_STA_DTIMEOUT) != 0) {
1329 ErrorState = SD_DATA_TIMEOUT;
1331 else if ((SDIO->STA & SDIO_STA_DCRCFAIL) != 0) {
1332 ErrorState = SD_DATA_CRC_FAIL;
1334 else if ((SDIO->STA & SDIO_STA_RXOVERR) != 0) {
1335 ErrorState = SD_RX_OVERRUN;
1337 else if ((SDIO->STA & SDIO_STA_RXDAVL) != 0) {
1338 ErrorState = SD_OUT_OF_BOUND;
1340 else {
1341 *(pSCR + 1) = ((tempscr[0] & SD_0TO7BITS) << 24) | ((tempscr[0] & SD_8TO15BITS) << 8) |
1342 ((tempscr[0] & SD_16TO23BITS) >> 8) | ((tempscr[0] & SD_24TO31BITS) >> 24);
1344 *(pSCR) = ((tempscr[1] & SD_0TO7BITS) << 24) | ((tempscr[1] & SD_8TO15BITS) << 8) |
1345 ((tempscr[1] & SD_16TO23BITS) >> 8) | ((tempscr[1] & SD_24TO31BITS) >> 24);
1351 return ErrorState;
1355 /** -----------------------------------------------------------------------------------------------------------------*/
1357 * @brief Initialize the SDIO module, DMA, and IO
1359 bool SD_Initialize_LL(DMA_Stream_TypeDef *dmaRef)
1361 // Sanity check DMA stread - we only support two possible
1362 if (((uint32_t)dmaRef != (uint32_t)DMA2_Stream3) && ((uint32_t)dmaRef != (uint32_t)DMA2_Stream6)) {
1363 return false;
1366 // Reset SDIO Module
1367 RCC->APB2RSTR |= RCC_APB2RSTR_SDIORST;
1368 delay(1);
1369 RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST;
1370 delay(1);
1372 // Enable SDIO clock
1373 RCC->APB2ENR |= RCC_APB2ENR_SDIOEN;
1375 // Enable DMA2 clocks
1376 RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
1378 //Configure Pins
1379 RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN;
1381 const IO_t d0 = IOGetByTag(IO_TAG(PC8));
1382 const IO_t clk = IOGetByTag(IO_TAG(PC12));
1383 const IO_t cmd = IOGetByTag(IO_TAG(PD2));
1385 #define SDIO_DATA IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_100MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL)
1386 #define SDIO_CMD IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_100MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL)
1387 #define SDIO_CLK IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_100MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL)
1389 IOInit(d0, OWNER_SDCARD, RESOURCE_NONE, 0);
1390 IOConfigGPIOAF(d0, SDIO_DATA, GPIO_AF_SDIO);
1392 #ifdef SDCARD_SDIO_4BIT
1393 const IO_t d1 = IOGetByTag(IO_TAG(PC9));
1394 const IO_t d2 = IOGetByTag(IO_TAG(PC10));
1395 const IO_t d3 = IOGetByTag(IO_TAG(PC11));
1397 IOInit(d1, OWNER_SDCARD, RESOURCE_NONE, 0);
1398 IOConfigGPIOAF(d1, SDIO_DATA, GPIO_AF_SDIO);
1400 IOInit(d2, OWNER_SDCARD, RESOURCE_NONE, 0);
1401 IOConfigGPIOAF(d2, SDIO_DATA, GPIO_AF_SDIO);
1403 IOInit(d3, OWNER_SDCARD, RESOURCE_NONE, 0);
1404 IOConfigGPIOAF(d3, SDIO_DATA, GPIO_AF_SDIO);
1405 #endif
1407 IOInit(clk, OWNER_SDCARD, RESOURCE_NONE, 0);
1408 IOConfigGPIOAF(clk, SDIO_CLK, GPIO_AF_SDIO);
1410 IOInit(cmd, OWNER_SDCARD, RESOURCE_NONE, 0);
1411 IOConfigGPIOAF(cmd, SDIO_CMD, GPIO_AF_SDIO);
1413 // NVIC configuration for SDIO interrupts
1414 NVIC_SetPriority(SDIO_IRQn, NVIC_PRIO_SDIO);
1415 NVIC_EnableIRQ(SDIO_IRQn);
1417 dma_stream = dmaRef;
1418 RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
1419 if ((uint32_t)dma_stream == (uint32_t)DMA2_Stream3) {
1420 // Initialize DMA2 channel 3
1421 DMA2_Stream3->CR = 0; // Reset DMA Stream control register
1422 DMA2_Stream3->PAR = (uint32_t)&SDIO->FIFO;
1423 DMA2->LIFCR = IFCR_CLEAR_MASK_STREAM3; // Clear all interrupt flags
1424 DMA2_Stream3->CR = (DMA_CHANNEL_4 | DMA_SxCR_PFCTRL | // Prepare the DMA Stream configuration
1425 DMA_MINC_ENABLE | DMA_PDATAALIGN_WORD | // And write to DMA Stream CR register
1426 DMA_MDATAALIGN_WORD | DMA_PRIORITY_VERY_HIGH |
1427 DMA_MBURST_INC4 | DMA_PBURST_INC4 |
1428 DMA_MEMORY_TO_PERIPH);
1429 DMA2_Stream3->FCR = (DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); // Configuration FIFO control register
1430 dmaInit(dmaGetByRef(DMA2_Stream3), OWNER_SDCARD, 0);
1431 dmaSetHandler(dmaGetByRef(DMA2_Stream3), SDIO_DMA_ST3_IRQHandler, 1, 0);
1432 } else {
1433 // Initialize DMA2 channel 6
1434 DMA2_Stream6->CR = 0; // Reset DMA Stream control register
1435 DMA2_Stream6->PAR = (uint32_t)&SDIO->FIFO;
1436 DMA2->HIFCR = IFCR_CLEAR_MASK_STREAM6; // Clear all interrupt flags
1437 DMA2_Stream6->CR = (DMA_CHANNEL_4 | DMA_SxCR_PFCTRL | // Prepare the DMA Stream configuration
1438 DMA_MINC_ENABLE | DMA_PDATAALIGN_WORD | // And write to DMA Stream CR register
1439 DMA_MDATAALIGN_WORD | DMA_PRIORITY_VERY_HIGH |
1440 DMA_MBURST_INC4 | DMA_PBURST_INC4 |
1441 DMA_MEMORY_TO_PERIPH);
1442 DMA2_Stream6->FCR = (DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); // Configuration FIFO control register
1443 dmaInit(dmaGetByRef(DMA2_Stream6), OWNER_SDCARD, 0);
1444 dmaSetHandler(dmaGetByRef(DMA2_Stream6), SDIO_DMA_ST6_IRQHandler, 1, 0);
1447 return true;
1451 /** -----------------------------------------------------------------------------------------------------------------*/
1452 bool SD_GetState(void)
1454 // Check SDCARD status
1455 if (SD_GetStatus() == SD_OK) return true;
1456 return false;
1460 /** -----------------------------------------------------------------------------------------------------------------*/
1461 bool SD_Init(void)
1463 SD_Error_t ErrorState;
1465 // Initialize SDIO peripheral interface with default configuration for SD card initialization
1466 MODIFY_REG(SDIO->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) SDIO_INIT_CLK_DIV);
1468 // Identify card operating voltage
1469 if ((ErrorState = SD_PowerON()) == SD_OK) {
1470 // Initialize the present card and put them in idle state
1471 if ((ErrorState = SD_InitializeCard()) == SD_OK) {
1472 // Read CSD/CID MSD registers
1473 if ((ErrorState = SD_GetCardInfo()) == SD_OK) {
1474 // Select the Card - Send CMD7 SDMMC_SEL_DESEL_CARD
1475 ErrorState = SD_TransmitCommand((SD_CMD_SEL_DESEL_CARD | SD_CMD_RESPONSE_SHORT), SD_CardRCA, 1);
1476 MODIFY_REG(SDIO->CLKCR, CLKCR_CLEAR_MASK, (uint32_t) SDIO_CLK_DIV); // Configure SDIO peripheral interface
1481 // Configure SD Bus width
1482 if (ErrorState == SD_OK) {
1483 // Enable wide operation
1484 #ifdef SDCARD_SDIO_4BIT
1485 ErrorState = SD_WideBusOperationConfig(SD_BUS_WIDE_4B);
1486 #else
1487 ErrorState = SD_WideBusOperationConfig(SD_BUS_WIDE_1B);
1488 #endif
1491 if (ErrorState == SD_OK && sdioConfig()->clockBypass) {
1492 if (SD_HighSpeed()) {
1493 SDIO->CLKCR |= SDIO_CLKCR_BYPASS;
1494 SDIO->CLKCR |= SDIO_CLKCR_NEGEDGE;
1500 // Configure the SDCARD device
1501 return ErrorState;
1504 /** -----------------------------------------------------------------------------------------------------------------*/
1506 * @brief This function handles SD card interrupt request.
1508 void SDIO_IRQHandler(void)
1510 // Check for SDIO interrupt flags
1511 if ((SDIO->STA & SDIO_STA_DATAEND) != 0) {
1512 SDIO->ICR = SDIO_ICR_DATAENDC;
1513 SDIO->ICR = SDIO_ICR_STATIC_FLAGS;
1514 SDIO->MASK &= ~(SDIO_MASK_DATAENDIE | SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
1515 SDIO_MASK_TXUNDERRIE | SDIO_MASK_RXOVERRIE | SDIO_MASK_TXFIFOHEIE | SDIO_MASK_RXFIFOHFIE);
1517 /* Currently doesn't implement multiple block write handling */
1518 if ((SD_Handle.Operation & 0x02) == (SDIO_DIR_TX << 1)) {
1519 /* Disable the stream */
1520 dma_stream->CR &= ~DMA_SxCR_EN;
1521 SDIO->DCTRL &= ~(SDIO_DCTRL_DMAEN);
1522 /* Transfer is complete */
1523 SD_Handle.TXCplt = 0;
1524 if ((SD_Handle.Operation & 0x01) == SD_MULTIPLE_BLOCK) {
1525 /* Send stop command in multiblock write */
1526 SD_TransmitCommand((SD_CMD_STOP_TRANSMISSION | SD_CMD_RESPONSE_SHORT), 0, 1);
1529 SD_Handle.TransferComplete = 1;
1530 SD_Handle.TransferError = SD_OK; // No transfer error
1532 else if ((SDIO->STA & SDIO_STA_DCRCFAIL) != 0) {
1533 SD_Handle.TransferError = SD_DATA_CRC_FAIL;
1535 else if ((SDIO->STA & SDIO_STA_DTIMEOUT) != 0) {
1536 SD_Handle.TransferError = SD_DATA_TIMEOUT;
1538 else if ((SDIO->STA & SDIO_STA_RXOVERR) != 0) {
1539 SD_Handle.TransferError = SD_RX_OVERRUN;
1541 else if ((SDIO->STA & SDIO_STA_TXUNDERR) != 0) {
1542 SD_Handle.TransferError = SD_TX_UNDERRUN;
1545 SDIO->ICR = SDIO_ICR_STATIC_FLAGS;
1547 // Disable all SDIO peripheral interrupt sources
1548 SDIO->MASK &= ~(SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | SDIO_MASK_DATAENDIE |
1549 SDIO_MASK_TXFIFOHEIE | SDIO_MASK_RXFIFOHFIE | SDIO_MASK_TXUNDERRIE |
1550 SDIO_MASK_RXOVERRIE);
1553 /** -----------------------------------------------------------------------------------------------------------------*/
1555 * @brief This function handles DMA2 Stream 3 interrupt request.
1557 void SDIO_DMA_ST3_IRQHandler(dmaChannelDescriptor_t *dma)
1559 UNUSED(dma);
1560 // Transfer Error Interrupt management
1561 if ((DMA2->LISR & DMA_LISR_TEIF3) != 0) {
1562 if ((DMA2_Stream3->CR & DMA_SxCR_TEIE) != 0) {
1563 DMA2_Stream3->CR &= ~DMA_SxCR_TEIE; // Disable the transfer error interrupt
1564 DMA2->LIFCR = DMA_LIFCR_CTEIF3; // Clear the transfer error flag
1568 // FIFO Error Interrupt management
1569 if ((DMA2->LISR & DMA_LISR_FEIF3) != 0) {
1570 if ((DMA2_Stream3->FCR & DMA_SxFCR_FEIE) != 0) {
1571 DMA2_Stream3->FCR &= ~DMA_SxFCR_FEIE; // Disable the FIFO Error interrupt
1572 DMA2->LIFCR = DMA_LIFCR_CFEIF3; // Clear the FIFO error flag
1576 // Direct Mode Error Interrupt management
1577 if ((DMA2->LISR & DMA_LISR_DMEIF3) != 0) {
1578 if ((DMA2_Stream3->CR & DMA_SxCR_DMEIE) != 0) {
1579 DMA2_Stream3->CR &= ~DMA_SxCR_DMEIE; // Disable the direct mode Error interrupt
1580 DMA2->LIFCR = DMA_LIFCR_CDMEIF3; // Clear the FIFO error flag
1584 // Half Transfer Complete Interrupt management
1585 if ((DMA2->LISR & DMA_LISR_HTIF3) != 0) {
1586 if ((DMA2_Stream3->CR & DMA_SxCR_HTIE) != 0) {
1587 if (((DMA2_Stream3->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0) { // Multi_Buffering mode enabled
1588 DMA2->LIFCR = DMA_LIFCR_CHTIF3; // Clear the half transfer complete flag
1590 else {
1591 if ((DMA2_Stream3->CR & DMA_SxCR_CIRC) == 0) { // Disable the half transfer interrupt if the DMA mode is not CIRCULAR
1592 DMA2_Stream3->CR &= ~DMA_SxCR_HTIE; // Disable the half transfer interrupt
1595 DMA2->LIFCR = DMA_LIFCR_CHTIF3; // Clear the half transfer complete flag
1600 // Transfer Complete Interrupt management
1601 if ((DMA2->LISR & DMA_LISR_TCIF3) != 0) {
1602 if ((DMA2_Stream3->CR & DMA_SxCR_TCIE) != 0) {
1603 if ((DMA2_Stream3->CR & (uint32_t)(DMA_SxCR_DBM)) != 0) {
1604 DMA2->LIFCR = DMA_LIFCR_CTCIF3; // Clear the transfer complete flag
1606 else {
1607 if ((DMA2_Stream3->CR & DMA_SxCR_CIRC) == 0) {
1608 DMA2_Stream3->CR &= ~DMA_SxCR_TCIE; // Disable the transfer complete interrupt
1611 DMA2->LIFCR = DMA_LIFCR_CTCIF3; // Clear the transfer complete flag
1612 SD_DMA_Complete(DMA2_Stream3);
1619 /** -----------------------------------------------------------------------------------------------------------------*/
1621 * @brief This function handles DMA2 Stream 6 interrupt request.
1623 void SDIO_DMA_ST6_IRQHandler(dmaChannelDescriptor_t *dma)
1625 UNUSED(dma);
1626 // Transfer Error Interrupt management
1627 if ((DMA2->HISR & DMA_HISR_TEIF6) != 0) {
1628 if ((DMA2_Stream6->CR & DMA_SxCR_TEIE) != 0) {
1629 DMA2_Stream6->CR &= ~DMA_SxCR_TEIE; // Disable the transfer error interrupt
1630 DMA2->HIFCR = DMA_HIFCR_CTEIF6; // Clear the transfer error flag
1634 // FIFO Error Interrupt management
1635 if ((DMA2->HISR & DMA_HISR_FEIF6) != 0) {
1636 if ((DMA2_Stream6->FCR & DMA_SxFCR_FEIE) != 0) {
1637 DMA2_Stream6->FCR &= ~DMA_SxFCR_FEIE; // Disable the FIFO Error interrupt
1638 DMA2->HIFCR = DMA_HIFCR_CFEIF6; // Clear the FIFO error flag
1642 // Direct Mode Error Interrupt management
1643 if ((DMA2->HISR & DMA_HISR_DMEIF6) != 0) {
1644 if ((DMA2_Stream6->CR & DMA_SxCR_DMEIE) != 0) {
1645 DMA2_Stream6->CR &= ~DMA_SxCR_DMEIE; // Disable the direct mode Error interrupt
1646 DMA2->HIFCR = DMA_HIFCR_CDMEIF6; // Clear the FIFO error flag
1650 // Half Transfer Complete Interrupt management
1651 if ((DMA2->HISR & DMA_HISR_HTIF6) != 0) {
1652 if ((DMA2_Stream6->CR & DMA_SxCR_HTIE) != 0) {
1653 if (((DMA2_Stream6->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0) { // Multi_Buffering mode enabled
1654 DMA2->HIFCR = DMA_HIFCR_CHTIF6; // Clear the half transfer complete flag
1656 else {
1657 if ((DMA2_Stream6->CR & DMA_SxCR_CIRC) == 0) { // Disable the half transfer interrupt if the DMA mode is not CIRCULAR
1658 DMA2_Stream6->CR &= ~DMA_SxCR_HTIE; // Disable the half transfer interrupt
1661 DMA2->HIFCR = DMA_HIFCR_CHTIF6; // Clear the half transfer complete flag
1666 // Transfer Complete Interrupt management
1667 if ((DMA2->HISR & DMA_HISR_TCIF6) != 0) {
1668 if ((DMA2_Stream6->CR & DMA_SxCR_TCIE) != 0) {
1669 if ((DMA2_Stream6->CR & (uint32_t)(DMA_SxCR_DBM)) != 0) {
1670 DMA2->HIFCR = DMA_HIFCR_CTCIF6; // Clear the transfer complete flag
1672 else {
1673 if ((DMA2_Stream6->CR & DMA_SxCR_CIRC) == 0) {
1674 DMA2_Stream6->CR &= ~DMA_SxCR_TCIE; // Disable the transfer complete interrupt
1677 DMA2->HIFCR = DMA_HIFCR_CTCIF6; // Clear the transfer complete flag
1678 SD_DMA_Complete(DMA2_Stream6);
1684 /* ------------------------------------------------------------------------------------------------------------------*/
1685 #endif