Fix SD card corruption due to not waiting for SD to leave the programming state
[SCSI2SD-V6.git] / STM32CubeMX / 2021 / Drivers / STM32F4xx_HAL_Driver / Src / stm32f4xx_ll_sdmmc.c
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_ll_sdmmc.c
4   * @author  MCD Application Team
5   * @brief   SDMMC Low Layer HAL module driver.
6   *    
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
13   *         
14   @verbatim
15   ==============================================================================
16                        ##### SDMMC peripheral features #####
17   ==============================================================================        
18     [..] The SD/SDMMC MMC card host interface (SDMMC) provides an interface between the AHB
19          peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDMMC cards and CE-ATA
20          devices.
21     
22     [..] The SDMMC features include the following:
23          (+) Full compliance with MultiMedia Card System Specification Version 4.2. Card support
24              for three different databus modes: 1-bit (default), 4-bit and 8-bit
25          (+) Full compatibility with previous versions of MultiMedia Cards (forward compatibility)
26          (+) Full compliance with SD Memory Card Specifications Version 2.0
27          (+) Full compliance with SD I/O Card Specification Version 2.0: card support for two
28              different data bus modes: 1-bit (default) and 4-bit
29          (+) Full support of the CE-ATA features (full compliance with CE-ATA digital protocol
30              Rev1.1)
31          (+) Data transfer up to 48 MHz for the 8 bit mode
32          (+) Data and command output enable signals to control external bidirectional drivers
33    
34                            ##### How to use this driver #####
35   ==============================================================================
36     [..]
37       This driver is a considered as a driver of service for external devices drivers 
38       that interfaces with the SDMMC peripheral.
39       According to the device used (SD card/ MMC card / SDMMC card ...), a set of APIs 
40       is used in the device's driver to perform SDMMC operations and functionalities.
41    
42       This driver is almost transparent for the final user, it is only used to implement other
43       functionalities of the external device.
44    
45     [..]
46       (+) The SDMMC clock (SDMMCCLK = 48 MHz) is coming from a specific output (MSI, PLLUSB1CLK,
47           PLLUSB2CLK). Before start working with SDMMC peripheral make sure that the
48           PLL is well configured.
49           The SDMMC peripheral uses two clock signals:
50           (++) SDMMC adapter clock (SDMMCCLK = 48 MHz)
51           (++) APB2 bus clock (PCLK2)
52        
53           -@@- PCLK2 and SDMMC_CK clock frequencies must respect the following condition:
54                Frequency(PCLK2) >= (3 / 8 x Frequency(SDMMC_CK))
55   
56       (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDMMC
57           peripheral.
58
59       (+) Enable the Power ON State using the SDIO_PowerState_ON() 
60           function and disable it using the function SDIO_PowerState_OFF().
61                 
62       (+) Enable/Disable the clock using the __SDIO_ENABLE()/__SDIO_DISABLE() macros.
63   
64       (+) Enable/Disable the peripheral interrupts using the macros __SDIO_ENABLE_IT() 
65           and __SDIO_DISABLE_IT() if you need to use interrupt mode. 
66   
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().
72   
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).
84   
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.
89   
90       (+) To control the DPSM (Data Path State Machine) and send/receive 
91            data to/from the card use the SDIO_DataConfig(), SDIO_GetDataCounter(), 
92           SDIO_ReadFIFO(), SDIO_WriteFIFO() and SDIO_GetFIFOCount() functions.
93   
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)
106                                      
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).
109   
110       (#) Send the selected Read command (refer to step 11).
111                     
112       (#) Use the SDIO flags/interrupts to check the transfer status.
113   
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)
126   
127      (#) Configure the SDMMC resources to send the data to the card according to 
128          selected transfer mode.
129                      
130      (#) Send the selected Write command.
131                     
132      (#) Use the SDIO flags/interrupts to check the transfer status.
133        
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.
142   
143   @endverbatim
144   ******************************************************************************
145   * @attention
146   *
147   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
148   * All rights reserved.</center></h2>
149   *
150   * This software component is licensed by ST under BSD 3-Clause license,
151   * the "License"; You may not use this file except in compliance with the
152   * License. You may obtain a copy of the License at:
153   *                       opensource.org/licenses/BSD-3-Clause
154   *
155   ******************************************************************************
156   */ 
157
158 /* Includes ------------------------------------------------------------------*/
159 #include "stm32f4xx_hal.h"
160
161 #if defined(SDIO)
162
163 /** @addtogroup STM32F4xx_HAL_Driver
164   * @{
165   */
166
167 /** @defgroup SDMMC_LL SDMMC Low Layer
168   * @brief Low layer module for SD
169   * @{
170   */
171
172 #if defined(HAL_SD_MODULE_ENABLED) || defined(HAL_MMC_MODULE_ENABLED)
173
174 /* Private typedef -----------------------------------------------------------*/
175 /* Private define ------------------------------------------------------------*/
176 /* Private macro -------------------------------------------------------------*/
177 /* Private variables ---------------------------------------------------------*/
178 /* Private function prototypes -----------------------------------------------*/
179 static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx);
180 static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout);
181 static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx);
182 static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx);
183 static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx);
184 static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA);
185
186 /* Exported functions --------------------------------------------------------*/
187
188 /** @defgroup SDMMC_LL_Exported_Functions SDMMC Low Layer Exported Functions
189   * @{
190   */
191
192 /** @defgroup HAL_SDMMC_LL_Group1 Initialization de-initialization functions 
193  *  @brief    Initialization and Configuration functions 
194  *
195 @verbatim    
196  ===============================================================================
197               ##### Initialization/de-initialization functions #####
198  ===============================================================================
199     [..]  This section provides functions allowing to:
200  
201 @endverbatim
202   * @{
203   */
204
205 /**
206   * @brief  Initializes the SDMMC according to the specified
207   *         parameters in the SDMMC_InitTypeDef and create the associated handle.
208   * @param  SDIOx: Pointer to SDMMC register base
209   * @param  Init: SDMMC initialization structure   
210   * @retval HAL status
211   */
212 HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init)
213 {
214   uint32_t tmpreg = 0;
215
216   /* Check the parameters */
217   assert_param(IS_SDIO_ALL_INSTANCE(SDIOx));
218   assert_param(IS_SDIO_CLOCK_EDGE(Init.ClockEdge)); 
219   assert_param(IS_SDIO_CLOCK_BYPASS(Init.ClockBypass));
220   assert_param(IS_SDIO_CLOCK_POWER_SAVE(Init.ClockPowerSave));
221   assert_param(IS_SDIO_BUS_WIDE(Init.BusWide));
222   assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl));
223   assert_param(IS_SDIO_CLKDIV(Init.ClockDiv));
224   
225   /* Set SDMMC configuration parameters */
226   tmpreg |= (Init.ClockEdge           |\
227              Init.ClockBypass         |\
228              Init.ClockPowerSave      |\
229              Init.BusWide             |\
230              Init.HardwareFlowControl |\
231              Init.ClockDiv
232              ); 
233   
234   /* Write to SDMMC CLKCR */
235   MODIFY_REG(SDIOx->CLKCR, CLKCR_CLEAR_MASK, tmpreg);  
236
237   return HAL_OK;
238 }
239
240
241 /**
242   * @}
243   */
244
245 /** @defgroup HAL_SDMMC_LL_Group2 IO operation functions 
246  *  @brief   Data transfers functions 
247  *
248 @verbatim   
249  ===============================================================================
250                       ##### I/O operation functions #####
251  ===============================================================================  
252     [..]
253     This subsection provides a set of functions allowing to manage the SDMMC data 
254     transfers.
255
256 @endverbatim
257   * @{
258   */
259
260 /**
261   * @brief  Read data (word) from Rx FIFO in blocking mode (polling) 
262   * @param  SDIOx: Pointer to SDMMC register base
263   * @retval HAL status
264   */
265 uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx)
266 {
267   /* Read data from Rx FIFO */ 
268   return (SDIOx->FIFO);
269 }
270
271 /**
272   * @brief  Write data (word) to Tx FIFO in blocking mode (polling) 
273   * @param  SDIOx: Pointer to SDMMC register base
274   * @param  pWriteData: pointer to data to write
275   * @retval HAL status
276   */
277 HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData)
278
279   /* Write data to FIFO */ 
280   SDIOx->FIFO = *pWriteData;
281
282   return HAL_OK;
283 }
284
285 /**
286   * @}
287   */
288
289 /** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions 
290  *  @brief   management functions 
291  *
292 @verbatim   
293  ===============================================================================
294                       ##### Peripheral Control functions #####
295  ===============================================================================  
296     [..]
297     This subsection provides a set of functions allowing to control the SDMMC data 
298     transfers.
299
300 @endverbatim
301   * @{
302   */
303
304 /**
305   * @brief  Set SDMMC Power state to ON. 
306   * @param  SDIOx: Pointer to SDMMC register base
307   * @retval HAL status
308   */
309 HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx)
310 {  
311   /* Set power state to ON */ 
312   SDIOx->POWER = SDIO_POWER_PWRCTRL;
313
314   /* 1ms: required power up waiting time before starting the SD initialization
315   sequence */
316   HAL_Delay(2);
317   
318   return HAL_OK;
319 }
320
321 /**
322   * @brief  Set SDMMC Power state to OFF. 
323   * @param  SDIOx: Pointer to SDMMC register base
324   * @retval HAL status
325   */
326 HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx)
327 {
328   /* Set power state to OFF */
329   SDIOx->POWER = (uint32_t)0x00000000;
330   
331   return HAL_OK;
332 }
333
334 /**
335   * @brief  Get SDMMC Power state. 
336   * @param  SDIOx: Pointer to SDMMC register base
337   * @retval Power status of the controller. The returned value can be one of the 
338   *         following values:
339   *            - 0x00: Power OFF
340   *            - 0x02: Power UP
341   *            - 0x03: Power ON 
342   */
343 uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx)  
344 {
345   return (SDIOx->POWER & SDIO_POWER_PWRCTRL);
346 }
347
348 /**
349   * @brief  Configure the SDMMC command path according to the specified parameters in
350   *         SDIO_CmdInitTypeDef structure and send the command 
351   * @param  SDIOx: Pointer to SDMMC register base
352   * @param  Command: pointer to a SDIO_CmdInitTypeDef structure that contains 
353   *         the configuration information for the SDMMC command
354   * @retval HAL status
355   */
356 HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command)
357 {
358   uint32_t tmpreg = 0;
359   
360   /* Check the parameters */
361   assert_param(IS_SDIO_CMD_INDEX(Command->CmdIndex));
362   assert_param(IS_SDIO_RESPONSE(Command->Response));
363   assert_param(IS_SDIO_WAIT(Command->WaitForInterrupt));
364   assert_param(IS_SDIO_CPSM(Command->CPSM));
365
366   /* Set the SDMMC Argument value */
367   SDIOx->ARG = Command->Argument;
368
369   /* Set SDMMC command parameters */
370   tmpreg |= (uint32_t)(Command->CmdIndex         |\
371                        Command->Response         |\
372                        Command->WaitForInterrupt |\
373                        Command->CPSM);
374   
375   /* Write to SDMMC CMD register */
376   MODIFY_REG(SDIOx->CMD, CMD_CLEAR_MASK, tmpreg); 
377   
378   return HAL_OK;  
379 }
380
381 /**
382   * @brief  Return the command index of last command for which response received
383   * @param  SDIOx: Pointer to SDMMC register base
384   * @retval Command index of the last command response received
385   */
386 uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx)
387 {
388   return (uint8_t)(SDIOx->RESPCMD);
389 }
390
391
392 /**
393   * @brief  Return the response received from the card for the last command
394   * @param  SDIOx: Pointer to SDMMC register base    
395   * @param  Response: Specifies the SDMMC response register. 
396   *          This parameter can be one of the following values:
397   *            @arg SDIO_RESP1: Response Register 1
398   *            @arg SDIO_RESP2: Response Register 2
399   *            @arg SDIO_RESP3: Response Register 3
400   *            @arg SDIO_RESP4: Response Register 4  
401   * @retval The Corresponding response register value
402   */
403 uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response)
404 {
405   uint32_t tmp;
406
407   /* Check the parameters */
408   assert_param(IS_SDIO_RESP(Response));
409   
410   /* Get the response */
411   tmp = (uint32_t)(&(SDIOx->RESP1)) + Response;
412   
413   return (*(__IO uint32_t *) tmp);
414 }  
415
416 /**
417   * @brief  Configure the SDMMC data path according to the specified 
418   *         parameters in the SDIO_DataInitTypeDef.
419   * @param  SDIOx: Pointer to SDIO register base  
420   * @param  Data : pointer to a SDIO_DataInitTypeDef structure 
421   *         that contains the configuration information for the SDMMC data.
422   * @retval HAL status
423   */
424 HAL_StatusTypeDef SDIO_ConfigData(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* Data)
425 {
426   uint32_t tmpreg = 0;
427   
428   /* Check the parameters */
429   assert_param(IS_SDIO_DATA_LENGTH(Data->DataLength));
430   assert_param(IS_SDIO_BLOCK_SIZE(Data->DataBlockSize));
431   assert_param(IS_SDIO_TRANSFER_DIR(Data->TransferDir));
432   assert_param(IS_SDIO_TRANSFER_MODE(Data->TransferMode));
433   assert_param(IS_SDIO_DPSM(Data->DPSM));
434
435   /* Set the SDMMC Data TimeOut value */
436   SDIOx->DTIMER = Data->DataTimeOut;
437
438   /* Set the SDMMC DataLength value */
439   SDIOx->DLEN = Data->DataLength;
440
441   /* Set the SDMMC data configuration parameters */
442   tmpreg |= (uint32_t)(Data->DataBlockSize |\
443                        Data->TransferDir   |\
444                        Data->TransferMode  |\
445                        Data->DPSM);
446   
447   /* Write to SDMMC DCTRL */
448   MODIFY_REG(SDIOx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);
449
450   return HAL_OK;
451
452 }
453
454 /**
455   * @brief  Returns number of remaining data bytes to be transferred.
456   * @param  SDIOx: Pointer to SDIO register base
457   * @retval Number of remaining data bytes to be transferred
458   */
459 uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx)
460 {
461   return (SDIOx->DCOUNT);
462 }
463
464 /**
465   * @brief  Get the FIFO data
466   * @param  SDIOx: Pointer to SDIO register base 
467   * @retval Data received
468   */
469 uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx)
470 {
471   return (SDIOx->FIFO);
472 }
473
474 /**
475   * @brief  Sets one of the two options of inserting read wait interval.
476   * @param  SDIOx: Pointer to SDIO register base   
477   * @param  SDIO_ReadWaitMode: SDMMC Read Wait operation mode.
478   *          This parameter can be:
479   *            @arg SDIO_READ_WAIT_MODE_CLK: Read Wait control by stopping SDMMCCLK
480   *            @arg SDIO_READ_WAIT_MODE_DATA2: Read Wait control using SDMMC_DATA2
481   * @retval None
482   */
483 HAL_StatusTypeDef SDIO_SetSDMMCReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode)
484 {
485   /* Check the parameters */
486   assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode));
487
488   /* Set SDMMC read wait mode */
489   MODIFY_REG(SDIOx->DCTRL, SDIO_DCTRL_RWMOD, SDIO_ReadWaitMode);
490   
491   return HAL_OK;  
492 }
493
494 /**
495   * @}
496   */
497
498
499 /** @defgroup HAL_SDMMC_LL_Group4 Command management functions 
500  *  @brief   Data transfers functions 
501  *
502 @verbatim   
503  ===============================================================================
504                    ##### Commands management functions #####
505  ===============================================================================  
506     [..]
507     This subsection provides a set of functions allowing to manage the needed commands.
508
509 @endverbatim
510   * @{
511   */
512
513 /**
514   * @brief  Send the Data Block Lenght command and check the response
515   * @param  SDIOx: Pointer to SDIO register base 
516   * @retval HAL status
517   */
518 uint32_t SDMMC_CmdBlockLength(SDIO_TypeDef *SDIOx, uint32_t BlockSize)
519 {
520   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
521   uint32_t errorstate;
522   
523   /* Set Block Size for Card */ 
524   sdmmc_cmdinit.Argument         = (uint32_t)BlockSize;
525   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SET_BLOCKLEN;
526   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
527   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
528   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
529   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
530   
531   /* Check for error conditions */
532   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SET_BLOCKLEN, SDIO_CMDTIMEOUT);
533
534   return errorstate;
535 }
536
537 /**
538   * @brief  Send the Read Single Block command and check the response
539   * @param  SDIOx: Pointer to SDIO register base 
540   * @retval HAL status
541   */
542 uint32_t SDMMC_CmdReadSingleBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
543 {
544   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
545   uint32_t errorstate;
546   
547   /* Set Block Size for Card */ 
548   sdmmc_cmdinit.Argument         = (uint32_t)ReadAdd;
549   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_READ_SINGLE_BLOCK;
550   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
551   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
552   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
553   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
554   
555   /* Check for error conditions */
556   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
557
558   return errorstate;
559 }
560
561 /**
562   * @brief  Send the Read Multi Block command and check the response
563   * @param  SDIOx: Pointer to SDIO register base 
564   * @retval HAL status
565   */
566 uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
567 {
568   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
569   uint32_t errorstate;
570   
571   /* Set Block Size for Card */ 
572   sdmmc_cmdinit.Argument         = (uint32_t)ReadAdd;
573   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_READ_MULT_BLOCK;
574   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
575   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
576   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
577   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
578   
579   /* Check for error conditions */
580   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_MULT_BLOCK, SDIO_CMDTIMEOUT);
581
582   return errorstate;
583 }
584
585 /**
586   * @brief  Send the Write Single Block command and check the response
587   * @param  SDIOx: Pointer to SDIO register base 
588   * @retval HAL status
589   */
590 uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
591 {
592   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
593   uint32_t errorstate;
594   
595   /* Set Block Size for Card */ 
596   sdmmc_cmdinit.Argument         = (uint32_t)WriteAdd;
597   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_WRITE_SINGLE_BLOCK;
598   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
599   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
600   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
601   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
602   
603   /* Check for error conditions */
604   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
605
606   return errorstate;
607 }
608
609 /**
610   * @brief  Set the count of a multi-block write command
611   * @param  SDIOx: Pointer to SDIO register base 
612   * @retval HAL status
613   */
614 uint32_t SDMMC_CmdSetBlockCount(SDIO_TypeDef *SDIOx, uint32_t appCmdArg, uint32_t blockCount)
615 {
616   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
617   uint32_t errorstate;
618   
619   errorstate = SDMMC_CmdAppCommand(SDIOx, appCmdArg);
620   if(errorstate == HAL_SD_ERROR_NONE)
621   {
622     sdmmc_cmdinit.Argument         = blockCount;
623     sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SET_BLOCK_COUNT;
624     sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
625     sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
626     sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
627     (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
628     errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SET_BLOCK_COUNT, SDIO_CMDTIMEOUT);
629   }
630
631   return errorstate;
632 }
633
634 /**
635   * @brief  Send the Write Multi Block command and check the response
636   * @param  SDIOx: Pointer to SDIO register base 
637   * @retval HAL status
638   */
639 uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
640 {
641   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
642   uint32_t errorstate;
643   
644   /* Set Block Size for Card */ 
645   sdmmc_cmdinit.Argument         = (uint32_t)WriteAdd;
646   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_WRITE_MULT_BLOCK;
647   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
648   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
649   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
650   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
651   
652   /* Check for error conditions */
653   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_MULT_BLOCK, SDIO_CMDTIMEOUT);
654
655   return errorstate;
656 }
657
658 /**
659   * @brief  Send the Start Address Erase command for SD and check the response
660   * @param  SDIOx: Pointer to SDIO register base 
661   * @retval HAL status
662   */
663 uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
664 {
665   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
666   uint32_t errorstate;
667   
668   /* Set Block Size for Card */ 
669   sdmmc_cmdinit.Argument         = (uint32_t)StartAdd;
670   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_ERASE_GRP_START;
671   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
672   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
673   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
674   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
675   
676   /* Check for error conditions */
677   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
678
679   return errorstate;
680 }
681
682 /**
683   * @brief  Send the End Address Erase command for SD and check the response
684   * @param  SDIOx: Pointer to SDIO register base 
685   * @retval HAL status
686   */
687 uint32_t SDMMC_CmdSDEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
688 {
689   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
690   uint32_t errorstate;
691   
692   /* Set Block Size for Card */ 
693   sdmmc_cmdinit.Argument         = (uint32_t)EndAdd;
694   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_ERASE_GRP_END;
695   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
696   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
697   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
698   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
699   
700   /* Check for error conditions */
701   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
702
703   return errorstate;
704 }
705
706 /**
707   * @brief  Send the Start Address Erase command and check the response
708   * @param  SDIOx: Pointer to SDIO register base 
709   * @retval HAL status
710   */
711 uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
712 {
713   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
714   uint32_t errorstate;
715   
716   /* Set Block Size for Card */ 
717   sdmmc_cmdinit.Argument         = (uint32_t)StartAdd;
718   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ERASE_GRP_START;
719   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
720   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
721   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
722   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
723   
724   /* Check for error conditions */
725   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
726
727   return errorstate;
728 }
729
730 /**
731   * @brief  Send the End Address Erase command and check the response
732   * @param  SDIOx: Pointer to SDIO register base 
733   * @retval HAL status
734   */
735 uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
736 {
737   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
738   uint32_t errorstate;
739   
740   /* Set Block Size for Card */ 
741   sdmmc_cmdinit.Argument         = (uint32_t)EndAdd;
742   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ERASE_GRP_END;
743   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
744   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
745   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
746   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
747   
748   /* Check for error conditions */
749   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
750
751   return errorstate;
752 }
753
754 /**
755   * @brief  Send the Erase command and check the response
756   * @param  SDIOx: Pointer to SDIO register base 
757   * @retval HAL status
758   */
759 uint32_t SDMMC_CmdErase(SDIO_TypeDef *SDIOx)
760 {
761   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
762   uint32_t errorstate;
763   
764   /* Set Block Size for Card */ 
765   sdmmc_cmdinit.Argument         = 0U;
766   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ERASE;
767   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
768   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
769   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
770   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
771   
772   /* Check for error conditions */
773   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE, SDIO_MAXERASETIMEOUT);
774
775   return errorstate;
776 }
777
778 /**
779   * @brief  Send the Stop Transfer command and check the response.
780   * @param  SDIOx: Pointer to SDIO register base 
781   * @retval HAL status
782   */
783 uint32_t SDMMC_CmdStopTransfer(SDIO_TypeDef *SDIOx)
784 {
785   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
786   uint32_t errorstate;
787   
788   /* Send CMD12 STOP_TRANSMISSION  */
789   sdmmc_cmdinit.Argument         = 0U;
790   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_STOP_TRANSMISSION;
791   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
792   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
793   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
794   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
795   
796   /* Check for error conditions */
797   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_STOP_TRANSMISSION, SDIO_STOPTRANSFERTIMEOUT);
798
799   return errorstate;
800 }
801
802 /**
803   * @brief  Send the Select Deselect command and check the response.
804   * @param  SDIOx: Pointer to SDIO register base 
805   * @param  addr: Address of the card to be selected  
806   * @retval HAL status
807   */
808 uint32_t SDMMC_CmdSelDesel(SDIO_TypeDef *SDIOx, uint64_t Addr)
809 {
810   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
811   uint32_t errorstate;
812   
813   /* Send CMD7 SDMMC_SEL_DESEL_CARD */
814   sdmmc_cmdinit.Argument         = (uint32_t)Addr;
815   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEL_DESEL_CARD;
816   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
817   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
818   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
819   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
820   
821   /* Check for error conditions */
822   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEL_DESEL_CARD, SDIO_CMDTIMEOUT);
823
824   return errorstate;
825 }
826
827 /**
828   * @brief  Send the Go Idle State command and check the response.
829   * @param  SDIOx: Pointer to SDIO register base 
830   * @retval HAL status
831   */
832 uint32_t SDMMC_CmdGoIdleState(SDIO_TypeDef *SDIOx)
833 {
834   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
835   uint32_t errorstate;
836   
837   sdmmc_cmdinit.Argument         = 0U;
838   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_GO_IDLE_STATE;
839   sdmmc_cmdinit.Response         = SDIO_RESPONSE_NO;
840   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
841   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
842   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
843   
844   /* Check for error conditions */
845   errorstate = SDMMC_GetCmdError(SDIOx);
846
847   return errorstate;
848 }
849
850 /**
851   * @brief  Send the Operating Condition command and check the response.
852   * @param  SDIOx: Pointer to SDIO register base 
853   * @retval HAL status
854   */
855 uint32_t SDMMC_CmdOperCond(SDIO_TypeDef *SDIOx)
856 {
857   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
858   uint32_t errorstate;
859   
860   /* Send CMD8 to verify SD card interface operating condition */
861   /* Argument: - [31:12]: Reserved (shall be set to '0')
862   - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
863   - [7:0]: Check Pattern (recommended 0xAA) */
864   /* CMD Response: R7 */
865   sdmmc_cmdinit.Argument         = SDMMC_CHECK_PATTERN;
866   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_HS_SEND_EXT_CSD;
867   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
868   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
869   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
870   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
871   
872   /* Check for error conditions */
873   errorstate = SDMMC_GetCmdResp7(SDIOx);
874
875   return errorstate;
876 }
877
878 /**
879   * @brief  Send the Application command to verify that that the next command 
880   *         is an application specific com-mand rather than a standard command
881   *         and check the response.
882   * @param  SDIOx: Pointer to SDIO register base 
883   * @param  Argument: Command Argument 
884   * @retval HAL status
885   */
886 uint32_t SDMMC_CmdAppCommand(SDIO_TypeDef *SDIOx, uint32_t Argument)
887 {
888   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
889   uint32_t errorstate;
890   
891   sdmmc_cmdinit.Argument         = (uint32_t)Argument;
892   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_APP_CMD;
893   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
894   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
895   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
896   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
897   
898   /* Check for error conditions */
899   /* If there is a HAL_ERROR, it is a MMC card, else
900   it is a SD card: SD card 2.0 (voltage range mismatch)
901      or SD card 1.x */
902   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_CMD, SDIO_CMDTIMEOUT);
903
904   return errorstate;
905 }
906
907 /**
908   * @brief  Send the command asking the accessed card to send its operating 
909   *         condition register (OCR)
910   * @param  SDIOx: Pointer to SDIO register base 
911   * @param  Argument: Command Argument
912   * @retval HAL status
913   */
914 uint32_t SDMMC_CmdAppOperCommand(SDIO_TypeDef *SDIOx, uint32_t Argument)
915 {
916   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
917   uint32_t errorstate;
918   
919   sdmmc_cmdinit.Argument         = SDMMC_VOLTAGE_WINDOW_SD | Argument;
920   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_APP_OP_COND;
921   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
922   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
923   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
924   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
925   
926   /* Check for error conditions */
927   errorstate = SDMMC_GetCmdResp3(SDIOx);
928
929   return errorstate;
930 }
931
932 /**
933   * @brief  Send the Bus Width command and check the response.
934   * @param  SDIOx: Pointer to SDIO register base 
935   * @param  BusWidth: BusWidth
936   * @retval HAL status
937   */
938 uint32_t SDMMC_CmdBusWidth(SDIO_TypeDef *SDIOx, uint32_t BusWidth)
939 {
940   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
941   uint32_t errorstate;
942   
943   sdmmc_cmdinit.Argument         = (uint32_t)BusWidth;
944   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_APP_SD_SET_BUSWIDTH;
945   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
946   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
947   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
948   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
949   
950   /* Check for error conditions */
951   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDIO_CMDTIMEOUT);
952
953   return errorstate;
954 }
955
956 /**
957   * @brief  Send the Send SCR command and check the response.
958   * @param  SDIOx: Pointer to SDIO register base 
959   * @retval HAL status
960   */
961 uint32_t SDMMC_CmdSendSCR(SDIO_TypeDef *SDIOx)
962 {
963   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
964   uint32_t errorstate;
965   
966   /* Send CMD51 SD_APP_SEND_SCR */
967   sdmmc_cmdinit.Argument         = 0U;
968   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_APP_SEND_SCR;
969   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
970   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
971   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
972   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
973   
974   /* Check for error conditions */
975   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_SEND_SCR, SDIO_CMDTIMEOUT);
976
977   return errorstate;
978 }
979
980 /**
981   * @brief  Send the Send CID command and check the response.
982   * @param  SDIOx: Pointer to SDIO register base 
983   * @retval HAL status
984   */
985 uint32_t SDMMC_CmdSendCID(SDIO_TypeDef *SDIOx)
986 {
987   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
988   uint32_t errorstate;
989   
990   /* Send CMD2 ALL_SEND_CID */
991   sdmmc_cmdinit.Argument         = 0U;
992   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ALL_SEND_CID;
993   sdmmc_cmdinit.Response         = SDIO_RESPONSE_LONG;
994   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
995   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
996   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
997   
998   /* Check for error conditions */
999   errorstate = SDMMC_GetCmdResp2(SDIOx);
1000
1001   return errorstate;
1002 }
1003
1004 /**
1005   * @brief  Send the Send CSD command and check the response.
1006   * @param  SDIOx: Pointer to SDIO register base 
1007   * @param  Argument: Command Argument
1008   * @retval HAL status
1009   */
1010 uint32_t SDMMC_CmdSendCSD(SDIO_TypeDef *SDIOx, uint32_t Argument)
1011 {
1012   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1013   uint32_t errorstate;
1014   
1015   /* Send CMD9 SEND_CSD */
1016   sdmmc_cmdinit.Argument         = Argument;
1017   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEND_CSD;
1018   sdmmc_cmdinit.Response         = SDIO_RESPONSE_LONG;
1019   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1020   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1021   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1022   
1023   /* Check for error conditions */
1024   errorstate = SDMMC_GetCmdResp2(SDIOx);
1025
1026   return errorstate;
1027 }
1028
1029 /**
1030   * @brief  Send the Send CSD command and check the response.
1031   * @param  SDIOx: Pointer to SDIO register base 
1032   * @param  pRCA: Card RCA  
1033   * @retval HAL status
1034   */
1035 uint32_t SDMMC_CmdSetRelAdd(SDIO_TypeDef *SDIOx, uint16_t *pRCA)
1036 {
1037   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1038   uint32_t errorstate;
1039   
1040   /* Send CMD3 SD_CMD_SET_REL_ADDR */
1041   sdmmc_cmdinit.Argument         = 0U;
1042   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SET_REL_ADDR;
1043   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
1044   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1045   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1046   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1047   
1048   /* Check for error conditions */
1049   errorstate = SDMMC_GetCmdResp6(SDIOx, SDMMC_CMD_SET_REL_ADDR, pRCA);
1050
1051   return errorstate;
1052 }
1053
1054 /**
1055   * @brief  Send the Status command and check the response.
1056   * @param  SDIOx: Pointer to SDIO register base 
1057   * @param  Argument: Command Argument
1058   * @retval HAL status
1059   */
1060 uint32_t SDMMC_CmdSendStatus(SDIO_TypeDef *SDIOx, uint32_t Argument)
1061 {
1062   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1063   uint32_t errorstate;
1064   
1065   sdmmc_cmdinit.Argument         = Argument;
1066   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEND_STATUS;
1067   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
1068   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1069   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1070   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1071   
1072   /* Check for error conditions */
1073   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEND_STATUS, SDIO_CMDTIMEOUT);
1074
1075   return errorstate;
1076 }
1077
1078 /**
1079   * @brief  Send the Status register command and check the response.
1080   * @param  SDIOx: Pointer to SDIO register base 
1081   * @retval HAL status
1082   */
1083 uint32_t SDMMC_CmdStatusRegister(SDIO_TypeDef *SDIOx)
1084 {
1085   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1086   uint32_t errorstate;
1087   
1088   sdmmc_cmdinit.Argument         = 0U;
1089   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_APP_STATUS;
1090   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
1091   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1092   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1093   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1094   
1095   /* Check for error conditions */
1096   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_STATUS, SDIO_CMDTIMEOUT);
1097
1098   return errorstate;
1099 }
1100
1101 /**
1102   * @brief  Sends host capacity support information and activates the card's 
1103   *         initialization process. Send SDMMC_CMD_SEND_OP_COND command
1104   * @param  SDIOx: Pointer to SDIO register base 
1105   * @parame Argument: Argument used for the command
1106   * @retval HAL status
1107   */
1108 uint32_t SDMMC_CmdOpCondition(SDIO_TypeDef *SDIOx, uint32_t Argument)
1109 {
1110   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1111   uint32_t errorstate;
1112   
1113   sdmmc_cmdinit.Argument         = Argument;
1114   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEND_OP_COND;
1115   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
1116   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1117   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1118   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1119   
1120   /* Check for error conditions */
1121   errorstate = SDMMC_GetCmdResp3(SDIOx);
1122
1123   return errorstate;
1124 }
1125
1126 /**
1127   * @brief  Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH comand
1128   * @param  SDIOx: Pointer to SDIO register base 
1129   * @parame Argument: Argument used for the command
1130   * @retval HAL status
1131   */
1132 uint32_t SDMMC_CmdSwitch(SDIO_TypeDef *SDIOx, uint32_t Argument)
1133 {
1134   SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1135   uint32_t errorstate;
1136   
1137   /* Send CMD6 to activate SDR50 Mode and Power Limit 1.44W */
1138   /* CMD Response: R1 */
1139   sdmmc_cmdinit.Argument         = Argument; /* SDMMC_SDR25_SWITCH_PATTERN */
1140   sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_HS_SWITCH;
1141   sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
1142   sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1143   sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1144   (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1145   
1146   /* Check for error conditions */
1147   errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_HS_SWITCH, SDIO_CMDTIMEOUT);
1148
1149   return errorstate;
1150 }
1151
1152 /**
1153   * @}
1154   */
1155
1156 /* Private function ----------------------------------------------------------*/  
1157 /** @addtogroup SD_Private_Functions
1158   * @{
1159   */
1160     
1161 /**
1162   * @brief  Checks for error conditions for CMD0.
1163   * @param  hsd: SD handle
1164   * @retval SD Card error state
1165   */
1166 static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx)
1167 {
1168   /* 8 is the number of required instructions cycles for the below loop statement.
1169   The SDIO_CMDTIMEOUT is expressed in ms */
1170   register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1171   
1172   do
1173   {
1174     if (count-- == 0U)
1175     {
1176       return SDMMC_ERROR_TIMEOUT;
1177     }
1178     
1179   }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDSENT));
1180   
1181   /* Clear all the static flags */
1182   __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
1183   
1184   return SDMMC_ERROR_NONE;
1185 }
1186
1187 /**
1188   * @brief  Checks for error conditions for R1 response.
1189   * @param  hsd: SD handle
1190   * @param  SD_CMD: The sent command index  
1191   * @retval SD Card error state
1192   */
1193 static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout)
1194 {
1195   uint32_t response_r1;
1196   uint32_t sta_reg;
1197   
1198   /* 8 is the number of required instructions cycles for the below loop statement.
1199   The Timeout is expressed in ms */
1200   register uint32_t count = Timeout * (SystemCoreClock / 8U /1000U);
1201   
1202   do
1203   {
1204     if (count-- == 0U)
1205     {
1206       return SDMMC_ERROR_TIMEOUT;
1207     }
1208     sta_reg = SDIOx->STA;
1209   }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
1210          ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
1211     
1212   if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1213   {
1214     __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1215     
1216     return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1217   }
1218   else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1219   {
1220     __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1221     
1222     return SDMMC_ERROR_CMD_CRC_FAIL;
1223   }
1224   else
1225   {
1226     /* Nothing to do */
1227   }
1228   
1229   /* Clear all the static flags */
1230   __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
1231   
1232   /* Check response received is of desired command */
1233   if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
1234   {
1235     return SDMMC_ERROR_CMD_CRC_FAIL;
1236   }
1237   
1238   /* We have received response, retrieve it for analysis  */
1239   response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
1240   
1241   if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO)
1242   {
1243     return SDMMC_ERROR_NONE;
1244   }
1245   else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE)
1246   {
1247     return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
1248   }
1249   else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED)
1250   {
1251     return SDMMC_ERROR_ADDR_MISALIGNED;
1252   }
1253   else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR)
1254   {
1255     return SDMMC_ERROR_BLOCK_LEN_ERR;
1256   }
1257   else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR)
1258   {
1259     return SDMMC_ERROR_ERASE_SEQ_ERR;
1260   }
1261   else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM)
1262   {
1263     return SDMMC_ERROR_BAD_ERASE_PARAM;
1264   }
1265   else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION)
1266   {
1267     return SDMMC_ERROR_WRITE_PROT_VIOLATION;
1268   }
1269   else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED)
1270   {
1271     return SDMMC_ERROR_LOCK_UNLOCK_FAILED;
1272   }
1273   else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED)
1274   {
1275     return SDMMC_ERROR_COM_CRC_FAILED;
1276   }
1277   else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD)
1278   {
1279     return SDMMC_ERROR_ILLEGAL_CMD;
1280   }
1281   else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED)
1282   {
1283     return SDMMC_ERROR_CARD_ECC_FAILED;
1284   }
1285   else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR)
1286   {
1287     return SDMMC_ERROR_CC_ERR;
1288   }
1289   else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN)
1290   {
1291     return SDMMC_ERROR_STREAM_READ_UNDERRUN;
1292   }
1293   else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN)
1294   {
1295     return SDMMC_ERROR_STREAM_WRITE_OVERRUN;
1296   }
1297   else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE)
1298   {
1299     return SDMMC_ERROR_CID_CSD_OVERWRITE;
1300   }
1301   else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP)
1302   {
1303     return SDMMC_ERROR_WP_ERASE_SKIP;
1304   }
1305   else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED)
1306   {
1307     return SDMMC_ERROR_CARD_ECC_DISABLED;
1308   }
1309   else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET)
1310   {
1311     return SDMMC_ERROR_ERASE_RESET;
1312   }
1313   else if((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR)
1314   {
1315     return SDMMC_ERROR_AKE_SEQ_ERR;
1316   }
1317   else
1318   {
1319     return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1320   }
1321 }
1322
1323 /**
1324   * @brief  Checks for error conditions for R2 (CID or CSD) response.
1325   * @param  hsd: SD handle
1326   * @retval SD Card error state
1327   */
1328 static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx)
1329 {
1330   uint32_t sta_reg;
1331   /* 8 is the number of required instructions cycles for the below loop statement.
1332   The SDIO_CMDTIMEOUT is expressed in ms */
1333   register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1334   
1335   do
1336   {
1337     if (count-- == 0U)
1338     {
1339       return SDMMC_ERROR_TIMEOUT;
1340     }
1341     sta_reg = SDIOx->STA;
1342   }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
1343          ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
1344     
1345   if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1346   {
1347     __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1348     
1349     return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1350   }
1351   else if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1352   {
1353     __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1354     
1355     return SDMMC_ERROR_CMD_CRC_FAIL;
1356   }
1357   else
1358   {
1359     /* No error flag set */
1360     /* Clear all the static flags */
1361     __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
1362   }
1363
1364   return SDMMC_ERROR_NONE;
1365 }
1366
1367 /**
1368   * @brief  Checks for error conditions for R3 (OCR) response.
1369   * @param  hsd: SD handle
1370   * @retval SD Card error state
1371   */
1372 static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx)
1373 {
1374   uint32_t sta_reg;
1375   /* 8 is the number of required instructions cycles for the below loop statement.
1376   The SDIO_CMDTIMEOUT is expressed in ms */
1377   register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1378   
1379   do
1380   {
1381     if (count-- == 0U)
1382     {
1383       return SDMMC_ERROR_TIMEOUT;
1384     }
1385     sta_reg = SDIOx->STA;
1386   }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
1387          ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
1388     
1389   if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1390   {
1391     __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1392     
1393     return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1394   }
1395   else
1396   {  
1397     /* Clear all the static flags */
1398     __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
1399   }
1400   
1401   return SDMMC_ERROR_NONE;
1402 }
1403
1404 /**
1405   * @brief  Checks for error conditions for R6 (RCA) response.
1406   * @param  hsd: SD handle
1407   * @param  SD_CMD: The sent command index
1408   * @param  pRCA: Pointer to the variable that will contain the SD card relative 
1409   *         address RCA   
1410   * @retval SD Card error state
1411   */
1412 static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA)
1413 {
1414   uint32_t response_r1;
1415   uint32_t sta_reg;
1416
1417   /* 8 is the number of required instructions cycles for the below loop statement.
1418   The SDIO_CMDTIMEOUT is expressed in ms */
1419   register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1420   
1421   do
1422   {
1423     if (count-- == 0U)
1424     {
1425       return SDMMC_ERROR_TIMEOUT;
1426     }
1427     sta_reg = SDIOx->STA;
1428   }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
1429          ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
1430     
1431   if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1432   {
1433     __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1434     
1435     return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1436   }
1437   else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1438   {
1439     __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1440     
1441     return SDMMC_ERROR_CMD_CRC_FAIL;
1442   }
1443   else
1444   {
1445     /* Nothing to do */
1446   }
1447   
1448   /* Check response received is of desired command */
1449   if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
1450   {
1451     return SDMMC_ERROR_CMD_CRC_FAIL;
1452   }
1453   
1454   /* Clear all the static flags */
1455   __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
1456   
1457   /* We have received response, retrieve it.  */
1458   response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
1459   
1460   if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO)
1461   {
1462     *pRCA = (uint16_t) (response_r1 >> 16);
1463     
1464     return SDMMC_ERROR_NONE;
1465   }
1466   else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD)
1467   {
1468     return SDMMC_ERROR_ILLEGAL_CMD;
1469   }
1470   else if((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED)
1471   {
1472     return SDMMC_ERROR_COM_CRC_FAILED;
1473   }
1474   else
1475   {
1476     return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1477   }
1478 }
1479
1480 /**
1481   * @brief  Checks for error conditions for R7 response.
1482   * @param  hsd: SD handle
1483   * @retval SD Card error state
1484   */
1485 static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx)
1486 {
1487   uint32_t sta_reg;
1488   /* 8 is the number of required instructions cycles for the below loop statement.
1489   The SDIO_CMDTIMEOUT is expressed in ms */
1490   register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1491   
1492   do
1493   {
1494     if (count-- == 0U)
1495     {
1496       return SDMMC_ERROR_TIMEOUT;
1497     }
1498     sta_reg = SDIOx->STA;
1499   }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
1500          ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
1501     
1502   if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1503   {
1504     /* Card is SD V2.0 compliant */
1505     __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1506     
1507     return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1508   }
1509   else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1510   {
1511     /* Card is SD V2.0 compliant */
1512     __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1513     
1514     return SDMMC_ERROR_CMD_CRC_FAIL;
1515   }
1516   else
1517   {
1518     /* Nothing to do */
1519   }
1520   
1521   if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDREND))
1522   {
1523     /* Card is SD V2.0 compliant */
1524     __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CMDREND);
1525   }
1526   
1527   return SDMMC_ERROR_NONE;
1528   
1529 }
1530
1531 /**
1532   * @}
1533   */
1534
1535 #endif /* HAL_SD_MODULE_ENABLED || HAL_MMC_MODULE_ENABLED */
1536 /**
1537   * @}
1538   */
1539
1540 /**
1541   * @}
1542   */
1543
1544 #endif /* SDIO */
1545
1546 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/