Increment eeprom version
[betaflight.git] / lib / main / STM32F1 / Drivers / STM32F1xx_HAL_Driver / Src / stm32f1xx_ll_sdmmc.c
blob4093d5cce40280ba01cf017c19e4078a3da4f8e4
1 /**
2 ******************************************************************************
3 * @file stm32f1xx_ll_sdmmc.c
4 * @author MCD Application Team
5 * @version V1.1.1
6 * @date 12-May-2017
7 * @brief SDIO Low Layer HAL module driver.
8 *
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
16 @verbatim
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
22 devices.
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
32 Rev1.1)
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 ==============================================================================
39 [..]
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.
48 [..]
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
57 peripheral.
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
71 __SDIO_DMA_DISABLE().
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:
79 (++) Command Argument
80 (++) Command Index
81 (++) Command Response type
82 (++) Command Wait
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 =======================
96 [..]
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:
100 (++) Data TimeOut
101 (++) Data Length
102 (++) Data Block size
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 ========================
116 [..]
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:
120 (++) Data TimeOut
121 (++) Data Length
122 (++) Data Block size
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 =====================================
136 [..]
137 (#) The commands used for Read/Write//Erase operations are managed in
138 separate functions.
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.
143 @endverbatim
144 ******************************************************************************
145 * @attention
147 * <h2><center>&copy; 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
181 * @{
184 /** @defgroup SDMMC_LL SDMMC Low Layer
185 * @brief Low layer module for SD
186 * @{
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
205 * @{
208 /** @defgroup HAL_SDMMC_LL_Group1 Initialization de-initialization functions
209 * @brief Initialization and Configuration functions
211 @verbatim
212 ===============================================================================
213 ##### Initialization/de-initialization functions #####
214 ===============================================================================
215 [..] This section provides functions allowing to:
217 @endverbatim
218 * @{
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
226 * @retval HAL status
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 |\
243 Init.ClockBypass |\
244 Init.ClockPowerSave |\
245 Init.BusWide |\
246 Init.HardwareFlowControl |\
247 Init.ClockDiv
250 /* Write to SDMMC CLKCR */
251 MODIFY_REG(SDIOx->CLKCR, CLKCR_CLEAR_MASK, tmpreg);
253 return HAL_OK;
258 * @}
261 /** @defgroup HAL_SDMMC_LL_Group2 IO operation functions
262 * @brief Data transfers functions
264 @verbatim
265 ===============================================================================
266 ##### I/O operation functions #####
267 ===============================================================================
268 [..]
269 This subsection provides a set of functions allowing to manage the SDMMC data
270 transfers.
272 @endverbatim
273 * @{
277 * @brief Read data (word) from Rx FIFO in blocking mode (polling)
278 * @param SDIOx: Pointer to SDMMC register base
279 * @retval HAL status
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
291 * @retval HAL status
293 HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData)
295 /* Write data to FIFO */
296 SDIOx->FIFO = *pWriteData;
298 return HAL_OK;
302 * @}
305 /** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions
306 * @brief management functions
308 @verbatim
309 ===============================================================================
310 ##### Peripheral Control functions #####
311 ===============================================================================
312 [..]
313 This subsection provides a set of functions allowing to control the SDMMC data
314 transfers.
316 @endverbatim
317 * @{
321 * @brief Set SDMMC Power state to ON.
322 * @param SDIOx: Pointer to SDMMC register base
323 * @retval HAL status
325 HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx)
327 /* Set power state to ON */
328 SDIOx->POWER = SDIO_POWER_PWRCTRL;
330 return HAL_OK;
334 * @brief Set SDMMC Power state to OFF.
335 * @param SDIOx: Pointer to SDMMC register base
336 * @retval HAL status
338 HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx)
340 /* Set power state to OFF */
341 SDIOx->POWER = 0x00000000U;
343 return HAL_OK;
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
350 * following values:
351 * - 0x00: Power OFF
352 * - 0x02: Power UP
353 * - 0x03: Power ON
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
366 * @retval HAL status
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 |\
383 Command->Response |\
384 Command->WaitForInterrupt |\
385 Command->CPSM);
387 /* Write to SDMMC CMD register */
388 MODIFY_REG(SDIOx->CMD, CMD_CLEAR_MASK, tmpreg);
390 return HAL_OK;
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.
434 * @retval HAL status
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 |\
455 Data->TransferDir |\
456 Data->TransferMode |\
457 Data->DPSM);
459 /* Write to SDMMC DCTRL */
460 MODIFY_REG(SDIOx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);
462 return HAL_OK;
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
493 * @retval None
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);
503 return HAL_OK;
507 * @}
511 /** @defgroup HAL_SDMMC_LL_Group4 Command management functions
512 * @brief Data transfers functions
514 @verbatim
515 ===============================================================================
516 ##### Commands management functions #####
517 ===============================================================================
518 [..]
519 This subsection provides a set of functions allowing to manage the needed commands.
521 @endverbatim
522 * @{
526 * @brief Send the Data Block Lenght command and check the response
527 * @param SDIOx: Pointer to SDMMC register base
528 * @retval HAL status
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);
546 return errorstate;
550 * @brief Send the Read Single Block command and check the response
551 * @param SDIOx: Pointer to SDMMC register base
552 * @retval HAL status
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);
570 return errorstate;
574 * @brief Send the Read Multi Block command and check the response
575 * @param SDIOx: Pointer to SDIO register base
576 * @retval HAL status
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);
594 return errorstate;
598 * @brief Send the Write Single Block command and check the response
599 * @param SDIOx: Pointer to SDIO register base
600 * @retval HAL status
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);
618 return errorstate;
622 * @brief Send the Write Multi Block command and check the response
623 * @param SDIOx: Pointer to SDIO register base
624 * @retval HAL status
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);
642 return errorstate;
646 * @brief Send the Start Address Erase command for SD and check the response
647 * @param SDIOx: Pointer to SDIO register base
648 * @retval HAL status
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);
666 return errorstate;
670 * @brief Send the End Address Erase command for SD and check the response
671 * @param SDIOx: Pointer to SDIO register base
672 * @retval HAL status
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);
690 return errorstate;
694 * @brief Send the Start Address Erase command and check the response
695 * @param SDIOx: Pointer to SDIO register base
696 * @retval HAL status
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);
714 return errorstate;
718 * @brief Send the End Address Erase command and check the response
719 * @param SDIOx: Pointer to SDIO register base
720 * @retval HAL status
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);
738 return errorstate;
742 * @brief Send the Erase command and check the response
743 * @param SDIOx: Pointer to SDIO register base
744 * @retval HAL status
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);
762 return errorstate;
766 * @brief Send the Stop Transfer command and check the response.
767 * @param SDIOx: Pointer to SDIO register base
768 * @retval HAL status
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);
786 return errorstate;
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
793 * @retval HAL status
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);
811 return errorstate;
815 * @brief Send the Go Idle State command and check the response.
816 * @param SDIOx: Pointer to SDIO register base
817 * @retval HAL status
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);
834 return errorstate;
838 * @brief Send the Operating Condition command and check the response.
839 * @param SDIOx: Pointer to SDIO register base
840 * @retval HAL status
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);
862 return errorstate;
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
870 * @retval HAL status
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)
887 or SD card 1.x */
888 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_CMD, SDIO_CMDTIMEOUT);
890 return errorstate;
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
897 * @retval HAL status
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);
914 return errorstate;
918 * @brief Send the Bus Width command and check the response.
919 * @param SDIOx: Pointer to SDIO register base
920 * @retval HAL status
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);
937 return errorstate;
941 * @brief Send the Send SCR command and check the response.
942 * @param SDIOx: Pointer to SDMMC register base
943 * @retval HAL status
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);
961 return errorstate;
965 * @brief Send the Send CID command and check the response.
966 * @param SDIOx: Pointer to SDIO register base
967 * @retval HAL status
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);
985 return errorstate;
989 * @brief Send the Send CSD command and check the response.
990 * @param SDIOx: Pointer to SDIO register base
991 * @retval HAL status
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);
1009 return errorstate;
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);
1033 return errorstate;
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);
1056 return errorstate;
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);
1079 return errorstate;
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);
1104 return errorstate;
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);
1128 return errorstate;
1132 * @}
1135 /* Private function ----------------------------------------------------------*/
1136 /** @addtogroup SD_Private_Functions
1137 * @{
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);
1153 if (count-- == 0U)
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);
1182 if (count-- == 0U)
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;
1290 else
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);
1309 if (count-- == 0U)
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;
1328 else
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);
1351 if (count-- == 0U)
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;
1364 else
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
1379 * address RCA
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);
1392 if (count-- == 0U)
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;
1438 else
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);
1457 if (count-- == 0U)
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;
1483 * @}
1487 * @}
1490 #endif /* STM32F103xE || STM32F103xG */
1492 #endif /* (HAL_SD_MODULE_ENABLED) || (HAL_MMC_MODULE_ENABLED) */
1495 * @}
1499 * @}
1502 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/