Merge maintenance-8.x.x fixes into master
[inav.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_ll_sdmmc.c
blobdd39836dec5f740ff7e10706abd2f18838d89a16
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_ll_sdmmc.c
4 * @author MCD Application Team
5 * @brief SDMMC Low Layer HAL module driver.
7 * This file provides firmware functions to manage the following
8 * functionalities of the SDMMC peripheral:
9 * + Initialization/de-initialization functions
10 * + I/O operation functions
11 * + Peripheral Control functions
12 * + Peripheral State functions
14 ******************************************************************************
15 * @attention
17 * Copyright (c) 2017 STMicroelectronics.
18 * All rights reserved.
20 * This software is licensed under terms that can be found in the LICENSE file
21 * in the root directory of this software component.
22 * If no LICENSE file comes with this software, it is provided AS-IS.
24 ******************************************************************************
25 @verbatim
26 ==============================================================================
27 ##### SDMMC peripheral features #####
28 ==============================================================================
29 [..] The SD/SDMMC MMC card host interface (SDMMC) provides an interface between the AHB
30 peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDMMC cards and CE-ATA
31 devices.
33 [..] The SDMMC features include the following:
34 (+) Full compliance with MultiMediaCard System Specification Version 4.51. Card support
35 for three different databus modes: 1-bit (default), 4-bit and 8-bit.
36 (+) Full compatibility with previous versions of MultiMediaCards (backward compatibility).
37 (+) Full compliance with SD memory card specifications version 4.1.
38 (SDR104 SDMMC_CK speed limited to maximum allowed IO speed, SPI mode and
39 UHS-II mode not supported).
40 (+) Full compliance with SDIO card specification version 4.0. Card support
41 for two different databus modes: 1-bit (default) and 4-bit.
42 (SDR104 SDMMC_CK speed limited to maximum allowed IO speed, SPI mode and
43 UHS-II mode not supported).
44 (+) Data transfer up to 208 Mbyte/s for the 8 bit mode. (depending maximum allowed IO speed).
45 (+) Data and command output enable signals to control external bidirectional drivers
47 ##### How to use this driver #####
48 ==============================================================================
49 [..]
50 This driver is a considered as a driver of service for external devices drivers
51 that interfaces with the SDMMC peripheral.
52 According to the device used (SD card/ MMC card / SDMMC card ...), a set of APIs
53 is used in the device's driver to perform SDMMC operations and functionalities.
55 This driver is almost transparent for the final user, it is only used to implement other
56 functionalities of the external device.
58 [..]
59 (+) The SDMMC clock is coming from output of PLL1_Q or PLL2_R.
60 Before start working with SDMMC peripheral make sure that the PLL is well configured.
61 The SDMMC peripheral uses two clock signals:
62 (++) PLL1_Q bus clock (default after reset)
63 (++) PLL2_R bus clock
65 (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDMMC
66 peripheral.
68 (+) Enable the Power ON State using the SDMMC_PowerState_ON(SDMMCx)
69 function and disable it using the function SDMMC_PowerState_OFF(SDMMCx).
71 (+) Enable/Disable the peripheral interrupts using the macros __SDMMC_ENABLE_IT(hSDMMC, IT)
72 and __SDMMC_DISABLE_IT(hSDMMC, IT) if you need to use interrupt mode.
74 (+) When using the DMA mode
75 (++) Configure the IDMA mode (Single buffer or double)
76 (++) Configure the buffer address
77 (++) Configure Data Path State Machine
79 (+) To control the CPSM (Command Path State Machine) and send
80 commands to the card use the SDMMC_SendCommand(SDMMCx),
81 SDMMC_GetCommandResponse() and SDMMC_GetResponse() functions. First, user has
82 to fill the command structure (pointer to SDMMC_CmdInitTypeDef) according
83 to the selected command to be sent.
84 The parameters that should be filled are:
85 (++) Command Argument
86 (++) Command Index
87 (++) Command Response type
88 (++) Command Wait
89 (++) CPSM Status (Enable or Disable).
91 -@@- To check if the command is well received, read the SDMMC_CMDRESP
92 register using the SDMMC_GetCommandResponse().
93 The SDMMC responses registers (SDMMC_RESP1 to SDMMC_RESP2), use the
94 SDMMC_GetResponse() function.
96 (+) To control the DPSM (Data Path State Machine) and send/receive
97 data to/from the card use the SDMMC_DataConfig(), SDMMC_GetDataCounter(),
98 SDMMC_ReadFIFO(), SDMMC_WriteFIFO() and SDMMC_GetFIFOCount() functions.
100 *** Read Operations ***
101 =======================
102 [..]
103 (#) First, user has to fill the data structure (pointer to
104 SDMMC_DataInitTypeDef) according to the selected data type to be received.
105 The parameters that should be filled are:
106 (++) Data TimeOut
107 (++) Data Length
108 (++) Data Block size
109 (++) Data Transfer direction: should be from card (To SDMMC)
110 (++) Data Transfer mode
111 (++) DPSM Status (Enable or Disable)
113 (#) Configure the SDMMC resources to receive the data from the card
114 according to selected transfer mode (Refer to Step 8, 9 and 10).
116 (#) Send the selected Read command (refer to step 11).
118 (#) Use the SDMMC flags/interrupts to check the transfer status.
120 *** Write Operations ***
121 ========================
122 [..]
123 (#) First, user has to fill the data structure (pointer to
124 SDMMC_DataInitTypeDef) according to the selected data type to be received.
125 The parameters that should be filled are:
126 (++) Data TimeOut
127 (++) Data Length
128 (++) Data Block size
129 (++) Data Transfer direction: should be to card (To CARD)
130 (++) Data Transfer mode
131 (++) DPSM Status (Enable or Disable)
133 (#) Configure the SDMMC resources to send the data to the card according to
134 selected transfer mode.
136 (#) Send the selected Write command.
138 (#) Use the SDMMC flags/interrupts to check the transfer status.
140 *** Command management operations ***
141 =====================================
142 [..]
143 (#) The commands used for Read/Write/Erase operations are managed in
144 separate functions.
145 Each function allows to send the needed command with the related argument,
146 then check the response.
147 By the same approach, you could implement a command and check the response.
149 @endverbatim
150 ******************************************************************************
153 /* Includes ------------------------------------------------------------------*/
154 #include "stm32h7xx_hal.h"
156 /** @addtogroup STM32H7xx_HAL_Driver
157 * @{
160 /** @defgroup SDMMC_LL SDMMC Low Layer
161 * @brief Low layer module for SD
162 * @{
165 #if defined (SDMMC1) || defined (SDMMC2)
166 #if defined (HAL_SD_MODULE_ENABLED) || defined (HAL_MMC_MODULE_ENABLED) || defined (HAL_SDIO_MODULE_ENABLED)
168 /* Private typedef -----------------------------------------------------------*/
169 /* Private define ------------------------------------------------------------*/
170 /* Private macro -------------------------------------------------------------*/
171 /* Private variables ---------------------------------------------------------*/
172 /* Private function prototypes -----------------------------------------------*/
173 static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx);
175 /* Exported functions --------------------------------------------------------*/
177 /** @defgroup SDMMC_LL_Exported_Functions SDMMC Low Layer Exported Functions
178 * @{
181 /** @defgroup HAL_SDMMC_LL_Group1 Initialization de-initialization functions
182 * @brief Initialization and Configuration functions
184 @verbatim
185 ===============================================================================
186 ##### Initialization/de-initialization functions #####
187 ===============================================================================
188 [..] This section provides functions allowing to:
190 @endverbatim
191 * @{
195 * @brief Initializes the SDMMC according to the specified
196 * parameters in the SDMMC_InitTypeDef and create the associated handle.
197 * @param SDMMCx: Pointer to SDMMC register base
198 * @param Init: SDMMC initialization structure
199 * @retval HAL status
201 HAL_StatusTypeDef SDMMC_Init(SDMMC_TypeDef *SDMMCx, SDMMC_InitTypeDef Init)
203 uint32_t tmpreg = 0;
205 /* Check the parameters */
206 assert_param(IS_SDMMC_ALL_INSTANCE(SDMMCx));
207 assert_param(IS_SDMMC_CLOCK_EDGE(Init.ClockEdge));
208 assert_param(IS_SDMMC_CLOCK_POWER_SAVE(Init.ClockPowerSave));
209 assert_param(IS_SDMMC_BUS_WIDE(Init.BusWide));
210 assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl));
211 assert_param(IS_SDMMC_CLKDIV(Init.ClockDiv));
213 /* Set SDMMC configuration parameters */
214 tmpreg |= (Init.ClockEdge | \
215 Init.ClockPowerSave | \
216 Init.BusWide | \
217 Init.HardwareFlowControl | \
218 Init.ClockDiv
221 /* Write to SDMMC CLKCR */
222 MODIFY_REG(SDMMCx->CLKCR, CLKCR_CLEAR_MASK, tmpreg);
224 return HAL_OK;
229 * @}
232 /** @defgroup HAL_SDMMC_LL_Group2 IO operation functions
233 * @brief Data transfers functions
235 @verbatim
236 ===============================================================================
237 ##### I/O operation functions #####
238 ===============================================================================
239 [..]
240 This subsection provides a set of functions allowing to manage the SDMMC data
241 transfers.
243 @endverbatim
244 * @{
248 * @brief Read data (word) from Rx FIFO in blocking mode (polling)
249 * @param SDMMCx: Pointer to SDMMC register base
250 * @retval HAL status
252 uint32_t SDMMC_ReadFIFO(const SDMMC_TypeDef *SDMMCx)
254 /* Read data from Rx FIFO */
255 return (SDMMCx->FIFO);
259 * @brief Write data (word) to Tx FIFO in blocking mode (polling)
260 * @param SDMMCx: Pointer to SDMMC register base
261 * @param pWriteData: pointer to data to write
262 * @retval HAL status
264 HAL_StatusTypeDef SDMMC_WriteFIFO(SDMMC_TypeDef *SDMMCx, uint32_t *pWriteData)
266 /* Write data to FIFO */
267 SDMMCx->FIFO = *pWriteData;
269 return HAL_OK;
273 * @}
276 /** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions
277 * @brief management functions
279 @verbatim
280 ===============================================================================
281 ##### Peripheral Control functions #####
282 ===============================================================================
283 [..]
284 This subsection provides a set of functions allowing to control the SDMMC data
285 transfers.
287 @endverbatim
288 * @{
292 * @brief Set SDMMC Power state to ON.
293 * @param SDMMCx: Pointer to SDMMC register base
294 * @retval HAL status
296 HAL_StatusTypeDef SDMMC_PowerState_ON(SDMMC_TypeDef *SDMMCx)
298 /* Set power state to ON */
299 SDMMCx->POWER |= SDMMC_POWER_PWRCTRL;
301 return HAL_OK;
305 * @brief Set SDMMC Power state to Power-Cycle.
306 * @param SDMMCx: Pointer to SDMMC register base
307 * @retval HAL status
309 HAL_StatusTypeDef SDMMC_PowerState_Cycle(SDMMC_TypeDef *SDMMCx)
311 /* Set power state to Power Cycle*/
312 SDMMCx->POWER |= SDMMC_POWER_PWRCTRL_1;
314 return HAL_OK;
318 * @brief Set SDMMC Power state to OFF.
319 * @param SDMMCx: Pointer to SDMMC register base
320 * @retval HAL status
322 HAL_StatusTypeDef SDMMC_PowerState_OFF(SDMMC_TypeDef *SDMMCx)
324 /* Set power state to OFF */
325 SDMMCx->POWER &= ~(SDMMC_POWER_PWRCTRL);
327 return HAL_OK;
331 * @brief Get SDMMC Power state.
332 * @param SDMMCx: Pointer to SDMMC register base
333 * @retval Power status of the controller. The returned value can be one of the
334 * following values:
335 * - 0x00: Power OFF
336 * - 0x02: Power UP
337 * - 0x03: Power ON
339 uint32_t SDMMC_GetPowerState(const SDMMC_TypeDef *SDMMCx)
341 return (SDMMCx->POWER & SDMMC_POWER_PWRCTRL);
345 * @brief Configure the SDMMC command path according to the specified parameters in
346 * SDMMC_CmdInitTypeDef structure and send the command
347 * @param SDMMCx: Pointer to SDMMC register base
348 * @param Command: pointer to a SDMMC_CmdInitTypeDef structure that contains
349 * the configuration information for the SDMMC command
350 * @retval HAL status
352 HAL_StatusTypeDef SDMMC_SendCommand(SDMMC_TypeDef *SDMMCx, const SDMMC_CmdInitTypeDef *Command)
354 uint32_t tmpreg = 0;
356 /* Check the parameters */
357 assert_param(IS_SDMMC_CMD_INDEX(Command->CmdIndex));
358 assert_param(IS_SDMMC_RESPONSE(Command->Response));
359 assert_param(IS_SDMMC_WAIT(Command->WaitForInterrupt));
360 assert_param(IS_SDMMC_CPSM(Command->CPSM));
362 /* Set the SDMMC Argument value */
363 SDMMCx->ARG = Command->Argument;
365 /* Set SDMMC command parameters */
366 tmpreg |= (uint32_t)(Command->CmdIndex | \
367 Command->Response | \
368 Command->WaitForInterrupt | \
369 Command->CPSM);
371 /* Write to SDMMC CMD register */
372 MODIFY_REG(SDMMCx->CMD, CMD_CLEAR_MASK, tmpreg);
374 return HAL_OK;
378 * @brief Return the command index of last command for which response received
379 * @param SDMMCx: Pointer to SDMMC register base
380 * @retval Command index of the last command response received
382 uint8_t SDMMC_GetCommandResponse(const SDMMC_TypeDef *SDMMCx)
384 return (uint8_t)(SDMMCx->RESPCMD);
389 * @brief Return the response received from the card for the last command
390 * @param SDMMCx: Pointer to SDMMC register base
391 * @param Response: Specifies the SDMMC response register.
392 * This parameter can be one of the following values:
393 * @arg SDMMC_RESP1: Response Register 1
394 * @arg SDMMC_RESP2: Response Register 2
395 * @arg SDMMC_RESP3: Response Register 3
396 * @arg SDMMC_RESP4: Response Register 4
397 * @retval The Corresponding response register value
399 uint32_t SDMMC_GetResponse(const SDMMC_TypeDef *SDMMCx, uint32_t Response)
401 uint32_t tmp;
403 /* Check the parameters */
404 assert_param(IS_SDMMC_RESP(Response));
406 /* Get the response */
407 tmp = (uint32_t)(&(SDMMCx->RESP1)) + Response;
409 return (*(__IO uint32_t *) tmp);
413 * @brief Configure the SDMMC data path according to the specified
414 * parameters in the SDMMC_DataInitTypeDef.
415 * @param SDMMCx: Pointer to SDMMC register base
416 * @param Data : pointer to a SDMMC_DataInitTypeDef structure
417 * that contains the configuration information for the SDMMC data.
418 * @retval HAL status
420 HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, const SDMMC_DataInitTypeDef *Data)
422 uint32_t tmpreg = 0;
424 /* Check the parameters */
425 assert_param(IS_SDMMC_DATA_LENGTH(Data->DataLength));
426 assert_param(IS_SDMMC_BLOCK_SIZE(Data->DataBlockSize));
427 assert_param(IS_SDMMC_TRANSFER_DIR(Data->TransferDir));
428 assert_param(IS_SDMMC_TRANSFER_MODE(Data->TransferMode));
429 assert_param(IS_SDMMC_DPSM(Data->DPSM));
431 /* Set the SDMMC Data TimeOut value */
432 SDMMCx->DTIMER = Data->DataTimeOut;
434 /* Set the SDMMC DataLength value */
435 SDMMCx->DLEN = Data->DataLength;
437 /* Set the SDMMC data configuration parameters */
438 tmpreg |= (uint32_t)(Data->DataBlockSize | \
439 Data->TransferDir | \
440 Data->TransferMode | \
441 Data->DPSM);
443 /* Write to SDMMC DCTRL */
444 MODIFY_REG(SDMMCx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);
446 return HAL_OK;
451 * @brief Returns number of remaining data bytes to be transferred.
452 * @param SDMMCx: Pointer to SDMMC register base
453 * @retval Number of remaining data bytes to be transferred
455 uint32_t SDMMC_GetDataCounter(const SDMMC_TypeDef *SDMMCx)
457 return (SDMMCx->DCOUNT);
461 * @brief Get the FIFO data
462 * @param SDMMCx: Pointer to SDMMC register base
463 * @retval Data received
465 uint32_t SDMMC_GetFIFOCount(const SDMMC_TypeDef *SDMMCx)
467 return (SDMMCx->FIFO);
471 * @brief Sets one of the two options of inserting read wait interval.
472 * @param SDMMCx: Pointer to SDMMC register base
473 * @param SDMMC_ReadWaitMode: SDMMC Read Wait operation mode.
474 * This parameter can be:
475 * @arg SDMMC_READ_WAIT_MODE_CLK: Read Wait control by stopping SDMMCCLK
476 * @arg SDMMC_READ_WAIT_MODE_DATA2: Read Wait control using SDMMC_DATA2
477 * @retval None
479 HAL_StatusTypeDef SDMMC_SetSDMMCReadWaitMode(SDMMC_TypeDef *SDMMCx, uint32_t SDMMC_ReadWaitMode)
481 /* Check the parameters */
482 assert_param(IS_SDMMC_READWAIT_MODE(SDMMC_ReadWaitMode));
484 /* Set SDMMC read wait mode */
485 MODIFY_REG(SDMMCx->DCTRL, SDMMC_DCTRL_RWMOD, SDMMC_ReadWaitMode);
487 return HAL_OK;
491 * @}
495 /** @defgroup HAL_SDMMC_LL_Group4 Command management functions
496 * @brief Data transfers functions
498 @verbatim
499 ===============================================================================
500 ##### Commands management functions #####
501 ===============================================================================
502 [..]
503 This subsection provides a set of functions allowing to manage the needed commands.
505 @endverbatim
506 * @{
510 * @brief Send the Data Block Length command and check the response
511 * @param SDMMCx: Pointer to SDMMC register base
512 * @retval HAL status
514 uint32_t SDMMC_CmdBlockLength(SDMMC_TypeDef *SDMMCx, uint32_t BlockSize)
516 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
517 uint32_t errorstate;
519 /* Set Block Size for Card */
520 sdmmc_cmdinit.Argument = (uint32_t)BlockSize;
521 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCKLEN;
522 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
523 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
524 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
525 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
527 /* Check for error conditions */
528 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_BLOCKLEN, SDMMC_CMDTIMEOUT);
530 return errorstate;
534 * @brief Send the Data Block number command and check the response
535 * @param SDMMCx: Pointer to SDMMC register base
536 * @retval HAL status
538 uint32_t SDMMC_CmdBlockCount(SDMMC_TypeDef *SDMMCx, uint32_t BlockCount)
540 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
541 uint32_t errorstate;
543 /* Set Block Size for Card */
544 sdmmc_cmdinit.Argument = (uint32_t)BlockCount;
545 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCK_COUNT;
546 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
547 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
548 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
549 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
551 /* Check for error conditions */
552 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_BLOCK_COUNT, SDMMC_CMDTIMEOUT);
554 return errorstate;
558 * @brief Send the Read Single Block command and check the response
559 * @param SDMMCx: Pointer to SDMMC register base
560 * @retval HAL status
562 uint32_t SDMMC_CmdReadSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
564 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
565 uint32_t errorstate;
567 /* Set Block Size for Card */
568 sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
569 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_SINGLE_BLOCK;
570 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
571 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
572 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
573 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
575 /* Check for error conditions */
576 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_SINGLE_BLOCK, SDMMC_CMDTIMEOUT);
578 return errorstate;
582 * @brief Send the Read Multi Block command and check the response
583 * @param SDMMCx: Pointer to SDMMC register base
584 * @retval HAL status
586 uint32_t SDMMC_CmdReadMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
588 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
589 uint32_t errorstate;
591 /* Set Block Size for Card */
592 sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
593 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_MULT_BLOCK;
594 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
595 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
596 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
597 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
599 /* Check for error conditions */
600 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_MULT_BLOCK, SDMMC_CMDTIMEOUT);
602 return errorstate;
606 * @brief Send the Write Single Block command and check the response
607 * @param SDMMCx: Pointer to SDMMC register base
608 * @retval HAL status
610 uint32_t SDMMC_CmdWriteSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
612 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
613 uint32_t errorstate;
615 /* Set Block Size for Card */
616 sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
617 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_SINGLE_BLOCK;
618 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
619 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
620 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
621 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
623 /* Check for error conditions */
624 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDMMC_CMDTIMEOUT);
626 return errorstate;
630 * @brief Send the Write Multi Block command and check the response
631 * @param SDMMCx: Pointer to SDMMC register base
632 * @retval HAL status
634 uint32_t SDMMC_CmdWriteMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
636 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
637 uint32_t errorstate;
639 /* Set Block Size for Card */
640 sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
641 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_MULT_BLOCK;
642 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
643 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
644 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
645 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
647 /* Check for error conditions */
648 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_MULT_BLOCK, SDMMC_CMDTIMEOUT);
650 return errorstate;
654 * @brief Send the Start Address Erase command for SD and check the response
655 * @param SDMMCx: Pointer to SDMMC register base
656 * @retval HAL status
658 uint32_t SDMMC_CmdSDEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd)
660 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
661 uint32_t errorstate;
663 /* Set Block Size for Card */
664 sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
665 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_START;
666 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
667 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
668 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
669 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
671 /* Check for error conditions */
672 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_START, SDMMC_CMDTIMEOUT);
674 return errorstate;
678 * @brief Send the End Address Erase command for SD and check the response
679 * @param SDMMCx: Pointer to SDMMC register base
680 * @retval HAL status
682 uint32_t SDMMC_CmdSDEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd)
684 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
685 uint32_t errorstate;
687 /* Set Block Size for Card */
688 sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
689 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_END;
690 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
691 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
692 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
693 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
695 /* Check for error conditions */
696 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_END, SDMMC_CMDTIMEOUT);
698 return errorstate;
702 * @brief Send the Start Address Erase command and check the response
703 * @param SDMMCx: Pointer to SDMMC register base
704 * @retval HAL status
706 uint32_t SDMMC_CmdEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd)
708 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
709 uint32_t errorstate;
711 /* Set Block Size for Card */
712 sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
713 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_START;
714 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
715 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
716 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
717 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
719 /* Check for error conditions */
720 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_START, SDMMC_CMDTIMEOUT);
722 return errorstate;
726 * @brief Send the End Address Erase command and check the response
727 * @param SDMMCx: Pointer to SDMMC register base
728 * @retval HAL status
730 uint32_t SDMMC_CmdEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd)
732 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
733 uint32_t errorstate;
735 /* Set Block Size for Card */
736 sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
737 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_END;
738 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
739 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
740 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
741 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
743 /* Check for error conditions */
744 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_END, SDMMC_CMDTIMEOUT);
746 return errorstate;
750 * @brief Send the Erase command and check the response
751 * @param SDMMCx Pointer to SDMMC register base
752 * @param EraseType Type of erase to be performed
753 * @retval HAL status
755 uint32_t SDMMC_CmdErase(SDMMC_TypeDef *SDMMCx, uint32_t EraseType)
757 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
758 uint32_t errorstate;
760 /* Set Block Size for Card */
761 sdmmc_cmdinit.Argument = EraseType;
762 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE;
763 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
764 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
765 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
766 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
768 /* Check for error conditions */
769 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE, SDMMC_MAXERASETIMEOUT);
771 return errorstate;
775 * @brief Send the Stop Transfer command and check the response.
776 * @param SDMMCx: Pointer to SDMMC register base
777 * @retval HAL status
779 uint32_t SDMMC_CmdStopTransfer(SDMMC_TypeDef *SDMMCx)
781 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
782 uint32_t errorstate;
784 /* Send CMD12 STOP_TRANSMISSION */
785 sdmmc_cmdinit.Argument = 0U;
786 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION;
787 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
788 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
789 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
791 __SDMMC_CMDSTOP_ENABLE(SDMMCx);
792 __SDMMC_CMDTRANS_DISABLE(SDMMCx);
794 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
796 /* Check for error conditions */
797 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_STOP_TRANSMISSION, SDMMC_STOPTRANSFERTIMEOUT);
799 __SDMMC_CMDSTOP_DISABLE(SDMMCx);
801 /* Ignore Address Out Of Range Error, Not relevant at end of memory */
802 if (errorstate == SDMMC_ERROR_ADDR_OUT_OF_RANGE)
804 errorstate = SDMMC_ERROR_NONE;
807 return errorstate;
811 * @brief Send the Select Deselect command and check the response.
812 * @param SDMMCx: Pointer to SDMMC register base
813 * @param addr: Address of the card to be selected
814 * @retval HAL status
816 uint32_t SDMMC_CmdSelDesel(SDMMC_TypeDef *SDMMCx, uint32_t Addr)
818 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
819 uint32_t errorstate;
821 /* Send CMD7 SDMMC_SEL_DESEL_CARD */
822 sdmmc_cmdinit.Argument = (uint32_t)Addr;
823 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEL_DESEL_CARD;
824 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
825 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
826 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
827 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
829 /* Check for error conditions */
830 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEL_DESEL_CARD, SDMMC_CMDTIMEOUT);
832 return errorstate;
836 * @brief Send the Go Idle State command and check the response.
837 * @param SDMMCx: Pointer to SDMMC register base
838 * @retval HAL status
840 uint32_t SDMMC_CmdGoIdleState(SDMMC_TypeDef *SDMMCx)
842 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
843 uint32_t errorstate;
845 sdmmc_cmdinit.Argument = 0U;
846 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_GO_IDLE_STATE;
847 sdmmc_cmdinit.Response = SDMMC_RESPONSE_NO;
848 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
849 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
850 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
852 /* Check for error conditions */
853 errorstate = SDMMC_GetCmdError(SDMMCx);
855 return errorstate;
859 * @brief Send the Operating Condition command and check the response.
860 * @param SDMMCx: Pointer to SDMMC register base
861 * @retval HAL status
863 uint32_t SDMMC_CmdOperCond(SDMMC_TypeDef *SDMMCx)
865 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
866 uint32_t errorstate;
868 /* Send CMD8 to verify SD card interface operating condition */
869 /* Argument: - [31:12]: Reserved (shall be set to '0')
870 - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
871 - [7:0]: Check Pattern (recommended 0xAA) */
872 /* CMD Response: R7 */
873 sdmmc_cmdinit.Argument = SDMMC_CHECK_PATTERN;
874 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD;
875 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
876 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
877 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
878 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
880 /* Check for error conditions */
881 errorstate = SDMMC_GetCmdResp7(SDMMCx);
883 return errorstate;
887 * @brief Send the Application command to verify that that the next command
888 * is an application specific com-mand rather than a standard command
889 * and check the response.
890 * @param SDMMCx: Pointer to SDMMC register base
891 * @param Argument: Command Argument
892 * @retval HAL status
894 uint32_t SDMMC_CmdAppCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
896 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
897 uint32_t errorstate;
899 sdmmc_cmdinit.Argument = (uint32_t)Argument;
900 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_CMD;
901 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
902 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
903 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
904 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
906 /* Check for error conditions */
907 /* If there is a HAL_ERROR, it is a MMC card, else
908 it is a SD card: SD card 2.0 (voltage range mismatch)
909 or SD card 1.x */
910 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_CMD, SDMMC_CMDTIMEOUT);
912 return errorstate;
916 * @brief Send the command asking the accessed card to send its operating
917 * condition register (OCR)
918 * @param SDMMCx: Pointer to SDMMC register base
919 * @param Argument: Command Argument
920 * @retval HAL status
922 uint32_t SDMMC_CmdAppOperCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
924 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
925 uint32_t errorstate;
927 sdmmc_cmdinit.Argument = Argument;
928 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_OP_COND;
929 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
930 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
931 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
932 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
934 /* Check for error conditions */
935 errorstate = SDMMC_GetCmdResp3(SDMMCx);
937 return errorstate;
941 * @brief Send the Bus Width command and check the response.
942 * @param SDMMCx: Pointer to SDMMC register base
943 * @param BusWidth: BusWidth
944 * @retval HAL status
946 uint32_t SDMMC_CmdBusWidth(SDMMC_TypeDef *SDMMCx, uint32_t BusWidth)
948 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
949 uint32_t errorstate;
951 sdmmc_cmdinit.Argument = (uint32_t)BusWidth;
952 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_SD_SET_BUSWIDTH;
953 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
954 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
955 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
956 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
958 /* Check for error conditions */
959 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDMMC_CMDTIMEOUT);
961 return errorstate;
965 * @brief Send the Send SCR command and check the response.
966 * @param SDMMCx: Pointer to SDMMC register base
967 * @retval HAL status
969 uint32_t SDMMC_CmdSendSCR(SDMMC_TypeDef *SDMMCx)
971 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
972 uint32_t errorstate;
974 /* Send CMD51 SD_APP_SEND_SCR */
975 sdmmc_cmdinit.Argument = 0U;
976 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR;
977 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
978 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
979 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
980 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
982 /* Check for error conditions */
983 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_SEND_SCR, SDMMC_CMDTIMEOUT);
985 return errorstate;
989 * @brief Send the Send CID command and check the response.
990 * @param SDMMCx: Pointer to SDMMC register base
991 * @retval HAL status
993 uint32_t SDMMC_CmdSendCID(SDMMC_TypeDef *SDMMCx)
995 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
996 uint32_t errorstate;
998 /* Send CMD2 ALL_SEND_CID */
999 sdmmc_cmdinit.Argument = 0U;
1000 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID;
1001 sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG;
1002 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1003 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1004 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1006 /* Check for error conditions */
1007 errorstate = SDMMC_GetCmdResp2(SDMMCx);
1009 return errorstate;
1013 * @brief Send the Send CSD command and check the response.
1014 * @param SDMMCx: Pointer to SDMMC register base
1015 * @param Argument: Command Argument
1016 * @retval HAL status
1018 uint32_t SDMMC_CmdSendCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1020 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1021 uint32_t errorstate;
1023 /* Send CMD9 SEND_CSD */
1024 sdmmc_cmdinit.Argument = Argument;
1025 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_CSD;
1026 sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG;
1027 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1028 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1029 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1031 /* Check for error conditions */
1032 errorstate = SDMMC_GetCmdResp2(SDMMCx);
1034 return errorstate;
1038 * @brief Send the Send CSD command and check the response.
1039 * @param SDMMCx: Pointer to SDMMC register base
1040 * @param pRCA: Card RCA
1041 * @retval HAL status
1043 uint32_t SDMMC_CmdSetRelAdd(SDMMC_TypeDef *SDMMCx, uint16_t *pRCA)
1045 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1046 uint32_t errorstate;
1048 /* Send CMD3 SD_CMD_SET_REL_ADDR */
1049 sdmmc_cmdinit.Argument = 0U;
1050 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR;
1051 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1052 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1053 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1054 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1056 /* Check for error conditions */
1057 errorstate = SDMMC_GetCmdResp6(SDMMCx, SDMMC_CMD_SET_REL_ADDR, pRCA);
1059 return errorstate;
1063 * @brief Send the Set Relative Address command to MMC card (not SD card).
1064 * @param SDMMCx Pointer to SDMMC register base
1065 * @param RCA Card RCA
1066 * @retval HAL status
1068 uint32_t SDMMC_CmdSetRelAddMmc(SDMMC_TypeDef *SDMMCx, uint16_t RCA)
1070 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1071 uint32_t errorstate;
1073 /* Send CMD3 SD_CMD_SET_REL_ADDR */
1074 sdmmc_cmdinit.Argument = ((uint32_t)RCA << 16U);
1075 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR;
1076 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1077 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1078 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1079 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1081 /* Check for error conditions */
1082 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_REL_ADDR, SDMMC_CMDTIMEOUT);
1084 return errorstate;
1088 * @brief Send the Sleep command to MMC card (not SD card).
1089 * @param SDMMCx Pointer to SDMMC register base
1090 * @param Argument Argument of the command (RCA and Sleep/Awake)
1091 * @retval HAL status
1093 uint32_t SDMMC_CmdSleepMmc(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1095 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1096 uint32_t errorstate;
1098 /* Send CMD5 SDMMC_CMD_MMC_SLEEP_AWAKE */
1099 sdmmc_cmdinit.Argument = Argument;
1100 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_MMC_SLEEP_AWAKE;
1101 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1102 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1103 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1104 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1106 /* Check for error conditions */
1107 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_MMC_SLEEP_AWAKE, SDMMC_CMDTIMEOUT);
1109 return errorstate;
1113 * @brief Send the Status command and check the response.
1114 * @param SDMMCx: Pointer to SDMMC register base
1115 * @param Argument: Command Argument
1116 * @retval HAL status
1118 uint32_t SDMMC_CmdSendStatus(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1120 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1121 uint32_t errorstate;
1123 sdmmc_cmdinit.Argument = Argument;
1124 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_STATUS;
1125 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1126 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1127 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1128 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1130 /* Check for error conditions */
1131 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEND_STATUS, SDMMC_CMDTIMEOUT);
1133 return errorstate;
1137 * @brief Send the Status register command and check the response.
1138 * @param SDMMCx: Pointer to SDMMC register base
1139 * @retval HAL status
1141 uint32_t SDMMC_CmdStatusRegister(SDMMC_TypeDef *SDMMCx)
1143 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1144 uint32_t errorstate;
1146 sdmmc_cmdinit.Argument = 0U;
1147 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS;
1148 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1149 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1150 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1151 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1153 /* Check for error conditions */
1154 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_STATUS, SDMMC_CMDTIMEOUT);
1156 return errorstate;
1160 * @brief Sends host capacity support information and activates the card's
1161 * initialization process. Send SDMMC_CMD_SEND_OP_COND command
1162 * @param SDMMCx: Pointer to SDMMC register base
1163 * @parame Argument: Argument used for the command
1164 * @retval HAL status
1166 uint32_t SDMMC_CmdOpCondition(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1168 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1169 uint32_t errorstate;
1171 sdmmc_cmdinit.Argument = Argument;
1172 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_OP_COND;
1173 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1174 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1175 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1176 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1178 /* Check for error conditions */
1179 errorstate = SDMMC_GetCmdResp3(SDMMCx);
1181 return errorstate;
1185 * @brief Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH command
1186 * @param SDMMCx: Pointer to SDMMC register base
1187 * @parame Argument: Argument used for the command
1188 * @retval HAL status
1190 uint32_t SDMMC_CmdSwitch(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1192 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1193 uint32_t errorstate;
1195 /* Send CMD6 to activate SDR50 Mode and Power Limit 1.44W */
1196 /* CMD Response: R1 */
1197 sdmmc_cmdinit.Argument = Argument; /* SDMMC_SDR25_SWITCH_PATTERN*/
1198 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SWITCH;
1199 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1200 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1201 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1202 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1204 /* Check for error conditions */
1205 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_HS_SWITCH, SDMMC_CMDTIMEOUT);
1207 return errorstate;
1211 * @brief Send the command asking the accessed card to send its operating
1212 * condition register (OCR)
1213 * @param None
1214 * @retval HAL status
1216 uint32_t SDMMC_CmdVoltageSwitch(SDMMC_TypeDef *SDMMCx)
1218 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1219 uint32_t errorstate;
1221 sdmmc_cmdinit.Argument = 0x00000000;
1222 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_VOLTAGE_SWITCH;
1223 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1224 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1225 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1226 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1228 /* Check for error conditions */
1229 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_VOLTAGE_SWITCH, SDMMC_CMDTIMEOUT);
1231 return errorstate;
1235 * @brief Send the Send EXT_CSD command and check the response.
1236 * @param SDMMCx: Pointer to SDMMC register base
1237 * @param Argument: Command Argument
1238 * @retval HAL status
1240 uint32_t SDMMC_CmdSendEXTCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1242 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1243 uint32_t errorstate;
1245 /* Send CMD9 SEND_CSD */
1246 sdmmc_cmdinit.Argument = Argument;
1247 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD;
1248 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1249 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1250 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1251 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1253 /* Check for error conditions */
1254 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_HS_SEND_EXT_CSD, SDMMC_CMDTIMEOUT);
1256 return errorstate;
1260 * @brief Execute a cmd52 to write single byte data and read single byte data if needed
1261 * @param SDMMCx: Pointer to SDMMC register base
1262 * @param Argument: SDMMC command argument which is sent to a card as part of a command message
1263 * @param pData: pointer to read response if needed
1264 * @retval SD Card error state
1266 uint32_t SDMMC_SDIO_CmdReadWriteDirect(SDMMC_TypeDef *SDMMCx, uint32_t Argument, uint8_t *pResponse)
1268 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1269 uint32_t errorstate;
1271 sdmmc_cmdinit.Argument = Argument;
1272 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SDMMC_RW_DIRECT;
1273 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1274 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1275 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1276 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1278 /* Check for error conditions */
1279 errorstate = SDMMC_GetCmdResp5(SDMMCx, SDMMC_CMD_SDMMC_RW_DIRECT, pResponse);
1281 return errorstate;
1285 * @brief Execute a cmd53 to write or read multiple data with a single command
1286 * @param SDMMCx: Pointer to SDMMC register base
1287 * @param Argument: SDMMC command argument which is sent to a card as part of a command message
1288 * @retval SD Card error state
1290 uint32_t SDMMC_SDIO_CmdReadWriteExtended(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1292 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1293 uint32_t errorstate;
1295 sdmmc_cmdinit.Argument = Argument;
1296 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SDMMC_RW_EXTENDED;
1297 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1298 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1299 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1300 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1302 /* Check for error conditions */
1303 errorstate = SDMMC_GetCmdResp5(SDMMCx, SDMMC_CMD_SDMMC_RW_EXTENDED, NULL);
1305 return errorstate;
1309 * @brief Execute a cmd5 to write or read multiple data with a single command
1310 * @param SDMMCx: Pointer to SDMMC register base
1311 * @param Argument: SDMMC command argument which is sent to a card as part of a command message
1312 * @retval SD Card error state
1314 uint32_t SDMMC_CmdSendOperationcondition(SDMMC_TypeDef *SDMMCx, uint32_t Argument, uint32_t *pResp)
1316 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1317 uint32_t errorstate;
1319 sdmmc_cmdinit.Argument = Argument;
1320 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SDMMC_SEN_OP_COND;
1321 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1322 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1323 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1324 (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1326 /* Check for error conditions */
1327 errorstate = SDMMC_GetCmdResp4(SDMMCx, pResp);
1329 return errorstate;
1332 * @}
1336 /** @defgroup HAL_SDMMC_LL_Group5 Responses management functions
1337 * @brief Responses functions
1339 @verbatim
1340 ===============================================================================
1341 ##### Responses management functions #####
1342 ===============================================================================
1343 [..]
1344 This subsection provides a set of functions allowing to manage the needed responses.
1346 @endverbatim
1347 * @{
1350 * @brief Checks for error conditions for R1 response.
1351 * @param hsd: SD handle
1352 * @param SD_CMD: The sent command index
1353 * @retval SD Card error state
1355 uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout)
1357 uint32_t response_r1;
1358 uint32_t sta_reg;
1360 /* 8 is the number of required instructions cycles for the below loop statement.
1361 The Timeout is expressed in ms */
1362 uint32_t count = Timeout * (SystemCoreClock / 8U / 1000U);
1366 if (count-- == 0U)
1368 return SDMMC_ERROR_TIMEOUT;
1370 sta_reg = SDMMCx->STA;
1371 } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT |
1372 SDMMC_FLAG_BUSYD0END)) == 0U) || ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));
1374 if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1376 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1378 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1380 else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
1382 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
1384 return SDMMC_ERROR_CMD_CRC_FAIL;
1386 else
1388 /* Nothing to do */
1391 /* Clear all the static flags */
1392 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1394 /* Check response received is of desired command */
1395 if (SDMMC_GetCommandResponse(SDMMCx) != SD_CMD)
1397 return SDMMC_ERROR_CMD_CRC_FAIL;
1400 /* We have received response, retrieve it for analysis */
1401 response_r1 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
1403 if ((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO)
1405 return SDMMC_ERROR_NONE;
1407 else if ((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE)
1409 return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
1411 else if ((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED)
1413 return SDMMC_ERROR_ADDR_MISALIGNED;
1415 else if ((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR)
1417 return SDMMC_ERROR_BLOCK_LEN_ERR;
1419 else if ((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR)
1421 return SDMMC_ERROR_ERASE_SEQ_ERR;
1423 else if ((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM)
1425 return SDMMC_ERROR_BAD_ERASE_PARAM;
1427 else if ((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION)
1429 return SDMMC_ERROR_WRITE_PROT_VIOLATION;
1431 else if ((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED)
1433 return SDMMC_ERROR_LOCK_UNLOCK_FAILED;
1435 else if ((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED)
1437 return SDMMC_ERROR_COM_CRC_FAILED;
1439 else if ((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD)
1441 return SDMMC_ERROR_ILLEGAL_CMD;
1443 else if ((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED)
1445 return SDMMC_ERROR_CARD_ECC_FAILED;
1447 else if ((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR)
1449 return SDMMC_ERROR_CC_ERR;
1451 else if ((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN)
1453 return SDMMC_ERROR_STREAM_READ_UNDERRUN;
1455 else if ((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN)
1457 return SDMMC_ERROR_STREAM_WRITE_OVERRUN;
1459 else if ((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE)
1461 return SDMMC_ERROR_CID_CSD_OVERWRITE;
1463 else if ((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP)
1465 return SDMMC_ERROR_WP_ERASE_SKIP;
1467 else if ((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED)
1469 return SDMMC_ERROR_CARD_ECC_DISABLED;
1471 else if ((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET)
1473 return SDMMC_ERROR_ERASE_RESET;
1475 else if ((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR)
1477 return SDMMC_ERROR_AKE_SEQ_ERR;
1479 else
1481 return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1486 * @brief Checks for error conditions for R2 (CID or CSD) response.
1487 * @param hsd: SD handle
1488 * @retval SD Card error state
1490 uint32_t SDMMC_GetCmdResp2(SDMMC_TypeDef *SDMMCx)
1492 uint32_t sta_reg;
1493 /* 8 is the number of required instructions cycles for the below loop statement.
1494 The SDMMC_CMDTIMEOUT is expressed in ms */
1495 uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U);
1499 if (count-- == 0U)
1501 return SDMMC_ERROR_TIMEOUT;
1503 sta_reg = SDMMCx->STA;
1504 } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1505 ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));
1507 if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1509 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1511 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1513 else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
1515 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
1517 return SDMMC_ERROR_CMD_CRC_FAIL;
1519 else
1521 /* No error flag set */
1522 /* Clear all the static flags */
1523 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1526 return SDMMC_ERROR_NONE;
1530 * @brief Checks for error conditions for R3 (OCR) response.
1531 * @param hsd: SD handle
1532 * @retval SD Card error state
1534 uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx)
1536 uint32_t sta_reg;
1537 /* 8 is the number of required instructions cycles for the below loop statement.
1538 The SDMMC_CMDTIMEOUT is expressed in ms */
1539 uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U);
1543 if (count-- == 0U)
1545 return SDMMC_ERROR_TIMEOUT;
1547 sta_reg = SDMMCx->STA;
1548 } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1549 ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));
1551 if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1553 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1555 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1557 else
1559 /* Clear all the static flags */
1560 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1563 return SDMMC_ERROR_NONE;
1567 * @brief Checks for error conditions for R4 response.
1568 * @param SDMMCx: Pointer to SDMMC register base
1569 * @param pResp: pointer to response
1570 * @retval error state
1572 uint32_t SDMMC_GetCmdResp4(SDMMC_TypeDef *SDMMCx, uint32_t *pResp)
1574 uint32_t sta_reg;
1576 /* 8 is the number of required instructions cycles for the below loop statement.
1577 The SDMMC_CMDTIMEOUT is expressed in ms */
1578 uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U);
1582 if (count-- == 0U)
1584 return SDMMC_ERROR_TIMEOUT;
1586 sta_reg = SDMMCx->STA;
1587 } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1588 ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));
1590 if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1592 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1594 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1596 else
1598 /* Clear all the static flags */
1599 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1602 /* Clear all the static flags */
1603 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1605 /* We have received response, retrieve it. */
1606 *pResp = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
1608 return SDMMC_ERROR_NONE;
1612 * @brief Checks for error conditions for R5 (cmd52/cmd53) response.
1613 * @param SDMMCx: Pointer to SDMMC register base
1614 * @param SDIO_CMD: The sent command index
1615 * @param pData: pointer to the read/write buffer needed for cmd52
1616 * @retval SDIO Card error state
1618 uint32_t SDMMC_GetCmdResp5(SDMMC_TypeDef *SDMMCx, uint8_t SDIO_CMD, uint8_t *pData)
1620 uint32_t response_r5;
1621 uint32_t sta_reg;
1623 /* 8 is the number of required instructions cycles for the below loop statement.
1624 The SDMMC_CMDTIMEOUT is expressed in ms */
1625 uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U);
1629 if (count-- == 0U)
1631 return SDMMC_ERROR_TIMEOUT;
1633 sta_reg = SDMMCx->STA;
1634 } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1635 ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));
1637 if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1639 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1641 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1643 else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
1645 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
1647 return SDMMC_ERROR_CMD_CRC_FAIL;
1649 else
1651 /* Nothing to do */
1654 /* Check response received is of desired command */
1655 if (SDMMC_GetCommandResponse(SDMMCx) != SDIO_CMD)
1657 return SDMMC_ERROR_CMD_CRC_FAIL;
1660 /* Clear all the static flags */
1661 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1663 /* We have received response, retrieve it. */
1664 response_r5 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
1666 if ((response_r5 & SDMMC_SDIO_R5_ERRORBITS) == SDMMC_ALLZERO)
1668 /* we only want 8 bit read or write data and the 8 bit response flags are masked in the data pointer */
1669 if (pData != NULL)
1671 *pData = (uint8_t)(response_r5 & 0xFFU);
1674 return SDMMC_ERROR_NONE;
1676 else if ((response_r5 & SDMMC_SDIO_R5_OUT_OF_RANGE) == SDMMC_SDIO_R5_OUT_OF_RANGE)
1678 return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
1680 else if ((response_r5 & SDMMC_SDIO_R5_INVALID_FUNCTION_NUMBER) == SDMMC_SDIO_R5_INVALID_FUNCTION_NUMBER)
1682 return SDMMC_ERROR_INVALID_PARAMETER;
1684 else if ((response_r5 & SDMMC_SDIO_R5_ILLEGAL_CMD) == SDMMC_SDIO_R5_ILLEGAL_CMD)
1686 return SDMMC_ERROR_ILLEGAL_CMD;
1688 else if ((response_r5 & SDMMC_SDIO_R5_COM_CRC_FAILED) == SDMMC_SDIO_R5_COM_CRC_FAILED)
1690 return SDMMC_ERROR_COM_CRC_FAILED;
1692 else
1694 return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1699 * @brief Checks for error conditions for R6 (RCA) response.
1700 * @param hsd: SD handle
1701 * @param SD_CMD: The sent command index
1702 * @param pRCA: Pointer to the variable that will contain the SD card relative
1703 * address RCA
1704 * @retval SD Card error state
1706 uint32_t SDMMC_GetCmdResp6(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint16_t *pRCA)
1708 uint32_t response_r1;
1709 uint32_t sta_reg;
1711 /* 8 is the number of required instructions cycles for the below loop statement.
1712 The SDMMC_CMDTIMEOUT is expressed in ms */
1713 uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U);
1717 if (count-- == 0U)
1719 return SDMMC_ERROR_TIMEOUT;
1721 sta_reg = SDMMCx->STA;
1722 } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1723 ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));
1725 if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1727 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1729 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1731 else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
1733 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
1735 return SDMMC_ERROR_CMD_CRC_FAIL;
1737 else
1739 /* Nothing to do */
1742 /* Check response received is of desired command */
1743 if (SDMMC_GetCommandResponse(SDMMCx) != SD_CMD)
1745 return SDMMC_ERROR_CMD_CRC_FAIL;
1748 /* Clear all the static flags */
1749 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1751 /* We have received response, retrieve it. */
1752 response_r1 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
1754 if ((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD |
1755 SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO)
1757 *pRCA = (uint16_t)(response_r1 >> 16);
1759 return SDMMC_ERROR_NONE;
1761 else if ((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD)
1763 return SDMMC_ERROR_ILLEGAL_CMD;
1765 else if ((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED)
1767 return SDMMC_ERROR_COM_CRC_FAILED;
1769 else
1771 return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1776 * @brief Checks for error conditions for R7 response.
1777 * @param hsd: SD handle
1778 * @retval SD Card error state
1780 uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx)
1782 uint32_t sta_reg;
1783 /* 8 is the number of required instructions cycles for the below loop statement.
1784 The SDMMC_CMDTIMEOUT is expressed in ms */
1785 uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U);
1789 if (count-- == 0U)
1791 return SDMMC_ERROR_TIMEOUT;
1793 sta_reg = SDMMCx->STA;
1794 } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1795 ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));
1797 if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1799 /* Card is not SD V2.0 compliant */
1800 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1802 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1805 else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
1807 /* Card is not SD V2.0 compliant */
1808 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
1810 return SDMMC_ERROR_CMD_CRC_FAIL;
1812 else
1814 /* Nothing to do */
1817 if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDREND))
1819 /* Card is SD V2.0 compliant */
1820 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND);
1823 return SDMMC_ERROR_NONE;
1828 * @}
1831 /* Private function ----------------------------------------------------------*/
1832 /** @addtogroup SD_Private_Functions
1833 * @{
1837 * @brief Checks for error conditions for CMD0.
1838 * @param hsd: SD handle
1839 * @retval SD Card error state
1841 static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx)
1843 /* 8 is the number of required instructions cycles for the below loop statement.
1844 The SDMMC_CMDTIMEOUT is expressed in ms */
1845 uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U);
1849 if (count-- == 0U)
1851 return SDMMC_ERROR_TIMEOUT;
1854 } while (!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDSENT));
1856 /* Clear all the static flags */
1857 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1859 return SDMMC_ERROR_NONE;
1863 * @}
1866 #endif /* HAL_SD_MODULE_ENABLED || HAL_MMC_MODULE_ENABLED */
1867 #endif /* SDMMC1 || SDMMC2 */
1869 * @}
1873 * @}