2 ******************************************************************************
3 * @file stm32f1xx_ll_sdmmc.c
4 * @author MCD Application Team
7 * @brief SDIO Low Layer HAL module driver.
9 * This file provides firmware functions to manage the following
10 * functionalities of the SDIO peripheral:
11 * + Initialization/de-initialization functions
12 * + I/O operation functions
13 * + Peripheral Control functions
14 * + Peripheral State functions
17 ==============================================================================
18 ##### SDMMC peripheral features #####
19 ==============================================================================
20 [..] The SD/SDMMC MMC card host interface (SDMMC) provides an interface between the APB2
21 peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDMMC cards and CE-ATA
24 [..] The SDMMC features include the following:
25 (+) Full compliance with MultiMedia Card System Specification Version 4.2. Card support
26 for three different databus modes: 1-bit (default), 4-bit and 8-bit
27 (+) Full compatibility with previous versions of MultiMedia Cards (forward compatibility)
28 (+) Full compliance with SD Memory Card Specifications Version 2.0
29 (+) Full compliance with SD I/O Card Specification Version 2.0: card support for two
30 different data bus modes: 1-bit (default) and 4-bit
31 (+) Full support of the CE-ATA features (full compliance with CE-ATA digital protocol
33 (+) Data transfer up to 48 MHz for the 8 bit mode
34 (+) Data and command output enable signals to control external bidirectional drivers.
37 ##### How to use this driver #####
38 ==============================================================================
40 This driver is a considered as a driver of service for external devices drivers
41 that interfaces with the SDMMC peripheral.
42 According to the device used (SD card/ MMC card / SDMMC card ...), a set of APIs
43 is used in the device's driver to perform SDMMC operations and functionalities.
45 This driver is almost transparent for the final user, it is only used to implement other
46 functionalities of the external device.
49 (+) The SDIO peripheral uses two clock signals:
50 (++) SDIO adapter clock (SDIOCLK = HCLK)
51 (++) AHB bus clock (HCLK/2)
53 -@@- PCLK2 and SDMMC_CK clock frequencies must respect the following condition:
54 Frequency(PCLK2) >= (3 / 8 x Frequency(SDMMC_CK))
56 (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDMMC
59 (+) Enable the Power ON State using the SDIO_PowerState_ON(SDIOx)
60 function and disable it using the function SDIO_PowerState_OFF(SDIOx).
62 (+) Enable/Disable the clock using the __SDIO_ENABLE()/__SDIO_DISABLE() macros.
64 (+) Enable/Disable the peripheral interrupts using the macros __SDIO_ENABLE_IT(hsdio, IT)
65 and __SDIO_DISABLE_IT(hsdio, IT) if you need to use interrupt mode.
67 (+) When using the DMA mode
68 (++) Configure the DMA in the MSP layer of the external device
69 (++) Active the needed channel Request
70 (++) Enable the DMA using __SDIO_DMA_ENABLE() macro or Disable it using the macro
73 (+) To control the CPSM (Command Path State Machine) and send
74 commands to the card use the SDIO_SendCommand(),
75 SDIO_GetCommandResponse() and SDIO_GetResponse() functions. First, user has
76 to fill the command structure (pointer to SDIO_CmdInitTypeDef) according
77 to the selected command to be sent.
78 The parameters that should be filled are:
81 (++) Command Response type
83 (++) CPSM Status (Enable or Disable).
85 -@@- To check if the command is well received, read the SDIO_CMDRESP
86 register using the SDIO_GetCommandResponse().
87 The SDMMC responses registers (SDIO_RESP1 to SDIO_RESP2), use the
88 SDIO_GetResponse() function.
90 (+) To control the DPSM (Data Path State Machine) and send/receive
91 data to/from the card use the SDIO_ConfigData(), SDIO_GetDataCounter(),
92 SDIO_ReadFIFO(), SDIO_WriteFIFO() and SDIO_GetFIFOCount() functions.
94 *** Read Operations ***
95 =======================
97 (#) First, user has to fill the data structure (pointer to
98 SDIO_DataInitTypeDef) according to the selected data type to be received.
99 The parameters that should be filled are:
103 (++) Data Transfer direction: should be from card (To SDMMC)
104 (++) Data Transfer mode
105 (++) DPSM Status (Enable or Disable)
107 (#) Configure the SDMMC resources to receive the data from the card
108 according to selected transfer mode (Refer to Step 8, 9 and 10).
110 (#) Send the selected Read command (refer to step 11).
112 (#) Use the SDIO flags/interrupts to check the transfer status.
114 *** Write Operations ***
115 ========================
117 (#) First, user has to fill the data structure (pointer to
118 SDIO_DataInitTypeDef) according to the selected data type to be received.
119 The parameters that should be filled are:
123 (++) Data Transfer direction: should be to card (To CARD)
124 (++) Data Transfer mode
125 (++) DPSM Status (Enable or Disable)
127 (#) Configure the SDMMC resources to send the data to the card according to
128 selected transfer mode.
130 (#) Send the selected Write command.
132 (#) Use the SDIO flags/interrupts to check the transfer status.
134 *** Command management operations ***
135 =====================================
137 (#) The commands used for Read/Write//Erase operations are managed in
139 Each function allows to send the needed command with the related argument,
140 then check the response.
141 By the same approach, you could implement a command and check the response.
144 ******************************************************************************
147 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
149 * Redistribution and use in source and binary forms, with or without modification,
150 * are permitted provided that the following conditions are met:
151 * 1. Redistributions of source code must retain the above copyright notice,
152 * this list of conditions and the following disclaimer.
153 * 2. Redistributions in binary form must reproduce the above copyright notice,
154 * this list of conditions and the following disclaimer in the documentation
155 * and/or other materials provided with the distribution.
156 * 3. Neither the name of STMicroelectronics nor the names of its contributors
157 * may be used to endorse or promote products derived from this software
158 * without specific prior written permission.
160 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
161 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
162 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
163 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
164 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
165 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
166 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
167 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
168 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
169 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
171 ******************************************************************************
174 /* Includes ------------------------------------------------------------------*/
175 #include "stm32f1xx_hal.h"
178 #if defined(STM32F103xE) || defined(STM32F103xG)
180 /** @addtogroup STM32F1xx_HAL_Driver
184 /** @defgroup SDMMC_LL SDMMC Low Layer
185 * @brief Low layer module for SD
188 #if defined (HAL_SD_MODULE_ENABLED) || defined(HAL_MMC_MODULE_ENABLED)
190 /* Private typedef -----------------------------------------------------------*/
191 /* Private define ------------------------------------------------------------*/
192 /* Private macro -------------------------------------------------------------*/
193 /* Private variables ---------------------------------------------------------*/
194 /* Private function prototypes -----------------------------------------------*/
195 static uint32_t SDMMC_GetCmdError(SDIO_TypeDef
*SDIOx
);
196 static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef
*SDIOx
, uint8_t SD_CMD
, uint32_t Timeout
);
197 static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef
*SDIOx
);
198 static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef
*SDIOx
);
199 static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef
*SDIOx
);
200 static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef
*SDIOx
, uint8_t SD_CMD
, uint16_t *pRCA
);
202 /* Exported functions --------------------------------------------------------*/
204 /** @defgroup SDMMC_LL_Exported_Functions SDMMC Low Layer Exported Functions
208 /** @defgroup HAL_SDMMC_LL_Group1 Initialization de-initialization functions
209 * @brief Initialization and Configuration functions
212 ===============================================================================
213 ##### Initialization/de-initialization functions #####
214 ===============================================================================
215 [..] This section provides functions allowing to:
222 * @brief Initializes the SDMMC according to the specified
223 * parameters in the SDMMC_InitTypeDef and create the associated handle.
224 * @param SDIOx: Pointer to SDMMC register base
225 * @param Init: SDMMC initialization structure
228 HAL_StatusTypeDef
SDIO_Init(SDIO_TypeDef
*SDIOx
, SDIO_InitTypeDef Init
)
230 uint32_t tmpreg
= 0U;
232 /* Check the parameters */
233 assert_param(IS_SDIO_ALL_INSTANCE(SDIOx
));
234 assert_param(IS_SDIO_CLOCK_EDGE(Init
.ClockEdge
));
235 assert_param(IS_SDIO_CLOCK_BYPASS(Init
.ClockBypass
));
236 assert_param(IS_SDIO_CLOCK_POWER_SAVE(Init
.ClockPowerSave
));
237 assert_param(IS_SDIO_BUS_WIDE(Init
.BusWide
));
238 assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(Init
.HardwareFlowControl
));
239 assert_param(IS_SDIO_CLKDIV(Init
.ClockDiv
));
241 /* Set SDMMC configuration parameters */
242 tmpreg
|= (Init
.ClockEdge
|\
244 Init
.ClockPowerSave
|\
246 Init
.HardwareFlowControl
|\
250 /* Write to SDMMC CLKCR */
251 MODIFY_REG(SDIOx
->CLKCR
, CLKCR_CLEAR_MASK
, tmpreg
);
261 /** @defgroup HAL_SDMMC_LL_Group2 IO operation functions
262 * @brief Data transfers functions
265 ===============================================================================
266 ##### I/O operation functions #####
267 ===============================================================================
269 This subsection provides a set of functions allowing to manage the SDMMC data
277 * @brief Read data (word) from Rx FIFO in blocking mode (polling)
278 * @param SDIOx: Pointer to SDMMC register base
281 uint32_t SDIO_ReadFIFO(SDIO_TypeDef
*SDIOx
)
283 /* Read data from Rx FIFO */
284 return (SDIOx
->FIFO
);
288 * @brief Write data (word) to Tx FIFO in blocking mode (polling)
289 * @param SDIOx: Pointer to SDMMC register base
290 * @param pWriteData: pointer to data to write
293 HAL_StatusTypeDef
SDIO_WriteFIFO(SDIO_TypeDef
*SDIOx
, uint32_t *pWriteData
)
295 /* Write data to FIFO */
296 SDIOx
->FIFO
= *pWriteData
;
305 /** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions
306 * @brief management functions
309 ===============================================================================
310 ##### Peripheral Control functions #####
311 ===============================================================================
313 This subsection provides a set of functions allowing to control the SDMMC data
321 * @brief Set SDMMC Power state to ON.
322 * @param SDIOx: Pointer to SDMMC register base
325 HAL_StatusTypeDef
SDIO_PowerState_ON(SDIO_TypeDef
*SDIOx
)
327 /* Set power state to ON */
328 SDIOx
->POWER
= SDIO_POWER_PWRCTRL
;
334 * @brief Set SDMMC Power state to OFF.
335 * @param SDIOx: Pointer to SDMMC register base
338 HAL_StatusTypeDef
SDIO_PowerState_OFF(SDIO_TypeDef
*SDIOx
)
340 /* Set power state to OFF */
341 SDIOx
->POWER
= 0x00000000U
;
347 * @brief Get SDMMC Power state.
348 * @param SDIOx: Pointer to SDMMC register base
349 * @retval Power status of the controller. The returned value can be one of the
355 uint32_t SDIO_GetPowerState(SDIO_TypeDef
*SDIOx
)
357 return (SDIOx
->POWER
& SDIO_POWER_PWRCTRL
);
361 * @brief Configure the SDMMC command path according to the specified parameters in
362 * SDIO_CmdInitTypeDef structure and send the command
363 * @param SDIOx: Pointer to SDMMC register base
364 * @param Command: pointer to a SDIO_CmdInitTypeDef structure that contains
365 * the configuration information for the SDMMC command
368 HAL_StatusTypeDef
SDIO_SendCommand(SDIO_TypeDef
*SDIOx
, SDIO_CmdInitTypeDef
*Command
)
370 uint32_t tmpreg
= 0U;
372 /* Check the parameters */
373 assert_param(IS_SDIO_CMD_INDEX(Command
->CmdIndex
));
374 assert_param(IS_SDIO_RESPONSE(Command
->Response
));
375 assert_param(IS_SDIO_WAIT(Command
->WaitForInterrupt
));
376 assert_param(IS_SDIO_CPSM(Command
->CPSM
));
378 /* Set the SDMMC Argument value */
379 SDIOx
->ARG
= Command
->Argument
;
381 /* Set SDMMC command parameters */
382 tmpreg
|= (uint32_t)(Command
->CmdIndex
|\
384 Command
->WaitForInterrupt
|\
387 /* Write to SDMMC CMD register */
388 MODIFY_REG(SDIOx
->CMD
, CMD_CLEAR_MASK
, tmpreg
);
394 * @brief Return the command index of last command for which response received
395 * @param SDIOx: Pointer to SDMMC register base
396 * @retval Command index of the last command response received
398 uint8_t SDIO_GetCommandResponse(SDIO_TypeDef
*SDIOx
)
400 return (uint8_t)(SDIOx
->RESPCMD
);
405 * @brief Return the response received from the card for the last command
406 * @param SDIOx: Pointer to SDMMC register base
407 * @param Response: Specifies the SDMMC response register.
408 * This parameter can be one of the following values:
409 * @arg SDIO_RESP1: Response Register 1
410 * @arg SDIO_RESP2: Response Register 2
411 * @arg SDIO_RESP3: Response Register 3
412 * @arg SDIO_RESP4: Response Register 4
413 * @retval The Corresponding response register value
415 uint32_t SDIO_GetResponse(SDIO_TypeDef
*SDIOx
, uint32_t Response
)
417 __IO
uint32_t tmp
= 0U;
419 /* Check the parameters */
420 assert_param(IS_SDIO_RESP(Response
));
422 /* Get the response */
423 tmp
= (uint32_t)&(SDIOx
->RESP1
) + Response
;
425 return (*(__IO
uint32_t *) tmp
);
429 * @brief Configure the SDMMC data path according to the specified
430 * parameters in the SDIO_DataInitTypeDef.
431 * @param SDIOx: Pointer to SDMMC register base
432 * @param Data : pointer to a SDIO_DataInitTypeDef structure
433 * that contains the configuration information for the SDMMC data.
436 HAL_StatusTypeDef
SDIO_ConfigData(SDIO_TypeDef
*SDIOx
, SDIO_DataInitTypeDef
* Data
)
438 uint32_t tmpreg
= 0U;
440 /* Check the parameters */
441 assert_param(IS_SDIO_DATA_LENGTH(Data
->DataLength
));
442 assert_param(IS_SDIO_BLOCK_SIZE(Data
->DataBlockSize
));
443 assert_param(IS_SDIO_TRANSFER_DIR(Data
->TransferDir
));
444 assert_param(IS_SDIO_TRANSFER_MODE(Data
->TransferMode
));
445 assert_param(IS_SDIO_DPSM(Data
->DPSM
));
447 /* Set the SDMMC Data TimeOut value */
448 SDIOx
->DTIMER
= Data
->DataTimeOut
;
450 /* Set the SDMMC DataLength value */
451 SDIOx
->DLEN
= Data
->DataLength
;
453 /* Set the SDMMC data configuration parameters */
454 tmpreg
|= (uint32_t)(Data
->DataBlockSize
|\
456 Data
->TransferMode
|\
459 /* Write to SDMMC DCTRL */
460 MODIFY_REG(SDIOx
->DCTRL
, DCTRL_CLEAR_MASK
, tmpreg
);
467 * @brief Returns number of remaining data bytes to be transferred.
468 * @param SDIOx: Pointer to SDMMC register base
469 * @retval Number of remaining data bytes to be transferred
471 uint32_t SDIO_GetDataCounter(SDIO_TypeDef
*SDIOx
)
473 return (SDIOx
->DCOUNT
);
477 * @brief Get the FIFO data
478 * @param SDIOx: Pointer to SDMMC register base
479 * @retval Data received
481 uint32_t SDIO_GetFIFOCount(SDIO_TypeDef
*SDIOx
)
483 return (SDIOx
->FIFO
);
487 * @brief Sets one of the two options of inserting read wait interval.
488 * @param SDIOx: Pointer to SDMMC register base
489 * @param SDIO_ReadWaitMode: SDMMC Read Wait operation mode.
490 * This parameter can be:
491 * @arg SDIO_READ_WAIT_MODE_CLK: Read Wait control by stopping SDMMCCLK
492 * @arg SDIO_READ_WAIT_MODE_DATA2: Read Wait control using SDMMC_DATA2
495 HAL_StatusTypeDef
SDIO_SetSDMMCReadWaitMode(SDIO_TypeDef
*SDIOx
, uint32_t SDIO_ReadWaitMode
)
497 /* Check the parameters */
498 assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode
));
500 /* Set SDMMC read wait mode */
501 MODIFY_REG(SDIOx
->DCTRL
, SDIO_DCTRL_RWMOD
, SDIO_ReadWaitMode
);
511 /** @defgroup HAL_SDMMC_LL_Group4 Command management functions
512 * @brief Data transfers functions
515 ===============================================================================
516 ##### Commands management functions #####
517 ===============================================================================
519 This subsection provides a set of functions allowing to manage the needed commands.
526 * @brief Send the Data Block Lenght command and check the response
527 * @param SDIOx: Pointer to SDMMC register base
530 uint32_t SDMMC_CmdBlockLength(SDIO_TypeDef
*SDIOx
, uint32_t BlockSize
)
532 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
533 uint32_t errorstate
= SDMMC_ERROR_NONE
;
535 /* Set Block Size for Card */
536 sdmmc_cmdinit
.Argument
= (uint32_t)BlockSize
;
537 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SET_BLOCKLEN
;
538 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
539 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
540 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
541 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
543 /* Check for error conditions */
544 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_SET_BLOCKLEN
, SDIO_CMDTIMEOUT
);
550 * @brief Send the Read Single Block command and check the response
551 * @param SDIOx: Pointer to SDMMC register base
554 uint32_t SDMMC_CmdReadSingleBlock(SDIO_TypeDef
*SDIOx
, uint32_t ReadAdd
)
556 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
557 uint32_t errorstate
= SDMMC_ERROR_NONE
;
559 /* Set Block Size for Card */
560 sdmmc_cmdinit
.Argument
= (uint32_t)ReadAdd
;
561 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_READ_SINGLE_BLOCK
;
562 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
563 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
564 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
565 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
567 /* Check for error conditions */
568 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_READ_SINGLE_BLOCK
, SDIO_CMDTIMEOUT
);
574 * @brief Send the Read Multi Block command and check the response
575 * @param SDIOx: Pointer to SDIO register base
578 uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef
*SDIOx
, uint32_t ReadAdd
)
580 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
581 uint32_t errorstate
= SDMMC_ERROR_NONE
;
583 /* Set Block Size for Card */
584 sdmmc_cmdinit
.Argument
= (uint32_t)ReadAdd
;
585 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_READ_MULT_BLOCK
;
586 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
587 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
588 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
589 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
591 /* Check for error conditions */
592 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_READ_MULT_BLOCK
, SDIO_CMDTIMEOUT
);
598 * @brief Send the Write Single Block command and check the response
599 * @param SDIOx: Pointer to SDIO register base
602 uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef
*SDIOx
, uint32_t WriteAdd
)
604 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
605 uint32_t errorstate
= SDMMC_ERROR_NONE
;
607 /* Set Block Size for Card */
608 sdmmc_cmdinit
.Argument
= (uint32_t)WriteAdd
;
609 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_WRITE_SINGLE_BLOCK
;
610 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
611 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
612 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
613 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
615 /* Check for error conditions */
616 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_WRITE_SINGLE_BLOCK
, SDIO_CMDTIMEOUT
);
622 * @brief Send the Write Multi Block command and check the response
623 * @param SDIOx: Pointer to SDIO register base
626 uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef
*SDIOx
, uint32_t WriteAdd
)
628 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
629 uint32_t errorstate
= SDMMC_ERROR_NONE
;
631 /* Set Block Size for Card */
632 sdmmc_cmdinit
.Argument
= (uint32_t)WriteAdd
;
633 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_WRITE_MULT_BLOCK
;
634 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
635 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
636 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
637 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
639 /* Check for error conditions */
640 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_WRITE_MULT_BLOCK
, SDIO_CMDTIMEOUT
);
646 * @brief Send the Start Address Erase command for SD and check the response
647 * @param SDIOx: Pointer to SDIO register base
650 uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef
*SDIOx
, uint32_t StartAdd
)
652 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
653 uint32_t errorstate
= SDMMC_ERROR_NONE
;
655 /* Set Block Size for Card */
656 sdmmc_cmdinit
.Argument
= (uint32_t)StartAdd
;
657 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SD_ERASE_GRP_START
;
658 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
659 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
660 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
661 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
663 /* Check for error conditions */
664 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_SD_ERASE_GRP_START
, SDIO_CMDTIMEOUT
);
670 * @brief Send the End Address Erase command for SD and check the response
671 * @param SDIOx: Pointer to SDIO register base
674 uint32_t SDMMC_CmdSDEraseEndAdd(SDIO_TypeDef
*SDIOx
, uint32_t EndAdd
)
676 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
677 uint32_t errorstate
= SDMMC_ERROR_NONE
;
679 /* Set Block Size for Card */
680 sdmmc_cmdinit
.Argument
= (uint32_t)EndAdd
;
681 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SD_ERASE_GRP_END
;
682 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
683 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
684 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
685 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
687 /* Check for error conditions */
688 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_SD_ERASE_GRP_END
, SDIO_CMDTIMEOUT
);
694 * @brief Send the Start Address Erase command and check the response
695 * @param SDIOx: Pointer to SDIO register base
698 uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef
*SDIOx
, uint32_t StartAdd
)
700 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
701 uint32_t errorstate
= SDMMC_ERROR_NONE
;
703 /* Set Block Size for Card */
704 sdmmc_cmdinit
.Argument
= (uint32_t)StartAdd
;
705 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_ERASE_GRP_START
;
706 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
707 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
708 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
709 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
711 /* Check for error conditions */
712 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_ERASE_GRP_START
, SDIO_CMDTIMEOUT
);
718 * @brief Send the End Address Erase command and check the response
719 * @param SDIOx: Pointer to SDIO register base
722 uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef
*SDIOx
, uint32_t EndAdd
)
724 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
725 uint32_t errorstate
= SDMMC_ERROR_NONE
;
727 /* Set Block Size for Card */
728 sdmmc_cmdinit
.Argument
= (uint32_t)EndAdd
;
729 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_ERASE_GRP_END
;
730 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
731 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
732 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
733 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
735 /* Check for error conditions */
736 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_ERASE_GRP_END
, SDIO_CMDTIMEOUT
);
742 * @brief Send the Erase command and check the response
743 * @param SDIOx: Pointer to SDIO register base
746 uint32_t SDMMC_CmdErase(SDIO_TypeDef
*SDIOx
)
748 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
749 uint32_t errorstate
= SDMMC_ERROR_NONE
;
751 /* Set Block Size for Card */
752 sdmmc_cmdinit
.Argument
= 0U;
753 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_ERASE
;
754 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
755 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
756 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
757 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
759 /* Check for error conditions */
760 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_ERASE
, SDIO_MAXERASETIMEOUT
);
766 * @brief Send the Stop Transfer command and check the response.
767 * @param SDIOx: Pointer to SDIO register base
770 uint32_t SDMMC_CmdStopTransfer(SDIO_TypeDef
*SDIOx
)
772 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
773 uint32_t errorstate
= SDMMC_ERROR_NONE
;
775 /* Send CMD12 STOP_TRANSMISSION */
776 sdmmc_cmdinit
.Argument
= 0U;
777 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_STOP_TRANSMISSION
;
778 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
779 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
780 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
781 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
783 /* Check for error conditions */
784 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_STOP_TRANSMISSION
, 100000000U);
790 * @brief Send the Select Deselect command and check the response.
791 * @param SDIOx: Pointer to SDIO register base
792 * @param addr: Address of the card to be selected
795 uint32_t SDMMC_CmdSelDesel(SDIO_TypeDef
*SDIOx
, uint64_t Addr
)
797 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
798 uint32_t errorstate
= SDMMC_ERROR_NONE
;
800 /* Send CMD7 SDMMC_SEL_DESEL_CARD */
801 sdmmc_cmdinit
.Argument
= (uint32_t)Addr
;
802 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SEL_DESEL_CARD
;
803 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
804 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
805 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
806 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
808 /* Check for error conditions */
809 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_SEL_DESEL_CARD
, SDIO_CMDTIMEOUT
);
815 * @brief Send the Go Idle State command and check the response.
816 * @param SDIOx: Pointer to SDIO register base
819 uint32_t SDMMC_CmdGoIdleState(SDIO_TypeDef
*SDIOx
)
821 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
822 uint32_t errorstate
= SDMMC_ERROR_NONE
;
824 sdmmc_cmdinit
.Argument
= 0U;
825 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_GO_IDLE_STATE
;
826 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_NO
;
827 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
828 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
829 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
831 /* Check for error conditions */
832 errorstate
= SDMMC_GetCmdError(SDIOx
);
838 * @brief Send the Operating Condition command and check the response.
839 * @param SDIOx: Pointer to SDIO register base
842 uint32_t SDMMC_CmdOperCond(SDIO_TypeDef
*SDIOx
)
844 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
845 uint32_t errorstate
= SDMMC_ERROR_NONE
;
847 /* Send CMD8 to verify SD card interface operating condition */
848 /* Argument: - [31:12]: Reserved (shall be set to '0')
849 - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
850 - [7:0]: Check Pattern (recommended 0xAA) */
851 /* CMD Response: R7 */
852 sdmmc_cmdinit
.Argument
= SDMMC_CHECK_PATTERN
;
853 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_HS_SEND_EXT_CSD
;
854 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
855 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
856 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
857 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
859 /* Check for error conditions */
860 errorstate
= SDMMC_GetCmdResp7(SDIOx
);
866 * @brief Send the Application command to verify that that the next command
867 * is an application specific com-mand rather than a standard command
868 * and check the response.
869 * @param SDIOx: Pointer to SDIO register base
872 uint32_t SDMMC_CmdAppCommand(SDIO_TypeDef
*SDIOx
, uint32_t Argument
)
874 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
875 uint32_t errorstate
= SDMMC_ERROR_NONE
;
877 sdmmc_cmdinit
.Argument
= (uint32_t)Argument
;
878 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_APP_CMD
;
879 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
880 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
881 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
882 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
884 /* Check for error conditions */
885 /* If there is a HAL_ERROR, it is a MMC card, else
886 it is a SD card: SD card 2.0 (voltage range mismatch)
888 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_APP_CMD
, SDIO_CMDTIMEOUT
);
894 * @brief Send the command asking the accessed card to send its operating
895 * condition register (OCR)
896 * @param SDIOx: Pointer to SDIO register base
899 uint32_t SDMMC_CmdAppOperCommand(SDIO_TypeDef
*SDIOx
, uint32_t SdType
)
901 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
902 uint32_t errorstate
= SDMMC_ERROR_NONE
;
904 sdmmc_cmdinit
.Argument
= SDMMC_VOLTAGE_WINDOW_SD
| SdType
;
905 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SD_APP_OP_COND
;
906 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
907 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
908 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
909 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
911 /* Check for error conditions */
912 errorstate
= SDMMC_GetCmdResp3(SDIOx
);
918 * @brief Send the Bus Width command and check the response.
919 * @param SDIOx: Pointer to SDIO register base
922 uint32_t SDMMC_CmdBusWidth(SDIO_TypeDef
*SDIOx
, uint32_t BusWidth
)
924 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
925 uint32_t errorstate
= SDMMC_ERROR_NONE
;
927 sdmmc_cmdinit
.Argument
= (uint32_t)BusWidth
;
928 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_APP_SD_SET_BUSWIDTH
;
929 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
930 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
931 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
932 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
934 /* Check for error conditions */
935 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_APP_SD_SET_BUSWIDTH
, SDIO_CMDTIMEOUT
);
941 * @brief Send the Send SCR command and check the response.
942 * @param SDIOx: Pointer to SDMMC register base
945 uint32_t SDMMC_CmdSendSCR(SDIO_TypeDef
*SDIOx
)
947 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
948 uint32_t errorstate
= SDMMC_ERROR_NONE
;
950 /* Send CMD51 SD_APP_SEND_SCR */
951 sdmmc_cmdinit
.Argument
= 0U;
952 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SD_APP_SEND_SCR
;
953 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
954 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
955 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
956 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
958 /* Check for error conditions */
959 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_SD_APP_SEND_SCR
, SDIO_CMDTIMEOUT
);
965 * @brief Send the Send CID command and check the response.
966 * @param SDIOx: Pointer to SDIO register base
969 uint32_t SDMMC_CmdSendCID(SDIO_TypeDef
*SDIOx
)
971 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
972 uint32_t errorstate
= SDMMC_ERROR_NONE
;
974 /* Send CMD2 ALL_SEND_CID */
975 sdmmc_cmdinit
.Argument
= 0U;
976 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_ALL_SEND_CID
;
977 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_LONG
;
978 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
979 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
980 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
982 /* Check for error conditions */
983 errorstate
= SDMMC_GetCmdResp2(SDIOx
);
989 * @brief Send the Send CSD command and check the response.
990 * @param SDIOx: Pointer to SDIO register base
993 uint32_t SDMMC_CmdSendCSD(SDIO_TypeDef
*SDIOx
, uint32_t Argument
)
995 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
996 uint32_t errorstate
= SDMMC_ERROR_NONE
;
998 /* Send CMD9 SEND_CSD */
999 sdmmc_cmdinit
.Argument
= (uint32_t)Argument
;
1000 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SEND_CSD
;
1001 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_LONG
;
1002 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
1003 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
1004 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
1006 /* Check for error conditions */
1007 errorstate
= SDMMC_GetCmdResp2(SDIOx
);
1013 * @brief Send the Send CSD command and check the response.
1014 * @param SDIOx: Pointer to SDIO register base
1015 * @retval HAL status
1017 uint32_t SDMMC_CmdSetRelAdd(SDIO_TypeDef
*SDIOx
, uint16_t *pRCA
)
1019 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
1020 uint32_t errorstate
= SDMMC_ERROR_NONE
;
1022 /* Send CMD3 SD_CMD_SET_REL_ADDR */
1023 sdmmc_cmdinit
.Argument
= 0U;
1024 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SET_REL_ADDR
;
1025 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
1026 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
1027 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
1028 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
1030 /* Check for error conditions */
1031 errorstate
= SDMMC_GetCmdResp6(SDIOx
, SDMMC_CMD_SET_REL_ADDR
, pRCA
);
1037 * @brief Send the Status command and check the response.
1038 * @param SDIOx: Pointer to SDIO register base
1039 * @retval HAL status
1041 uint32_t SDMMC_CmdSendStatus(SDIO_TypeDef
*SDIOx
, uint32_t Argument
)
1043 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
1044 uint32_t errorstate
= SDMMC_ERROR_NONE
;
1046 sdmmc_cmdinit
.Argument
= (uint32_t)Argument
;
1047 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SEND_STATUS
;
1048 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
1049 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
1050 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
1051 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
1053 /* Check for error conditions */
1054 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_SEND_STATUS
, SDIO_CMDTIMEOUT
);
1060 * @brief Send the Status register command and check the response.
1061 * @param SDIOx: Pointer to SDIO register base
1062 * @retval HAL status
1064 uint32_t SDMMC_CmdStatusRegister(SDIO_TypeDef
*SDIOx
)
1066 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
1067 uint32_t errorstate
= SDMMC_ERROR_NONE
;
1069 sdmmc_cmdinit
.Argument
= 0U;
1070 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SD_APP_STATUS
;
1071 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
1072 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
1073 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
1074 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
1076 /* Check for error conditions */
1077 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_SD_APP_STATUS
, SDIO_CMDTIMEOUT
);
1083 * @brief Sends host capacity support information and activates the card's
1084 * initialization process. Send SDMMC_CMD_SEND_OP_COND command
1085 * @param SDIOx: Pointer to SDIO register base
1086 * @parame Argument: Argument used for the command
1087 * @retval HAL status
1089 uint32_t SDMMC_CmdOpCondition(SDIO_TypeDef
*SDIOx
, uint32_t Argument
)
1091 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
1092 uint32_t errorstate
= SDMMC_ERROR_NONE
;
1094 sdmmc_cmdinit
.Argument
= Argument
;
1095 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_SEND_OP_COND
;
1096 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
1097 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
1098 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
1099 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
1101 /* Check for error conditions */
1102 errorstate
= SDMMC_GetCmdResp3(SDIOx
);
1108 * @brief Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH comand
1109 * @param SDIOx: Pointer to SDIO register base
1110 * @parame Argument: Argument used for the command
1111 * @retval HAL status
1113 uint32_t SDMMC_CmdSwitch(SDIO_TypeDef
*SDIOx
, uint32_t Argument
)
1115 SDIO_CmdInitTypeDef sdmmc_cmdinit
;
1116 uint32_t errorstate
= SDMMC_ERROR_NONE
;
1118 sdmmc_cmdinit
.Argument
= Argument
;
1119 sdmmc_cmdinit
.CmdIndex
= SDMMC_CMD_HS_SWITCH
;
1120 sdmmc_cmdinit
.Response
= SDIO_RESPONSE_SHORT
;
1121 sdmmc_cmdinit
.WaitForInterrupt
= SDIO_WAIT_NO
;
1122 sdmmc_cmdinit
.CPSM
= SDIO_CPSM_ENABLE
;
1123 SDIO_SendCommand(SDIOx
, &sdmmc_cmdinit
);
1125 /* Check for error conditions */
1126 errorstate
= SDMMC_GetCmdResp1(SDIOx
, SDMMC_CMD_HS_SWITCH
, SDIO_CMDTIMEOUT
);
1135 /* Private function ----------------------------------------------------------*/
1136 /** @addtogroup SD_Private_Functions
1141 * @brief Checks for error conditions for CMD0.
1142 * @param hsd: SD handle
1143 * @retval SD Card error state
1145 static uint32_t SDMMC_GetCmdError(SDIO_TypeDef
*SDIOx
)
1147 /* 8 is the number of required instructions cycles for the below loop statement.
1148 The SDMMC_CMDTIMEOUT is expressed in ms */
1149 register uint32_t count
= SDIO_CMDTIMEOUT
* (SystemCoreClock
/ 8U /1000U);
1155 return SDMMC_ERROR_TIMEOUT
;
1158 }while(!__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CMDSENT
));
1160 /* Clear all the static flags */
1161 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_STATIC_FLAGS
);
1163 return SDMMC_ERROR_NONE
;
1167 * @brief Checks for error conditions for R1 response.
1168 * @param hsd: SD handle
1169 * @param SD_CMD: The sent command index
1170 * @retval SD Card error state
1172 static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef
*SDIOx
, uint8_t SD_CMD
, uint32_t Timeout
)
1174 uint32_t response_r1
;
1176 /* 8 is the number of required instructions cycles for the below loop statement.
1177 The Timeout is expressed in ms */
1178 register uint32_t count
= Timeout
* (SystemCoreClock
/ 8U /1000U);
1184 return SDMMC_ERROR_TIMEOUT
;
1187 }while(!__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
| SDIO_FLAG_CMDREND
| SDIO_FLAG_CTIMEOUT
));
1189 if(__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CTIMEOUT
))
1191 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_FLAG_CTIMEOUT
);
1193 return SDMMC_ERROR_CMD_RSP_TIMEOUT
;
1195 else if(__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
))
1197 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
);
1199 return SDMMC_ERROR_CMD_CRC_FAIL
;
1202 /* Check response received is of desired command */
1203 if(SDIO_GetCommandResponse(SDIOx
) != SD_CMD
)
1205 return SDMMC_ERROR_CMD_CRC_FAIL
;
1208 /* Clear all the static flags */
1209 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_STATIC_FLAGS
);
1211 /* We have received response, retrieve it for analysis */
1212 response_r1
= SDIO_GetResponse(SDIOx
, SDIO_RESP1
);
1214 if((response_r1
& SDMMC_OCR_ERRORBITS
) == SDMMC_ALLZERO
)
1216 return SDMMC_ERROR_NONE
;
1218 else if((response_r1
& SDMMC_OCR_ADDR_OUT_OF_RANGE
) == SDMMC_OCR_ADDR_OUT_OF_RANGE
)
1220 return SDMMC_ERROR_ADDR_OUT_OF_RANGE
;
1222 else if((response_r1
& SDMMC_OCR_ADDR_MISALIGNED
) == SDMMC_OCR_ADDR_MISALIGNED
)
1224 return SDMMC_ERROR_ADDR_MISALIGNED
;
1226 else if((response_r1
& SDMMC_OCR_BLOCK_LEN_ERR
) == SDMMC_OCR_BLOCK_LEN_ERR
)
1228 return SDMMC_ERROR_BLOCK_LEN_ERR
;
1230 else if((response_r1
& SDMMC_OCR_ERASE_SEQ_ERR
) == SDMMC_OCR_ERASE_SEQ_ERR
)
1232 return SDMMC_ERROR_ERASE_SEQ_ERR
;
1234 else if((response_r1
& SDMMC_OCR_BAD_ERASE_PARAM
) == SDMMC_OCR_BAD_ERASE_PARAM
)
1236 return SDMMC_ERROR_BAD_ERASE_PARAM
;
1238 else if((response_r1
& SDMMC_OCR_WRITE_PROT_VIOLATION
) == SDMMC_OCR_WRITE_PROT_VIOLATION
)
1240 return SDMMC_ERROR_WRITE_PROT_VIOLATION
;
1242 else if((response_r1
& SDMMC_OCR_LOCK_UNLOCK_FAILED
) == SDMMC_OCR_LOCK_UNLOCK_FAILED
)
1244 return SDMMC_ERROR_LOCK_UNLOCK_FAILED
;
1246 else if((response_r1
& SDMMC_OCR_COM_CRC_FAILED
) == SDMMC_OCR_COM_CRC_FAILED
)
1248 return SDMMC_ERROR_COM_CRC_FAILED
;
1250 else if((response_r1
& SDMMC_OCR_ILLEGAL_CMD
) == SDMMC_OCR_ILLEGAL_CMD
)
1252 return SDMMC_ERROR_ILLEGAL_CMD
;
1254 else if((response_r1
& SDMMC_OCR_CARD_ECC_FAILED
) == SDMMC_OCR_CARD_ECC_FAILED
)
1256 return SDMMC_ERROR_CARD_ECC_FAILED
;
1258 else if((response_r1
& SDMMC_OCR_CC_ERROR
) == SDMMC_OCR_CC_ERROR
)
1260 return SDMMC_ERROR_CC_ERR
;
1262 else if((response_r1
& SDMMC_OCR_STREAM_READ_UNDERRUN
) == SDMMC_OCR_STREAM_READ_UNDERRUN
)
1264 return SDMMC_ERROR_STREAM_READ_UNDERRUN
;
1266 else if((response_r1
& SDMMC_OCR_STREAM_WRITE_OVERRUN
) == SDMMC_OCR_STREAM_WRITE_OVERRUN
)
1268 return SDMMC_ERROR_STREAM_WRITE_OVERRUN
;
1270 else if((response_r1
& SDMMC_OCR_CID_CSD_OVERWRITE
) == SDMMC_OCR_CID_CSD_OVERWRITE
)
1272 return SDMMC_ERROR_CID_CSD_OVERWRITE
;
1274 else if((response_r1
& SDMMC_OCR_WP_ERASE_SKIP
) == SDMMC_OCR_WP_ERASE_SKIP
)
1276 return SDMMC_ERROR_WP_ERASE_SKIP
;
1278 else if((response_r1
& SDMMC_OCR_CARD_ECC_DISABLED
) == SDMMC_OCR_CARD_ECC_DISABLED
)
1280 return SDMMC_ERROR_CARD_ECC_DISABLED
;
1282 else if((response_r1
& SDMMC_OCR_ERASE_RESET
) == SDMMC_OCR_ERASE_RESET
)
1284 return SDMMC_ERROR_ERASE_RESET
;
1286 else if((response_r1
& SDMMC_OCR_AKE_SEQ_ERROR
) == SDMMC_OCR_AKE_SEQ_ERROR
)
1288 return SDMMC_ERROR_AKE_SEQ_ERR
;
1292 return SDMMC_ERROR_GENERAL_UNKNOWN_ERR
;
1297 * @brief Checks for error conditions for R2 (CID or CSD) response.
1298 * @param hsd: SD handle
1299 * @retval SD Card error state
1301 static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef
*SDIOx
)
1303 /* 8 is the number of required instructions cycles for the below loop statement.
1304 The SDMMC_CMDTIMEOUT is expressed in ms */
1305 register uint32_t count
= SDIO_CMDTIMEOUT
* (SystemCoreClock
/ 8U /1000U);
1311 return SDMMC_ERROR_TIMEOUT
;
1314 }while(!__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
| SDIO_FLAG_CMDREND
| SDIO_FLAG_CTIMEOUT
));
1316 if (__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CTIMEOUT
))
1318 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_FLAG_CTIMEOUT
);
1320 return SDMMC_ERROR_CMD_RSP_TIMEOUT
;
1322 else if (__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
))
1324 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
);
1326 return SDMMC_ERROR_CMD_CRC_FAIL
;
1330 /* No error flag set */
1331 /* Clear all the static flags */
1332 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_STATIC_FLAGS
);
1335 return SDMMC_ERROR_NONE
;
1339 * @brief Checks for error conditions for R3 (OCR) response.
1340 * @param hsd: SD handle
1341 * @retval SD Card error state
1343 static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef
*SDIOx
)
1345 /* 8 is the number of required instructions cycles for the below loop statement.
1346 The SDMMC_CMDTIMEOUT is expressed in ms */
1347 register uint32_t count
= SDIO_CMDTIMEOUT
* (SystemCoreClock
/ 8U /1000U);
1353 return SDMMC_ERROR_TIMEOUT
;
1356 }while(!__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
| SDIO_FLAG_CMDREND
| SDIO_FLAG_CTIMEOUT
));
1358 if(__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CTIMEOUT
))
1360 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_FLAG_CTIMEOUT
);
1362 return SDMMC_ERROR_CMD_RSP_TIMEOUT
;
1367 /* Clear all the static flags */
1368 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_STATIC_FLAGS
);
1371 return SDMMC_ERROR_NONE
;
1375 * @brief Checks for error conditions for R6 (RCA) response.
1376 * @param hsd: SD handle
1377 * @param SD_CMD: The sent command index
1378 * @param pRCA: Pointer to the variable that will contain the SD card relative
1380 * @retval SD Card error state
1382 static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef
*SDIOx
, uint8_t SD_CMD
, uint16_t *pRCA
)
1384 uint32_t response_r1
;
1386 /* 8 is the number of required instructions cycles for the below loop statement.
1387 The SDMMC_CMDTIMEOUT is expressed in ms */
1388 register uint32_t count
= SDIO_CMDTIMEOUT
* (SystemCoreClock
/ 8U /1000U);
1394 return SDMMC_ERROR_TIMEOUT
;
1397 }while(!__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
| SDIO_FLAG_CMDREND
| SDIO_FLAG_CTIMEOUT
));
1399 if(__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CTIMEOUT
))
1401 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_FLAG_CTIMEOUT
);
1403 return SDMMC_ERROR_CMD_RSP_TIMEOUT
;
1405 else if(__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
))
1407 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
);
1409 return SDMMC_ERROR_CMD_CRC_FAIL
;
1412 /* Check response received is of desired command */
1413 if(SDIO_GetCommandResponse(SDIOx
) != SD_CMD
)
1415 return SDMMC_ERROR_CMD_CRC_FAIL
;
1418 /* Clear all the static flags */
1419 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_STATIC_FLAGS
);
1421 /* We have received response, retrieve it. */
1422 response_r1
= SDIO_GetResponse(SDIOx
, SDIO_RESP1
);
1424 if((response_r1
& (SDMMC_R6_GENERAL_UNKNOWN_ERROR
| SDMMC_R6_ILLEGAL_CMD
| SDMMC_R6_COM_CRC_FAILED
)) == SDMMC_ALLZERO
)
1426 *pRCA
= (uint16_t) (response_r1
>> 16);
1428 return SDMMC_ERROR_NONE
;
1430 else if((response_r1
& SDMMC_R6_ILLEGAL_CMD
) == SDMMC_R6_ILLEGAL_CMD
)
1432 return SDMMC_ERROR_ILLEGAL_CMD
;
1434 else if((response_r1
& SDMMC_R6_COM_CRC_FAILED
) == SDMMC_R6_COM_CRC_FAILED
)
1436 return SDMMC_ERROR_COM_CRC_FAILED
;
1440 return SDMMC_ERROR_GENERAL_UNKNOWN_ERR
;
1445 * @brief Checks for error conditions for R7 response.
1446 * @param hsd: SD handle
1447 * @retval SD Card error state
1449 static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef
*SDIOx
)
1451 /* 8 is the number of required instructions cycles for the below loop statement.
1452 The SDIO_CMDTIMEOUT is expressed in ms */
1453 register uint32_t count
= SDIO_CMDTIMEOUT
* (SystemCoreClock
/ 8U /1000U);
1459 return SDMMC_ERROR_TIMEOUT
;
1462 }while(!__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CCRCFAIL
| SDIO_FLAG_CMDREND
| SDIO_FLAG_CTIMEOUT
));
1464 if(__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CTIMEOUT
))
1466 /* Card is SD V2.0 compliant */
1467 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_FLAG_CMDREND
);
1469 return SDMMC_ERROR_CMD_RSP_TIMEOUT
;
1472 if(__SDIO_GET_FLAG(SDIOx
, SDIO_FLAG_CMDREND
))
1474 /* Card is SD V2.0 compliant */
1475 __SDIO_CLEAR_FLAG(SDIOx
, SDIO_FLAG_CMDREND
);
1478 return SDMMC_ERROR_NONE
;
1490 #endif /* STM32F103xE || STM32F103xG */
1492 #endif /* (HAL_SD_MODULE_ENABLED) || (HAL_MMC_MODULE_ENABLED) */
1502 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/