1 /**
2   ******************************************************************************
3   * @file    stm32f2xx_hal_sd.c
4   * @author  MCD Application Team
5   * @brief   SD card HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Secure Digital (SD) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2016 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                         ##### How to use this driver #####
27   ==============================================================================
28   [..]
29     This driver implements a high level communication layer for read and write from/to
30     this memory. The needed STM32 hardware resources (SDIO and GPIO) are performed by
31     the user in HAL_SD_MspInit() function (MSP layer).
32     Basically, the MSP layer configuration should be the same as we provide in the
33     examples.
34     You can easily tailor this configuration according to hardware resources.
35 
36   [..]
37     This driver is a generic layered driver for SDIO memories which uses the HAL
38     SDIO driver functions to interface with SD and uSD cards devices.
39     It is used as follows:
40 
41     (#)Initialize the SDIO low level resources by implementing the HAL_SD_MspInit() API:
42         (##) Enable the SDIO interface clock using __HAL_RCC_SDIO_CLK_ENABLE();
43         (##) SDIO pins configuration for SD card
44             (+++) Enable the clock for the SDIO GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
45             (+++) Configure these SDIO pins as alternate function pull-up using HAL_GPIO_Init()
46                   and according to your pin assignment;
47         (##) DMA configuration if you need to use DMA process (HAL_SD_ReadBlocks_DMA()
48              and HAL_SD_WriteBlocks_DMA() APIs).
49             (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
50             (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
51         (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
52             (+++) Configure the SDIO and DMA interrupt priorities using functions
53                   HAL_NVIC_SetPriority(); DMA priority is superior to SDIO's priority
54             (+++) Enable the NVIC DMA and SDIO IRQs using function HAL_NVIC_EnableIRQ()
55             (+++) SDIO interrupts are managed using the macros __HAL_SD_ENABLE_IT()
56                   and __HAL_SD_DISABLE_IT() inside the communication process.
57             (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_GET_IT()
58                   and __HAL_SD_CLEAR_IT()
59         (##) NVIC configuration if you need to use interrupt process (HAL_SD_ReadBlocks_IT()
60              and HAL_SD_WriteBlocks_IT() APIs).
61             (+++) Configure the SDIO interrupt priorities using function HAL_NVIC_SetPriority();
62             (+++) Enable the NVIC SDIO IRQs using function HAL_NVIC_EnableIRQ()
63             (+++) SDIO interrupts are managed using the macros __HAL_SD_ENABLE_IT()
64                   and __HAL_SD_DISABLE_IT() inside the communication process.
65             (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_GET_IT()
66                   and __HAL_SD_CLEAR_IT()
67     (#) At this stage, you can perform SD read/write/erase operations after SD card initialization
68 
69 
70   *** SD Card Initialization and configuration ***
71   ================================================
72   [..]
73     To initialize the SD Card, use the HAL_SD_Init() function. It Initializes
74     SDIO Peripheral(STM32 side) and the SD Card, and put it into StandBy State (Ready for data transfer).
75     This function provide the following operations:
76 
77     (#) Apply the SD Card initialization process at 400KHz and check the SD Card
78         type (Standard Capacity or High Capacity). You can change or adapt this
79         frequency by adjusting the "ClockDiv" field.
80         The SD Card frequency (SDIO_CK) is computed as follows:
81 
82            SDIO_CK = SDIOCLK / (ClockDiv + 2)
83 
84         In initialization mode and according to the SD Card standard,
85         make sure that the SDIO_CK frequency doesn't exceed 400KHz.
86 
87         This phase of initialization is done through SDIO_Init() and
88         SDIO_PowerState_ON() SDIO low level APIs.
89 
90     (#) Initialize the SD card. The API used is HAL_SD_InitCard().
91         This phase allows the card initialization and identification
92         and check the SD Card type (Standard Capacity or High Capacity)
93         The initialization flow is compatible with SD standard.
94 
95         This API (HAL_SD_InitCard()) could be used also to reinitialize the card in case
96         of plug-off plug-in.
97 
98     (#) Configure the SD Card Data transfer frequency. You can change or adapt this
99         frequency by adjusting the "ClockDiv" field.
100         In transfer mode and according to the SD Card standard, make sure that the
101         SDIO_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
102         To be able to use a frequency higher than 24MHz, you should use the SDIO
103         peripheral in bypass mode. Refer to the corresponding reference manual
104         for more details.
105 
106     (#) Select the corresponding SD Card according to the address read with the step 2.
107 
108     (#) Configure the SD Card in wide bus mode: 4-bits data.
109 
110   *** SD Card Read operation ***
111   ==============================
112   [..]
113     (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks().
114         This function support only 512-bytes block length (the block size should be
115         chosen as 512 bytes).
116         You can choose either one block read operation or multiple block read operation
117         by adjusting the "NumberOfBlocks" parameter.
118         After this, you have to ensure that the transfer is done correctly. The check is done
119         through HAL_SD_GetCardState() function for SD card state.
120 
121     (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA().
122         This function support only 512-bytes block length (the block size should be
123         chosen as 512 bytes).
124         You can choose either one block read operation or multiple block read operation
125         by adjusting the "NumberOfBlocks" parameter.
126         After this, you have to ensure that the transfer is done correctly. The check is done
127         through HAL_SD_GetCardState() function for SD card state.
128         You could also check the DMA transfer process through the SD Rx interrupt event.
129 
130     (+) You can read from SD card in Interrupt mode by using function HAL_SD_ReadBlocks_IT().
131         This function support only 512-bytes block length (the block size should be
132         chosen as 512 bytes).
133         You can choose either one block read operation or multiple block read operation
134         by adjusting the "NumberOfBlocks" parameter.
135         After this, you have to ensure that the transfer is done correctly. The check is done
136         through HAL_SD_GetCardState() function for SD card state.
137         You could also check the IT transfer process through the SD Rx interrupt event.
138 
139   *** SD Card Write operation ***
140   ===============================
141   [..]
142     (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks().
143         This function support only 512-bytes block length (the block size should be
144         chosen as 512 bytes).
145         You can choose either one block read operation or multiple block read operation
146         by adjusting the "NumberOfBlocks" parameter.
147         After this, you have to ensure that the transfer is done correctly. The check is done
148         through HAL_SD_GetCardState() function for SD card state.
149 
150     (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA().
151         This function support only 512-bytes block length (the block size should be
152         chosen as 512 bytes).
153         You can choose either one block read operation or multiple block read operation
154         by adjusting the "NumberOfBlocks" parameter.
155         After this, you have to ensure that the transfer is done correctly. The check is done
156         through HAL_SD_GetCardState() function for SD card state.
157         You could also check the DMA transfer process through the SD Tx interrupt event.
158 
159     (+) You can write to SD card in Interrupt mode by using function HAL_SD_WriteBlocks_IT().
160         This function support only 512-bytes block length (the block size should be
161         chosen as 512 bytes).
162         You can choose either one block read operation or multiple block read operation
163         by adjusting the "NumberOfBlocks" parameter.
164         After this, you have to ensure that the transfer is done correctly. The check is done
165         through HAL_SD_GetCardState() function for SD card state.
166         You could also check the IT transfer process through the SD Tx interrupt event.
167 
168   *** SD card status ***
169   ======================
170   [..]
171     (+) The SD Status contains status bits that are related to the SD Memory
172         Card proprietary features. To get SD card status use the HAL_SD_GetCardStatus().
173 
174   *** SD card information ***
175   ===========================
176   [..]
177     (+) To get SD card information, you can use the function HAL_SD_GetCardInfo().
178         It returns useful information about the SD card such as block size, card type,
179         block number ...
180 
181   *** SD card CSD register ***
182   ============================
183     (+) The HAL_SD_GetCardCSD() API allows to get the parameters of the CSD register.
184         Some of the CSD parameters are useful for card initialization and identification.
185 
186   *** SD card CID register ***
187   ============================
188     (+) The HAL_SD_GetCardCID() API allows to get the parameters of the CID register.
189         Some of the CSD parameters are useful for card initialization and identification.
190 
191   *** SD HAL driver macros list ***
192   ==================================
193   [..]
194     Below the list of most used macros in SD HAL driver.
195 
196     (+) __HAL_SD_ENABLE : Enable the SD device
197     (+) __HAL_SD_DISABLE : Disable the SD device
198     (+) __HAL_SD_DMA_ENABLE: Enable the SDIO DMA transfer
199     (+) __HAL_SD_DMA_DISABLE: Disable the SDIO DMA transfer
200     (+) __HAL_SD_ENABLE_IT: Enable the SD device interrupt
201     (+) __HAL_SD_DISABLE_IT: Disable the SD device interrupt
202     (+) __HAL_SD_GET_FLAG:Check whether the specified SD flag is set or not
203     (+) __HAL_SD_CLEAR_FLAG: Clear the SD's pending flags
204 
205     (@) You can refer to the SD HAL driver header file for more useful macros
206 
207   *** Callback registration ***
208   =============================================
209   [..]
210     The compilation define USE_HAL_SD_REGISTER_CALLBACKS when set to 1
211     allows the user to configure dynamically the driver callbacks.
212 
213     Use Functions HAL_SD_RegisterCallback() to register a user callback,
214     it allows to register following callbacks:
215       (+) TxCpltCallback : callback when a transmission transfer is completed.
216       (+) RxCpltCallback : callback when a reception transfer is completed.
217       (+) ErrorCallback : callback when error occurs.
218       (+) AbortCpltCallback : callback when abort is completed.
219       (+) MspInitCallback    : SD MspInit.
220       (+) MspDeInitCallback  : SD MspDeInit.
221     This function takes as parameters the HAL peripheral handle, the Callback ID
222     and a pointer to the user callback function.
223 
224     Use function HAL_SD_UnRegisterCallback() to reset a callback to the default
225     weak (surcharged) function. It allows to reset following callbacks:
226       (+) TxCpltCallback : callback when a transmission transfer is completed.
227       (+) RxCpltCallback : callback when a reception transfer is completed.
228       (+) ErrorCallback : callback when error occurs.
229       (+) AbortCpltCallback : callback when abort is completed.
230       (+) MspInitCallback    : SD MspInit.
231       (+) MspDeInitCallback  : SD MspDeInit.
232     This function) takes as parameters the HAL peripheral handle and the Callback ID.
233 
234     By default, after the HAL_SD_Init and if the state is HAL_SD_STATE_RESET
235     all callbacks are reset to the corresponding legacy weak (surcharged) functions.
236     Exception done for MspInit and MspDeInit callbacks that are respectively
237     reset to the legacy weak (surcharged) functions in the HAL_SD_Init
238     and  HAL_SD_DeInit only when these callbacks are null (not registered beforehand).
239     If not, MspInit or MspDeInit are not null, the HAL_SD_Init and HAL_SD_DeInit
240     keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
241 
242     Callbacks can be registered/unregistered in READY state only.
243     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
244     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
245     during the Init/DeInit.
246     In that case first register the MspInit/MspDeInit user callbacks
247     using HAL_SD_RegisterCallback before calling HAL_SD_DeInit
248     or HAL_SD_Init function.
249 
250     When The compilation define USE_HAL_SD_REGISTER_CALLBACKS is set to 0 or
251     not defined, the callback registering feature is not available
252     and weak (surcharged) callbacks are used.
253 
254   @endverbatim
255   ******************************************************************************
256   */
257 
258 /* Includes ------------------------------------------------------------------*/
259 #include "stm32f2xx_hal.h"
260 
261 #if defined(SDIO)
262 
263 /** @addtogroup STM32F2xx_HAL_Driver
264   * @{
265   */
266 
267 /** @addtogroup SD
268   * @{
269   */
270 
271 #ifdef HAL_SD_MODULE_ENABLED
272 
273 /* Private typedef -----------------------------------------------------------*/
274 /* Private define ------------------------------------------------------------*/
275 /** @addtogroup SD_Private_Defines
276   * @{
277   */
278 
279 /**
280   * @}
281   */
282 
283 /* Private macro -------------------------------------------------------------*/
284 /* Private variables ---------------------------------------------------------*/
285 /* Private function prototypes -----------------------------------------------*/
286 /* Private functions ---------------------------------------------------------*/
287 /** @defgroup SD_Private_Functions SD Private Functions
288   * @{
289   */
290 static uint32_t SD_InitCard(SD_HandleTypeDef *hsd);
291 static uint32_t SD_PowerON(SD_HandleTypeDef *hsd);
292 static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus);
293 static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus);
294 static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd);
295 static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd);
296 static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR);
297 static void SD_PowerOFF(SD_HandleTypeDef *hsd);
298 static void SD_Write_IT(SD_HandleTypeDef *hsd);
299 static void SD_Read_IT(SD_HandleTypeDef *hsd);
300 static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma);
301 static void SD_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
302 static void SD_DMAError(DMA_HandleTypeDef *hdma);
303 static void SD_DMATxAbort(DMA_HandleTypeDef *hdma);
304 static void SD_DMARxAbort(DMA_HandleTypeDef *hdma);
305 /**
306   * @}
307   */
308 
309 /* Exported functions --------------------------------------------------------*/
310 /** @addtogroup SD_Exported_Functions
311   * @{
312   */
313 
314 /** @addtogroup SD_Exported_Functions_Group1
315  *  @brief   Initialization and de-initialization functions
316  *
317 @verbatim
318   ==============================================================================
319           ##### Initialization and de-initialization functions #####
320   ==============================================================================
321   [..]
322     This section provides functions allowing to initialize/de-initialize the SD
323     card device to be ready for use.
324 
325 @endverbatim
326   * @{
327   */
328 
329 /**
330   * @brief  Initializes the SD according to the specified parameters in the
331             SD_HandleTypeDef and create the associated handle.
332   * @param  hsd: Pointer to the SD handle
333   * @retval HAL status
334   */
HAL_SD_Init(SD_HandleTypeDef * hsd)335 HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd)
336 {
337   /* Check the SD handle allocation */
338   if(hsd == NULL)
339   {
340     return HAL_ERROR;
341   }
342 
343   /* Check the parameters */
344   assert_param(IS_SDIO_ALL_INSTANCE(hsd->Instance));
345   assert_param(IS_SDIO_CLOCK_EDGE(hsd->Init.ClockEdge));
346   assert_param(IS_SDIO_CLOCK_BYPASS(hsd->Init.ClockBypass));
347   assert_param(IS_SDIO_CLOCK_POWER_SAVE(hsd->Init.ClockPowerSave));
348   assert_param(IS_SDIO_BUS_WIDE(hsd->Init.BusWide));
349   assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hsd->Init.HardwareFlowControl));
350   assert_param(IS_SDIO_CLKDIV(hsd->Init.ClockDiv));
351 
352   if(hsd->State == HAL_SD_STATE_RESET)
353   {
354     /* Allocate lock resource and initialize it */
355     hsd->Lock = HAL_UNLOCKED;
356 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
357     /* Reset Callback pointers in HAL_SD_STATE_RESET only */
358     hsd->TxCpltCallback    = HAL_SD_TxCpltCallback;
359     hsd->RxCpltCallback    = HAL_SD_RxCpltCallback;
360     hsd->ErrorCallback     = HAL_SD_ErrorCallback;
361     hsd->AbortCpltCallback = HAL_SD_AbortCallback;
362 
363     if(hsd->MspInitCallback == NULL)
364     {
365       hsd->MspInitCallback = HAL_SD_MspInit;
366     }
367 
368     /* Init the low level hardware */
369     hsd->MspInitCallback(hsd);
370 #else
371     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
372     HAL_SD_MspInit(hsd);
373 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
374   }
375 
376   hsd->State = HAL_SD_STATE_BUSY;
377 
378   /* Initialize the Card parameters */
379   if (HAL_SD_InitCard(hsd) != HAL_OK)
380   {
381     return HAL_ERROR;
382   }
383 
384   /* Initialize the error code */
385   hsd->ErrorCode = HAL_SD_ERROR_NONE;
386 
387   /* Initialize the SD operation */
388   hsd->Context = SD_CONTEXT_NONE;
389 
390   /* Initialize the SD state */
391   hsd->State = HAL_SD_STATE_READY;
392 
393   return HAL_OK;
394 }
395 
396 /**
397   * @brief  Initializes the SD Card.
398   * @param  hsd: Pointer to SD handle
399   * @note   This function initializes the SD card. It could be used when a card
400             re-initialization is needed.
401   * @retval HAL status
402   */
HAL_SD_InitCard(SD_HandleTypeDef * hsd)403 HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd)
404 {
405   uint32_t errorstate;
406   HAL_StatusTypeDef status;
407   SD_InitTypeDef Init;
408 
409   /* Default SDIO peripheral configuration for SD card initialization */
410   Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
411   Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
412   Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
413   Init.BusWide             = SDIO_BUS_WIDE_1B;
414   Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
415   Init.ClockDiv            = SDIO_INIT_CLK_DIV;
416 
417   /* Initialize SDIO peripheral interface with default configuration */
418   status = SDIO_Init(hsd->Instance, Init);
419   if(status != HAL_OK)
420   {
421     return HAL_ERROR;
422   }
423 
424   /* Disable SDIO Clock */
425   __HAL_SD_DISABLE(hsd);
426 
427   /* Set Power State to ON */
428   (void)SDIO_PowerState_ON(hsd->Instance);
429 
430   /* Enable SDIO Clock */
431   __HAL_SD_ENABLE(hsd);
432 
433   /* Required power up waiting time before starting the SD initialization  sequence */
434   HAL_Delay(2);
435 
436   /* Identify card operating voltage */
437   errorstate = SD_PowerON(hsd);
438   if(errorstate != HAL_SD_ERROR_NONE)
439   {
440     hsd->State = HAL_SD_STATE_READY;
441     hsd->ErrorCode |= errorstate;
442     return HAL_ERROR;
443   }
444 
445   /* Card initialization */
446   errorstate = SD_InitCard(hsd);
447   if(errorstate != HAL_SD_ERROR_NONE)
448   {
449     hsd->State = HAL_SD_STATE_READY;
450     hsd->ErrorCode |= errorstate;
451     return HAL_ERROR;
452   }
453 
454   /* Set Block Size for Card */
455   errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
456   if(errorstate != HAL_SD_ERROR_NONE)
457   {
458     /* Clear all the static flags */
459     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
460     hsd->ErrorCode |= errorstate;
461     hsd->State = HAL_SD_STATE_READY;
462     return HAL_ERROR;
463   }
464 
465   return HAL_OK;
466 }
467 
468 /**
469   * @brief  De-Initializes the SD card.
470   * @param  hsd: Pointer to SD handle
471   * @retval HAL status
472   */
HAL_SD_DeInit(SD_HandleTypeDef * hsd)473 HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd)
474 {
475   /* Check the SD handle allocation */
476   if(hsd == NULL)
477   {
478     return HAL_ERROR;
479   }
480 
481   /* Check the parameters */
482   assert_param(IS_SDIO_ALL_INSTANCE(hsd->Instance));
483 
484   hsd->State = HAL_SD_STATE_BUSY;
485 
486   /* Set SD power state to off */
487   SD_PowerOFF(hsd);
488 
489 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
490   if(hsd->MspDeInitCallback == NULL)
491   {
492     hsd->MspDeInitCallback = HAL_SD_MspDeInit;
493   }
494 
495   /* DeInit the low level hardware */
496   hsd->MspDeInitCallback(hsd);
497 #else
498   /* De-Initialize the MSP layer */
499   HAL_SD_MspDeInit(hsd);
500 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
501 
502   hsd->ErrorCode = HAL_SD_ERROR_NONE;
503   hsd->State = HAL_SD_STATE_RESET;
504 
505   return HAL_OK;
506 }
507 
508 
509 /**
510   * @brief  Initializes the SD MSP.
511   * @param  hsd: Pointer to SD handle
512   * @retval None
513   */
HAL_SD_MspInit(SD_HandleTypeDef * hsd)514 __weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
515 {
516   /* Prevent unused argument(s) compilation warning */
517   UNUSED(hsd);
518 
519   /* NOTE : This function should not be modified, when the callback is needed,
520             the HAL_SD_MspInit could be implemented in the user file
521    */
522 }
523 
524 /**
525   * @brief  De-Initialize SD MSP.
526   * @param  hsd: Pointer to SD handle
527   * @retval None
528   */
HAL_SD_MspDeInit(SD_HandleTypeDef * hsd)529 __weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)
530 {
531   /* Prevent unused argument(s) compilation warning */
532   UNUSED(hsd);
533 
534   /* NOTE : This function should not be modified, when the callback is needed,
535             the HAL_SD_MspDeInit could be implemented in the user file
536    */
537 }
538 
539 /**
540   * @}
541   */
542 
543 /** @addtogroup SD_Exported_Functions_Group2
544  *  @brief   Data transfer functions
545  *
546 @verbatim
547   ==============================================================================
548                         ##### IO operation functions #####
549   ==============================================================================
550   [..]
551     This subsection provides a set of functions allowing to manage the data
552     transfer from/to SD card.
553 
554 @endverbatim
555   * @{
556   */
557 
558 /**
559   * @brief  Reads block(s) from a specified address in a card. The Data transfer
560   *         is managed by polling mode.
561   * @note   This API should be followed by a check on the card state through
562   *         HAL_SD_GetCardState().
563   * @param  hsd: Pointer to SD handle
564   * @param  pData: pointer to the buffer that will contain the received data
565   * @param  BlockAdd: Block Address from where data is to be read
566   * @param  NumberOfBlocks: Number of SD blocks to read
567   * @param  Timeout: Specify timeout value
568   * @retval HAL status
569   */
HAL_SD_ReadBlocks(SD_HandleTypeDef * hsd,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)570 HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
571 {
572   SDIO_DataInitTypeDef config;
573   uint32_t errorstate;
574   uint32_t tickstart = HAL_GetTick();
575   uint32_t count, data, dataremaining;
576   uint32_t add = BlockAdd;
577   uint8_t *tempbuff = pData;
578 
579   if(NULL == pData)
580   {
581     hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
582     return HAL_ERROR;
583   }
584 
585   if(hsd->State == HAL_SD_STATE_READY)
586   {
587     hsd->ErrorCode = HAL_SD_ERROR_NONE;
588 
589     if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
590     {
591       hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
592       return HAL_ERROR;
593     }
594 
595     hsd->State = HAL_SD_STATE_BUSY;
596 
597     /* Initialize data control register */
598     hsd->Instance->DCTRL = 0U;
599 
600     if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
601     {
602       add *= 512U;
603     }
604 
605     /* Configure the SD DPSM (Data Path State Machine) */
606     config.DataTimeOut   = SDMMC_DATATIMEOUT;
607     config.DataLength    = NumberOfBlocks * BLOCKSIZE;
608     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
609     config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
610     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
611     config.DPSM          = SDIO_DPSM_ENABLE;
612     (void)SDIO_ConfigData(hsd->Instance, &config);
613 
614     /* Read block(s) in polling mode */
615     if(NumberOfBlocks > 1U)
616     {
617       hsd->Context = SD_CONTEXT_READ_MULTIPLE_BLOCK;
618 
619       /* Read Multi Block command */
620       errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add);
621     }
622     else
623     {
624       hsd->Context = SD_CONTEXT_READ_SINGLE_BLOCK;
625 
626       /* Read Single Block command */
627       errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add);
628     }
629     if(errorstate != HAL_SD_ERROR_NONE)
630     {
631       /* Clear all the static flags */
632       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
633       hsd->ErrorCode |= errorstate;
634       hsd->State = HAL_SD_STATE_READY;
635       hsd->Context = SD_CONTEXT_NONE;
636       return HAL_ERROR;
637     }
638 
639     /* Poll on SDIO flags */
640     dataremaining = config.DataLength;
641     while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
642     {
643       if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF) && (dataremaining > 0U))
644       {
645         /* Read data from SDIO Rx FIFO */
646         for(count = 0U; count < 8U; count++)
647         {
648           data = SDIO_ReadFIFO(hsd->Instance);
649           *tempbuff = (uint8_t)(data & 0xFFU);
650           tempbuff++;
651           dataremaining--;
652           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
653           tempbuff++;
654           dataremaining--;
655           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
656           tempbuff++;
657           dataremaining--;
658           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
659           tempbuff++;
660           dataremaining--;
661         }
662       }
663 
664       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
665       {
666         /* Clear all the static flags */
667         __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
668         hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;
669         hsd->State= HAL_SD_STATE_READY;
670         hsd->Context = SD_CONTEXT_NONE;
671         return HAL_TIMEOUT;
672       }
673     }
674 
675     /* Send stop transmission command in case of multiblock read */
676     if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
677     {
678       if(hsd->SdCard.CardType != CARD_SECURED)
679       {
680         /* Send stop transmission command */
681         errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
682         if(errorstate != HAL_SD_ERROR_NONE)
683         {
684           /* Clear all the static flags */
685           __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
686           hsd->ErrorCode |= errorstate;
687           hsd->State = HAL_SD_STATE_READY;
688           hsd->Context = SD_CONTEXT_NONE;
689           return HAL_ERROR;
690         }
691       }
692     }
693 
694     /* Get error state */
695     if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
696     {
697       /* Clear all the static flags */
698       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
699       hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
700       hsd->State = HAL_SD_STATE_READY;
701       hsd->Context = SD_CONTEXT_NONE;
702       return HAL_ERROR;
703     }
704     else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
705     {
706       /* Clear all the static flags */
707       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
708       hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
709       hsd->State = HAL_SD_STATE_READY;
710       hsd->Context = SD_CONTEXT_NONE;
711       return HAL_ERROR;
712     }
713     else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
714     {
715       /* Clear all the static flags */
716       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
717       hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN;
718       hsd->State = HAL_SD_STATE_READY;
719       hsd->Context = SD_CONTEXT_NONE;
720       return HAL_ERROR;
721     }
722     else
723     {
724       /* Nothing to do */
725     }
726 
727     /* Empty FIFO if there is still any data */
728     while ((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (dataremaining > 0U))
729     {
730       data = SDIO_ReadFIFO(hsd->Instance);
731       *tempbuff = (uint8_t)(data & 0xFFU);
732       tempbuff++;
733       dataremaining--;
734       *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
735       tempbuff++;
736       dataremaining--;
737       *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
738       tempbuff++;
739       dataremaining--;
740       *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
741       tempbuff++;
742       dataremaining--;
743 
744       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
745       {
746         /* Clear all the static flags */
747         __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
748         hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;
749         hsd->State= HAL_SD_STATE_READY;
750         hsd->Context = SD_CONTEXT_NONE;
751         return HAL_ERROR;
752       }
753     }
754 
755     /* Clear all the static flags */
756     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
757 
758     hsd->State = HAL_SD_STATE_READY;
759 
760     return HAL_OK;
761   }
762   else
763   {
764     hsd->ErrorCode |= HAL_SD_ERROR_BUSY;
765     return HAL_ERROR;
766   }
767 }
768 
769 /**
770   * @brief  Allows to write block(s) to a specified address in a card. The Data
771   *         transfer is managed by polling mode.
772   * @note   This API should be followed by a check on the card state through
773   *         HAL_SD_GetCardState().
774   * @param  hsd: Pointer to SD handle
775   * @param  pData: pointer to the buffer that will contain the data to transmit
776   * @param  BlockAdd: Block Address where data will be written
777   * @param  NumberOfBlocks: Number of SD blocks to write
778   * @param  Timeout: Specify timeout value
779   * @retval HAL status
780   */
HAL_SD_WriteBlocks(SD_HandleTypeDef * hsd,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)781 HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
782 {
783   SDIO_DataInitTypeDef config;
784   uint32_t errorstate;
785   uint32_t tickstart = HAL_GetTick();
786   uint32_t count, data, dataremaining;
787   uint32_t add = BlockAdd;
788   uint8_t *tempbuff = pData;
789 
790   if(NULL == pData)
791   {
792     hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
793     return HAL_ERROR;
794   }
795 
796   if(hsd->State == HAL_SD_STATE_READY)
797   {
798     hsd->ErrorCode = HAL_SD_ERROR_NONE;
799 
800     if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
801     {
802       hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
803       return HAL_ERROR;
804     }
805 
806     hsd->State = HAL_SD_STATE_BUSY;
807 
808     /* Initialize data control register */
809     hsd->Instance->DCTRL = 0U;
810 
811     if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
812     {
813       add *= 512U;
814     }
815 
816     /* Configure the SD DPSM (Data Path State Machine) */
817     config.DataTimeOut   = SDMMC_DATATIMEOUT;
818     config.DataLength    = NumberOfBlocks * BLOCKSIZE;
819     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
820     config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
821     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
822     config.DPSM          = SDIO_DPSM_ENABLE;
823     (void)SDIO_ConfigData(hsd->Instance, &config);
824 
825     /* Write Blocks in Polling mode */
826     if(NumberOfBlocks > 1U)
827     {
828       hsd->Context = SD_CONTEXT_WRITE_MULTIPLE_BLOCK;
829 
830       /* Write Multi Block command */
831       errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add);
832     }
833     else
834     {
835       hsd->Context = SD_CONTEXT_WRITE_SINGLE_BLOCK;
836 
837       /* Write Single Block command */
838       errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add);
839     }
840     if(errorstate != HAL_SD_ERROR_NONE)
841     {
842       /* Clear all the static flags */
843       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
844       hsd->ErrorCode |= errorstate;
845       hsd->State = HAL_SD_STATE_READY;
846       hsd->Context = SD_CONTEXT_NONE;
847       return HAL_ERROR;
848     }
849 
850     /* Write block(s) in polling mode */
851     dataremaining = config.DataLength;
852     while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
853     {
854       if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE) && (dataremaining > 0U))
855       {
856         /* Write data to SDIO Tx FIFO */
857         for(count = 0U; count < 8U; count++)
858         {
859           data = (uint32_t)(*tempbuff);
860           tempbuff++;
861           dataremaining--;
862           data |= ((uint32_t)(*tempbuff) << 8U);
863           tempbuff++;
864           dataremaining--;
865           data |= ((uint32_t)(*tempbuff) << 16U);
866           tempbuff++;
867           dataremaining--;
868           data |= ((uint32_t)(*tempbuff) << 24U);
869           tempbuff++;
870           dataremaining--;
871           (void)SDIO_WriteFIFO(hsd->Instance, &data);
872         }
873       }
874 
875       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
876       {
877         /* Clear all the static flags */
878         __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
879         hsd->ErrorCode |= errorstate;
880         hsd->State = HAL_SD_STATE_READY;
881         hsd->Context = SD_CONTEXT_NONE;
882         return HAL_TIMEOUT;
883       }
884     }
885 
886     /* Send stop transmission command in case of multiblock write */
887     if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
888     {
889       if(hsd->SdCard.CardType != CARD_SECURED)
890       {
891         /* Send stop transmission command */
892         errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
893         if(errorstate != HAL_SD_ERROR_NONE)
894         {
895           /* Clear all the static flags */
896           __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
897           hsd->ErrorCode |= errorstate;
898           hsd->State = HAL_SD_STATE_READY;
899           hsd->Context = SD_CONTEXT_NONE;
900           return HAL_ERROR;
901         }
902       }
903     }
904 
905     /* Get error state */
906     if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
907     {
908       /* Clear all the static flags */
909       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
910       hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
911       hsd->State = HAL_SD_STATE_READY;
912       hsd->Context = SD_CONTEXT_NONE;
913       return HAL_ERROR;
914     }
915     else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
916     {
917       /* Clear all the static flags */
918       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
919       hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
920       hsd->State = HAL_SD_STATE_READY;
921       hsd->Context = SD_CONTEXT_NONE;
922       return HAL_ERROR;
923     }
924     else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR))
925     {
926       /* Clear all the static flags */
927       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
928       hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN;
929       hsd->State = HAL_SD_STATE_READY;
930       hsd->Context = SD_CONTEXT_NONE;
931       return HAL_ERROR;
932     }
933     else
934     {
935       /* Nothing to do */
936     }
937 
938     /* Clear all the static flags */
939     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
940 
941     hsd->State = HAL_SD_STATE_READY;
942 
943     return HAL_OK;
944   }
945   else
946   {
947     hsd->ErrorCode |= HAL_SD_ERROR_BUSY;
948     return HAL_ERROR;
949   }
950 }
951 
952 /**
953   * @brief  Reads block(s) from a specified address in a card. The Data transfer
954   *         is managed in interrupt mode.
955   * @note   This API should be followed by a check on the card state through
956   *         HAL_SD_GetCardState().
957   * @note   You could also check the IT transfer process through the SD Rx
958   *         interrupt event.
959   * @param  hsd: Pointer to SD handle
960   * @param  pData: Pointer to the buffer that will contain the received data
961   * @param  BlockAdd: Block Address from where data is to be read
962   * @param  NumberOfBlocks: Number of blocks to read.
963   * @retval HAL status
964   */
HAL_SD_ReadBlocks_IT(SD_HandleTypeDef * hsd,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)965 HAL_StatusTypeDef HAL_SD_ReadBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
966 {
967   SDIO_DataInitTypeDef config;
968   uint32_t errorstate;
969   uint32_t add = BlockAdd;
970 
971   if(NULL == pData)
972   {
973     hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
974     return HAL_ERROR;
975   }
976 
977   if(hsd->State == HAL_SD_STATE_READY)
978   {
979     hsd->ErrorCode = HAL_SD_ERROR_NONE;
980 
981     if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
982     {
983       hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
984       return HAL_ERROR;
985     }
986 
987     hsd->State = HAL_SD_STATE_BUSY;
988 
989     /* Initialize data control register */
990     hsd->Instance->DCTRL = 0U;
991 
992     hsd->pRxBuffPtr = pData;
993     hsd->RxXferSize = BLOCKSIZE * NumberOfBlocks;
994 
995     __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF));
996 
997     if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
998     {
999       add *= 512U;
1000     }
1001 
1002     /* Configure the SD DPSM (Data Path State Machine) */
1003     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1004     config.DataLength    = BLOCKSIZE * NumberOfBlocks;
1005     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1006     config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
1007     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
1008     config.DPSM          = SDIO_DPSM_ENABLE;
1009     (void)SDIO_ConfigData(hsd->Instance, &config);
1010 
1011     /* Read Blocks in IT mode */
1012     if(NumberOfBlocks > 1U)
1013     {
1014       hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_IT);
1015 
1016       /* Read Multi Block command */
1017       errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add);
1018     }
1019     else
1020     {
1021       hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_IT);
1022 
1023       /* Read Single Block command */
1024       errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add);
1025     }
1026     if(errorstate != HAL_SD_ERROR_NONE)
1027     {
1028       /* Clear all the static flags */
1029       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1030       hsd->ErrorCode |= errorstate;
1031       hsd->State = HAL_SD_STATE_READY;
1032       hsd->Context = SD_CONTEXT_NONE;
1033       return HAL_ERROR;
1034     }
1035 
1036     return HAL_OK;
1037   }
1038   else
1039   {
1040     return HAL_BUSY;
1041   }
1042 }
1043 
1044 /**
1045   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1046   *         is managed in interrupt mode.
1047   * @note   This API should be followed by a check on the card state through
1048   *         HAL_SD_GetCardState().
1049   * @note   You could also check the IT transfer process through the SD Tx
1050   *         interrupt event.
1051   * @param  hsd: Pointer to SD handle
1052   * @param  pData: Pointer to the buffer that will contain the data to transmit
1053   * @param  BlockAdd: Block Address where data will be written
1054   * @param  NumberOfBlocks: Number of blocks to write
1055   * @retval HAL status
1056   */
HAL_SD_WriteBlocks_IT(SD_HandleTypeDef * hsd,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1057 HAL_StatusTypeDef HAL_SD_WriteBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1058 {
1059   SDIO_DataInitTypeDef config;
1060   uint32_t errorstate;
1061   uint32_t add = BlockAdd;
1062 
1063   if(NULL == pData)
1064   {
1065     hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
1066     return HAL_ERROR;
1067   }
1068 
1069   if(hsd->State == HAL_SD_STATE_READY)
1070   {
1071     hsd->ErrorCode = HAL_SD_ERROR_NONE;
1072 
1073     if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
1074     {
1075       hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
1076       return HAL_ERROR;
1077     }
1078 
1079     hsd->State = HAL_SD_STATE_BUSY;
1080 
1081     /* Initialize data control register */
1082     hsd->Instance->DCTRL = 0U;
1083 
1084     hsd->pTxBuffPtr = pData;
1085     hsd->TxXferSize = BLOCKSIZE * NumberOfBlocks;
1086 
1087     /* Enable transfer interrupts */
1088     __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE));
1089 
1090     if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
1091     {
1092       add *= 512U;
1093     }
1094 
1095     /* Write Blocks in Polling mode */
1096     if(NumberOfBlocks > 1U)
1097     {
1098       hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK| SD_CONTEXT_IT);
1099 
1100       /* Write Multi Block command */
1101       errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add);
1102     }
1103     else
1104     {
1105       hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_IT);
1106 
1107       /* Write Single Block command */
1108       errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add);
1109     }
1110     if(errorstate != HAL_SD_ERROR_NONE)
1111     {
1112       /* Clear all the static flags */
1113       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1114       hsd->ErrorCode |= errorstate;
1115       hsd->State = HAL_SD_STATE_READY;
1116       hsd->Context = SD_CONTEXT_NONE;
1117       return HAL_ERROR;
1118     }
1119 
1120     /* Configure the SD DPSM (Data Path State Machine) */
1121     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1122     config.DataLength    = BLOCKSIZE * NumberOfBlocks;
1123     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1124     config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
1125     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
1126     config.DPSM          = SDIO_DPSM_ENABLE;
1127     (void)SDIO_ConfigData(hsd->Instance, &config);
1128 
1129     return HAL_OK;
1130   }
1131   else
1132   {
1133     return HAL_BUSY;
1134   }
1135 }
1136 
1137 /**
1138   * @brief  Reads block(s) from a specified address in a card. The Data transfer
1139   *         is managed by DMA mode.
1140   * @note   This API should be followed by a check on the card state through
1141   *         HAL_SD_GetCardState().
1142   * @note   You could also check the DMA transfer process through the SD Rx
1143   *         interrupt event.
1144   * @param  hsd: Pointer SD handle
1145   * @param  pData: Pointer to the buffer that will contain the received data
1146   * @param  BlockAdd: Block Address from where data is to be read
1147   * @param  NumberOfBlocks: Number of blocks to read.
1148   * @retval HAL status
1149   */
HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef * hsd,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1150 HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1151 {
1152   SDIO_DataInitTypeDef config;
1153   uint32_t errorstate;
1154   uint32_t add = BlockAdd;
1155 
1156   if(NULL == pData)
1157   {
1158     hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
1159     return HAL_ERROR;
1160   }
1161 
1162   if(hsd->State == HAL_SD_STATE_READY)
1163   {
1164     hsd->ErrorCode = HAL_SD_ERROR_NONE;
1165 
1166     if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
1167     {
1168       hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
1169       return HAL_ERROR;
1170     }
1171 
1172     hsd->State = HAL_SD_STATE_BUSY;
1173 
1174     /* Initialize data control register */
1175     hsd->Instance->DCTRL = 0U;
1176 
1177     __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1178 
1179     /* Set the DMA transfer complete callback */
1180     hsd->hdmarx->XferCpltCallback = SD_DMAReceiveCplt;
1181 
1182     /* Set the DMA error callback */
1183     hsd->hdmarx->XferErrorCallback = SD_DMAError;
1184 
1185     /* Set the DMA Abort callback */
1186     hsd->hdmarx->XferAbortCallback = NULL;
1187 
1188     /* Force DMA Direction */
1189     hsd->hdmarx->Init.Direction = DMA_PERIPH_TO_MEMORY;
1190     MODIFY_REG(hsd->hdmarx->Instance->CR, DMA_SxCR_DIR, hsd->hdmarx->Init.Direction);
1191 
1192     /* Enable the DMA Channel */
1193     if(HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4U) != HAL_OK)
1194     {
1195       __HAL_SD_DISABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1196       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1197       hsd->ErrorCode |= HAL_SD_ERROR_DMA;
1198       hsd->State = HAL_SD_STATE_READY;
1199       return HAL_ERROR;
1200     }
1201     else
1202     {
1203       /* Enable SD DMA transfer */
1204       __HAL_SD_DMA_ENABLE(hsd);
1205 
1206       if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
1207       {
1208         add *= 512U;
1209       }
1210 
1211       /* Configure the SD DPSM (Data Path State Machine) */
1212       config.DataTimeOut   = SDMMC_DATATIMEOUT;
1213       config.DataLength    = BLOCKSIZE * NumberOfBlocks;
1214       config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1215       config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
1216       config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
1217       config.DPSM          = SDIO_DPSM_ENABLE;
1218       (void)SDIO_ConfigData(hsd->Instance, &config);
1219 
1220       /* Read Blocks in DMA mode */
1221       if(NumberOfBlocks > 1U)
1222       {
1223         hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
1224 
1225         /* Read Multi Block command */
1226         errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add);
1227       }
1228       else
1229       {
1230         hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_DMA);
1231 
1232         /* Read Single Block command */
1233         errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add);
1234       }
1235       if(errorstate != HAL_SD_ERROR_NONE)
1236       {
1237         /* Clear all the static flags */
1238         __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1239         hsd->ErrorCode |= errorstate;
1240         hsd->State = HAL_SD_STATE_READY;
1241         hsd->Context = SD_CONTEXT_NONE;
1242         return HAL_ERROR;
1243       }
1244 
1245       return HAL_OK;
1246     }
1247   }
1248   else
1249   {
1250     return HAL_BUSY;
1251   }
1252 }
1253 
1254 /**
1255   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1256   *         is managed by DMA mode.
1257   * @note   This API should be followed by a check on the card state through
1258   *         HAL_SD_GetCardState().
1259   * @note   You could also check the DMA transfer process through the SD Tx
1260   *         interrupt event.
1261   * @param  hsd: Pointer to SD handle
1262   * @param  pData: Pointer to the buffer that will contain the data to transmit
1263   * @param  BlockAdd: Block Address where data will be written
1264   * @param  NumberOfBlocks: Number of blocks to write
1265   * @retval HAL status
1266   */
HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef * hsd,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1267 HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1268 {
1269   SDIO_DataInitTypeDef config;
1270   uint32_t errorstate;
1271   uint32_t add = BlockAdd;
1272 
1273   if(NULL == pData)
1274   {
1275     hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
1276     return HAL_ERROR;
1277   }
1278 
1279   if(hsd->State == HAL_SD_STATE_READY)
1280   {
1281     hsd->ErrorCode = HAL_SD_ERROR_NONE;
1282 
1283     if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
1284     {
1285       hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
1286       return HAL_ERROR;
1287     }
1288 
1289     hsd->State = HAL_SD_STATE_BUSY;
1290 
1291     /* Initialize data control register */
1292     hsd->Instance->DCTRL = 0U;
1293 
1294     /* Enable SD Error interrupts */
1295     __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
1296 
1297     /* Set the DMA transfer complete callback */
1298     hsd->hdmatx->XferCpltCallback = SD_DMATransmitCplt;
1299 
1300     /* Set the DMA error callback */
1301     hsd->hdmatx->XferErrorCallback = SD_DMAError;
1302 
1303     /* Set the DMA Abort callback */
1304     hsd->hdmatx->XferAbortCallback = NULL;
1305 
1306     if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
1307     {
1308       add *= 512U;
1309     }
1310 
1311     /* Write Blocks in Polling mode */
1312     if(NumberOfBlocks > 1U)
1313     {
1314       hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
1315 
1316       /* Write Multi Block command */
1317       errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add);
1318     }
1319     else
1320     {
1321       hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_DMA);
1322 
1323       /* Write Single Block command */
1324       errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add);
1325     }
1326     if(errorstate != HAL_SD_ERROR_NONE)
1327     {
1328       /* Clear all the static flags */
1329       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1330       hsd->ErrorCode |= errorstate;
1331       hsd->State = HAL_SD_STATE_READY;
1332       hsd->Context = SD_CONTEXT_NONE;
1333       return HAL_ERROR;
1334     }
1335 
1336     /* Enable SDIO DMA transfer */
1337     __HAL_SD_DMA_ENABLE(hsd);
1338 
1339     /* Force DMA Direction */
1340     hsd->hdmatx->Init.Direction = DMA_MEMORY_TO_PERIPH;
1341     MODIFY_REG(hsd->hdmatx->Instance->CR, DMA_SxCR_DIR, hsd->hdmatx->Init.Direction);
1342 
1343     /* Enable the DMA Channel */
1344     if(HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pData, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4U) != HAL_OK)
1345     {
1346       __HAL_SD_DISABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
1347       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1348       hsd->ErrorCode |= HAL_SD_ERROR_DMA;
1349       hsd->State = HAL_SD_STATE_READY;
1350       hsd->Context = SD_CONTEXT_NONE;
1351       return HAL_ERROR;
1352     }
1353     else
1354     {
1355       /* Configure the SD DPSM (Data Path State Machine) */
1356       config.DataTimeOut   = SDMMC_DATATIMEOUT;
1357       config.DataLength    = BLOCKSIZE * NumberOfBlocks;
1358       config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1359       config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
1360       config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
1361       config.DPSM          = SDIO_DPSM_ENABLE;
1362       (void)SDIO_ConfigData(hsd->Instance, &config);
1363 
1364       return HAL_OK;
1365     }
1366   }
1367   else
1368   {
1369     return HAL_BUSY;
1370   }
1371 }
1372 
1373 /**
1374   * @brief  Erases the specified memory area of the given SD card.
1375   * @note   This API should be followed by a check on the card state through
1376   *         HAL_SD_GetCardState().
1377   * @param  hsd: Pointer to SD handle
1378   * @param  BlockStartAdd: Start Block address
1379   * @param  BlockEndAdd: End Block address
1380   * @retval HAL status
1381   */
HAL_SD_Erase(SD_HandleTypeDef * hsd,uint32_t BlockStartAdd,uint32_t BlockEndAdd)1382 HAL_StatusTypeDef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1383 {
1384   uint32_t errorstate;
1385   uint32_t start_add = BlockStartAdd;
1386   uint32_t end_add = BlockEndAdd;
1387 
1388   if(hsd->State == HAL_SD_STATE_READY)
1389   {
1390     hsd->ErrorCode = HAL_SD_ERROR_NONE;
1391 
1392     if(end_add < start_add)
1393     {
1394       hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
1395       return HAL_ERROR;
1396     }
1397 
1398     if(end_add > (hsd->SdCard.LogBlockNbr))
1399     {
1400       hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
1401       return HAL_ERROR;
1402     }
1403 
1404     hsd->State = HAL_SD_STATE_BUSY;
1405 
1406     /* Check if the card command class supports erase command */
1407     if(((hsd->SdCard.Class) & SDIO_CCCC_ERASE) == 0U)
1408     {
1409       /* Clear all the static flags */
1410       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1411       hsd->ErrorCode |= HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
1412       hsd->State = HAL_SD_STATE_READY;
1413       return HAL_ERROR;
1414     }
1415 
1416     if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1417     {
1418       /* Clear all the static flags */
1419       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1420       hsd->ErrorCode |= HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
1421       hsd->State = HAL_SD_STATE_READY;
1422       return HAL_ERROR;
1423     }
1424 
1425     /* Get start and end block for high capacity cards */
1426     if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
1427     {
1428       start_add *= 512U;
1429       end_add   *= 512U;
1430     }
1431 
1432     /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */
1433     if(hsd->SdCard.CardType != CARD_SECURED)
1434     {
1435       /* Send CMD32 SD_ERASE_GRP_START with argument as addr  */
1436       errorstate = SDMMC_CmdSDEraseStartAdd(hsd->Instance, start_add);
1437       if(errorstate != HAL_SD_ERROR_NONE)
1438       {
1439         /* Clear all the static flags */
1440         __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1441         hsd->ErrorCode |= errorstate;
1442         hsd->State = HAL_SD_STATE_READY;
1443         return HAL_ERROR;
1444       }
1445 
1446       /* Send CMD33 SD_ERASE_GRP_END with argument as addr  */
1447       errorstate = SDMMC_CmdSDEraseEndAdd(hsd->Instance, end_add);
1448       if(errorstate != HAL_SD_ERROR_NONE)
1449       {
1450         /* Clear all the static flags */
1451         __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1452         hsd->ErrorCode |= errorstate;
1453         hsd->State = HAL_SD_STATE_READY;
1454         return HAL_ERROR;
1455       }
1456     }
1457 
1458     /* Send CMD38 ERASE */
1459     errorstate = SDMMC_CmdErase(hsd->Instance);
1460     if(errorstate != HAL_SD_ERROR_NONE)
1461     {
1462       /* Clear all the static flags */
1463       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1464       hsd->ErrorCode |= errorstate;
1465       hsd->State = HAL_SD_STATE_READY;
1466       return HAL_ERROR;
1467     }
1468 
1469     hsd->State = HAL_SD_STATE_READY;
1470 
1471     return HAL_OK;
1472   }
1473   else
1474   {
1475     return HAL_BUSY;
1476   }
1477 }
1478 
1479 /**
1480   * @brief  This function handles SD card interrupt request.
1481   * @param  hsd: Pointer to SD handle
1482   * @retval None
1483   */
HAL_SD_IRQHandler(SD_HandleTypeDef * hsd)1484 void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd)
1485 {
1486   uint32_t errorstate;
1487   uint32_t context = hsd->Context;
1488 
1489   /* Check for SDIO interrupt flags */
1490   if((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF) != RESET) && ((context & SD_CONTEXT_IT) != 0U))
1491   {
1492     SD_Read_IT(hsd);
1493   }
1494 
1495   else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DATAEND) != RESET)
1496   {
1497     __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DATAEND);
1498 
1499     __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND  | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1500                              SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR  | SDIO_IT_TXFIFOHE |\
1501                              SDIO_IT_RXFIFOHF);
1502 
1503     hsd->Instance->DCTRL &= ~(SDIO_DCTRL_DTEN);
1504 
1505     if((context & SD_CONTEXT_IT) != 0U)
1506     {
1507       if(((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1508       {
1509         errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
1510         if(errorstate != HAL_SD_ERROR_NONE)
1511         {
1512           hsd->ErrorCode |= errorstate;
1513 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1514           hsd->ErrorCallback(hsd);
1515 #else
1516           HAL_SD_ErrorCallback(hsd);
1517 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
1518         }
1519       }
1520 
1521       /* Clear all the static flags */
1522       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
1523 
1524       hsd->State = HAL_SD_STATE_READY;
1525       hsd->Context = SD_CONTEXT_NONE;
1526       if(((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1527       {
1528 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1529         hsd->RxCpltCallback(hsd);
1530 #else
1531         HAL_SD_RxCpltCallback(hsd);
1532 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
1533       }
1534       else
1535       {
1536 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1537         hsd->TxCpltCallback(hsd);
1538 #else
1539         HAL_SD_TxCpltCallback(hsd);
1540 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
1541       }
1542     }
1543     else if((context & SD_CONTEXT_DMA) != 0U)
1544     {
1545       if((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1546       {
1547         errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
1548         if(errorstate != HAL_SD_ERROR_NONE)
1549         {
1550           hsd->ErrorCode |= errorstate;
1551 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1552           hsd->ErrorCallback(hsd);
1553 #else
1554           HAL_SD_ErrorCallback(hsd);
1555 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
1556         }
1557       }
1558       if(((context & SD_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
1559       {
1560         /* Disable the DMA transfer for transmit request by setting the DMAEN bit
1561         in the SD DCTRL register */
1562         hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
1563 
1564         hsd->State = HAL_SD_STATE_READY;
1565 
1566 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1567         hsd->TxCpltCallback(hsd);
1568 #else
1569         HAL_SD_TxCpltCallback(hsd);
1570 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
1571       }
1572     }
1573     else
1574     {
1575       /* Nothing to do */
1576     }
1577   }
1578 
1579   else if((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE) != RESET) && ((context & SD_CONTEXT_IT) != 0U))
1580   {
1581     SD_Write_IT(hsd);
1582   }
1583 
1584   else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_RXOVERR | SDIO_FLAG_TXUNDERR) != RESET)
1585   {
1586     /* Set Error code */
1587     if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL) != RESET)
1588     {
1589       hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
1590     }
1591     if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT) != RESET)
1592     {
1593       hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
1594     }
1595     if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR) != RESET)
1596     {
1597       hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN;
1598     }
1599     if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR) != RESET)
1600     {
1601       hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN;
1602     }
1603 
1604     /* Clear All flags */
1605     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS | SDIO_FLAG_STBITERR);
1606 
1607     /* Disable all interrupts */
1608     __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1609                              SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
1610 
1611     hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
1612 
1613     if((context & SD_CONTEXT_IT) != 0U)
1614     {
1615       /* Set the SD state to ready to be able to start again the process */
1616       hsd->State = HAL_SD_STATE_READY;
1617       hsd->Context = SD_CONTEXT_NONE;
1618 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1619       hsd->ErrorCallback(hsd);
1620 #else
1621       HAL_SD_ErrorCallback(hsd);
1622 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
1623     }
1624     else if((context & SD_CONTEXT_DMA) != 0U)
1625     {
1626       /* Abort the SD DMA channel */
1627       if(((context & SD_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1628       {
1629         /* Set the DMA Tx abort callback */
1630         hsd->hdmatx->XferAbortCallback = SD_DMATxAbort;
1631         /* Abort DMA in IT mode */
1632         if(HAL_DMA_Abort_IT(hsd->hdmatx) != HAL_OK)
1633         {
1634           SD_DMATxAbort(hsd->hdmatx);
1635         }
1636       }
1637       else if(((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1638       {
1639         /* Set the DMA Rx abort callback */
1640         hsd->hdmarx->XferAbortCallback = SD_DMARxAbort;
1641         /* Abort DMA in IT mode */
1642         if(HAL_DMA_Abort_IT(hsd->hdmarx) != HAL_OK)
1643         {
1644           SD_DMARxAbort(hsd->hdmarx);
1645         }
1646       }
1647       else
1648       {
1649         hsd->ErrorCode = HAL_SD_ERROR_NONE;
1650         hsd->State = HAL_SD_STATE_READY;
1651         hsd->Context = SD_CONTEXT_NONE;
1652 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1653         hsd->AbortCpltCallback(hsd);
1654 #else
1655         HAL_SD_AbortCallback(hsd);
1656 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
1657       }
1658     }
1659     else
1660     {
1661       /* Nothing to do */
1662     }
1663   }
1664   else
1665   {
1666     /* Nothing to do */
1667   }
1668 }
1669 
1670 /**
1671   * @brief return the SD state
1672   * @param hsd: Pointer to sd handle
1673   * @retval HAL state
1674   */
HAL_SD_GetState(SD_HandleTypeDef * hsd)1675 HAL_SD_StateTypeDef HAL_SD_GetState(SD_HandleTypeDef *hsd)
1676 {
1677   return hsd->State;
1678 }
1679 
1680 /**
1681 * @brief  Return the SD error code
1682 * @param  hsd : Pointer to a SD_HandleTypeDef structure that contains
1683   *              the configuration information.
1684 * @retval SD Error Code
1685 */
HAL_SD_GetError(SD_HandleTypeDef * hsd)1686 uint32_t HAL_SD_GetError(SD_HandleTypeDef *hsd)
1687 {
1688   return hsd->ErrorCode;
1689 }
1690 
1691 /**
1692   * @brief Tx Transfer completed callbacks
1693   * @param hsd: Pointer to SD handle
1694   * @retval None
1695   */
HAL_SD_TxCpltCallback(SD_HandleTypeDef * hsd)1696 __weak void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
1697 {
1698   /* Prevent unused argument(s) compilation warning */
1699   UNUSED(hsd);
1700 
1701   /* NOTE : This function should not be modified, when the callback is needed,
1702             the HAL_SD_TxCpltCallback can be implemented in the user file
1703    */
1704 }
1705 
1706 /**
1707   * @brief Rx Transfer completed callbacks
1708   * @param hsd: Pointer SD handle
1709   * @retval None
1710   */
HAL_SD_RxCpltCallback(SD_HandleTypeDef * hsd)1711 __weak void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
1712 {
1713   /* Prevent unused argument(s) compilation warning */
1714   UNUSED(hsd);
1715 
1716   /* NOTE : This function should not be modified, when the callback is needed,
1717             the HAL_SD_RxCpltCallback can be implemented in the user file
1718    */
1719 }
1720 
1721 /**
1722   * @brief SD error callbacks
1723   * @param hsd: Pointer SD handle
1724   * @retval None
1725   */
HAL_SD_ErrorCallback(SD_HandleTypeDef * hsd)1726 __weak void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
1727 {
1728   /* Prevent unused argument(s) compilation warning */
1729   UNUSED(hsd);
1730 
1731   /* NOTE : This function should not be modified, when the callback is needed,
1732             the HAL_SD_ErrorCallback can be implemented in the user file
1733    */
1734 }
1735 
1736 /**
1737   * @brief SD Abort callbacks
1738   * @param hsd: Pointer SD handle
1739   * @retval None
1740   */
HAL_SD_AbortCallback(SD_HandleTypeDef * hsd)1741 __weak void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
1742 {
1743   /* Prevent unused argument(s) compilation warning */
1744   UNUSED(hsd);
1745 
1746   /* NOTE : This function should not be modified, when the callback is needed,
1747             the HAL_SD_AbortCallback can be implemented in the user file
1748    */
1749 }
1750 
1751 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1752 /**
1753   * @brief  Register a User SD Callback
1754   *         To be used instead of the weak (surcharged) predefined callback
1755   * @param hsd : SD handle
1756   * @param CallbackID : ID of the callback to be registered
1757   *        This parameter can be one of the following values:
1758   *          @arg @ref HAL_SD_TX_CPLT_CB_ID    SD Tx Complete Callback ID
1759   *          @arg @ref HAL_SD_RX_CPLT_CB_ID    SD Rx Complete Callback ID
1760   *          @arg @ref HAL_SD_ERROR_CB_ID      SD Error Callback ID
1761   *          @arg @ref HAL_SD_ABORT_CB_ID      SD Abort Callback ID
1762   *          @arg @ref HAL_SD_MSP_INIT_CB_ID   SD MspInit Callback ID
1763   *          @arg @ref HAL_SD_MSP_DEINIT_CB_ID SD MspDeInit Callback ID
1764   * @param pCallback : pointer to the Callback function
1765   * @retval status
1766   */
HAL_SD_RegisterCallback(SD_HandleTypeDef * hsd,HAL_SD_CallbackIDTypeDef CallbackID,pSD_CallbackTypeDef pCallback)1767 HAL_StatusTypeDef HAL_SD_RegisterCallback(SD_HandleTypeDef *hsd, HAL_SD_CallbackIDTypeDef CallbackID, pSD_CallbackTypeDef pCallback)
1768 {
1769   HAL_StatusTypeDef status = HAL_OK;
1770 
1771   if(pCallback == NULL)
1772   {
1773     /* Update the error code */
1774     hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1775     return HAL_ERROR;
1776   }
1777 
1778   /* Process locked */
1779   __HAL_LOCK(hsd);
1780 
1781   if(hsd->State == HAL_SD_STATE_READY)
1782   {
1783     switch (CallbackID)
1784     {
1785     case HAL_SD_TX_CPLT_CB_ID :
1786       hsd->TxCpltCallback = pCallback;
1787       break;
1788     case HAL_SD_RX_CPLT_CB_ID :
1789       hsd->RxCpltCallback = pCallback;
1790       break;
1791     case HAL_SD_ERROR_CB_ID :
1792       hsd->ErrorCallback = pCallback;
1793       break;
1794     case HAL_SD_ABORT_CB_ID :
1795       hsd->AbortCpltCallback = pCallback;
1796       break;
1797     case HAL_SD_MSP_INIT_CB_ID :
1798       hsd->MspInitCallback = pCallback;
1799       break;
1800     case HAL_SD_MSP_DEINIT_CB_ID :
1801       hsd->MspDeInitCallback = pCallback;
1802       break;
1803     default :
1804       /* Update the error code */
1805       hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1806       /* update return status */
1807       status =  HAL_ERROR;
1808       break;
1809     }
1810   }
1811   else if (hsd->State == HAL_SD_STATE_RESET)
1812   {
1813     switch (CallbackID)
1814     {
1815     case HAL_SD_MSP_INIT_CB_ID :
1816       hsd->MspInitCallback = pCallback;
1817       break;
1818     case HAL_SD_MSP_DEINIT_CB_ID :
1819       hsd->MspDeInitCallback = pCallback;
1820       break;
1821     default :
1822       /* Update the error code */
1823       hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1824       /* update return status */
1825       status =  HAL_ERROR;
1826       break;
1827     }
1828   }
1829   else
1830   {
1831     /* Update the error code */
1832     hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1833     /* update return status */
1834     status =  HAL_ERROR;
1835   }
1836 
1837   /* Release Lock */
1838   __HAL_UNLOCK(hsd);
1839   return status;
1840 }
1841 
1842 /**
1843   * @brief  Unregister a User SD Callback
1844   *         SD Callback is redirected to the weak (surcharged) predefined callback
1845   * @param hsd : SD handle
1846   * @param CallbackID : ID of the callback to be unregistered
1847   *        This parameter can be one of the following values:
1848   *          @arg @ref HAL_SD_TX_CPLT_CB_ID    SD Tx Complete Callback ID
1849   *          @arg @ref HAL_SD_RX_CPLT_CB_ID    SD Rx Complete Callback ID
1850   *          @arg @ref HAL_SD_ERROR_CB_ID      SD Error Callback ID
1851   *          @arg @ref HAL_SD_ABORT_CB_ID      SD Abort Callback ID
1852   *          @arg @ref HAL_SD_MSP_INIT_CB_ID   SD MspInit Callback ID
1853   *          @arg @ref HAL_SD_MSP_DEINIT_CB_ID SD MspDeInit Callback ID
1854   * @retval status
1855   */
HAL_SD_UnRegisterCallback(SD_HandleTypeDef * hsd,HAL_SD_CallbackIDTypeDef CallbackID)1856 HAL_StatusTypeDef HAL_SD_UnRegisterCallback(SD_HandleTypeDef *hsd, HAL_SD_CallbackIDTypeDef CallbackID)
1857 {
1858   HAL_StatusTypeDef status = HAL_OK;
1859 
1860   /* Process locked */
1861   __HAL_LOCK(hsd);
1862 
1863   if(hsd->State == HAL_SD_STATE_READY)
1864   {
1865     switch (CallbackID)
1866     {
1867     case HAL_SD_TX_CPLT_CB_ID :
1868       hsd->TxCpltCallback = HAL_SD_TxCpltCallback;
1869       break;
1870     case HAL_SD_RX_CPLT_CB_ID :
1871       hsd->RxCpltCallback = HAL_SD_RxCpltCallback;
1872       break;
1873     case HAL_SD_ERROR_CB_ID :
1874       hsd->ErrorCallback = HAL_SD_ErrorCallback;
1875       break;
1876     case HAL_SD_ABORT_CB_ID :
1877       hsd->AbortCpltCallback = HAL_SD_AbortCallback;
1878       break;
1879     case HAL_SD_MSP_INIT_CB_ID :
1880       hsd->MspInitCallback = HAL_SD_MspInit;
1881       break;
1882     case HAL_SD_MSP_DEINIT_CB_ID :
1883       hsd->MspDeInitCallback = HAL_SD_MspDeInit;
1884       break;
1885     default :
1886       /* Update the error code */
1887       hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1888       /* update return status */
1889       status =  HAL_ERROR;
1890       break;
1891     }
1892   }
1893   else if (hsd->State == HAL_SD_STATE_RESET)
1894   {
1895     switch (CallbackID)
1896     {
1897     case HAL_SD_MSP_INIT_CB_ID :
1898       hsd->MspInitCallback = HAL_SD_MspInit;
1899       break;
1900     case HAL_SD_MSP_DEINIT_CB_ID :
1901       hsd->MspDeInitCallback = HAL_SD_MspDeInit;
1902       break;
1903     default :
1904       /* Update the error code */
1905       hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1906       /* update return status */
1907       status =  HAL_ERROR;
1908       break;
1909     }
1910   }
1911   else
1912   {
1913     /* Update the error code */
1914     hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1915     /* update return status */
1916     status =  HAL_ERROR;
1917   }
1918 
1919   /* Release Lock */
1920   __HAL_UNLOCK(hsd);
1921   return status;
1922 }
1923 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
1924 
1925 /**
1926   * @}
1927   */
1928 
1929 /** @addtogroup SD_Exported_Functions_Group3
1930  *  @brief   management functions
1931  *
1932 @verbatim
1933   ==============================================================================
1934                       ##### Peripheral Control functions #####
1935   ==============================================================================
1936   [..]
1937     This subsection provides a set of functions allowing to control the SD card
1938     operations and get the related information
1939 
1940 @endverbatim
1941   * @{
1942   */
1943 
1944 /**
1945   * @brief  Returns information the information of the card which are stored on
1946   *         the CID register.
1947   * @param  hsd: Pointer to SD handle
1948   * @param  pCID: Pointer to a HAL_SD_CardCIDTypeDef structure that
1949   *         contains all CID register parameters
1950   * @retval HAL status
1951   */
HAL_SD_GetCardCID(SD_HandleTypeDef * hsd,HAL_SD_CardCIDTypeDef * pCID)1952 HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID)
1953 {
1954   pCID->ManufacturerID = (uint8_t)((hsd->CID[0] & 0xFF000000U) >> 24U);
1955 
1956   pCID->OEM_AppliID = (uint16_t)((hsd->CID[0] & 0x00FFFF00U) >> 8U);
1957 
1958   pCID->ProdName1 = (((hsd->CID[0] & 0x000000FFU) << 24U) | ((hsd->CID[1] & 0xFFFFFF00U) >> 8U));
1959 
1960   pCID->ProdName2 = (uint8_t)(hsd->CID[1] & 0x000000FFU);
1961 
1962   pCID->ProdRev = (uint8_t)((hsd->CID[2] & 0xFF000000U) >> 24U);
1963 
1964   pCID->ProdSN = (((hsd->CID[2] & 0x00FFFFFFU) << 8U) | ((hsd->CID[3] & 0xFF000000U) >> 24U));
1965 
1966   pCID->Reserved1 = (uint8_t)((hsd->CID[3] & 0x00F00000U) >> 20U);
1967 
1968   pCID->ManufactDate = (uint16_t)((hsd->CID[3] & 0x000FFF00U) >> 8U);
1969 
1970   pCID->CID_CRC = (uint8_t)((hsd->CID[3] & 0x000000FEU) >> 1U);
1971 
1972   pCID->Reserved2 = 1U;
1973 
1974   return HAL_OK;
1975 }
1976 
1977 /**
1978   * @brief  Returns information the information of the card which are stored on
1979   *         the CSD register.
1980   * @param  hsd: Pointer to SD handle
1981   * @param  pCSD: Pointer to a HAL_SD_CardCSDTypeDef structure that
1982   *         contains all CSD register parameters
1983   * @retval HAL status
1984   */
HAL_SD_GetCardCSD(SD_HandleTypeDef * hsd,HAL_SD_CardCSDTypeDef * pCSD)1985 HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD)
1986 {
1987   pCSD->CSDStruct = (uint8_t)((hsd->CSD[0] & 0xC0000000U) >> 30U);
1988 
1989   pCSD->SysSpecVersion = (uint8_t)((hsd->CSD[0] & 0x3C000000U) >> 26U);
1990 
1991   pCSD->Reserved1 = (uint8_t)((hsd->CSD[0] & 0x03000000U) >> 24U);
1992 
1993   pCSD->TAAC = (uint8_t)((hsd->CSD[0] & 0x00FF0000U) >> 16U);
1994 
1995   pCSD->NSAC = (uint8_t)((hsd->CSD[0] & 0x0000FF00U) >> 8U);
1996 
1997   pCSD->MaxBusClkFrec = (uint8_t)(hsd->CSD[0] & 0x000000FFU);
1998 
1999   pCSD->CardComdClasses = (uint16_t)((hsd->CSD[1] & 0xFFF00000U) >> 20U);
2000 
2001   pCSD->RdBlockLen = (uint8_t)((hsd->CSD[1] & 0x000F0000U) >> 16U);
2002 
2003   pCSD->PartBlockRead   = (uint8_t)((hsd->CSD[1] & 0x00008000U) >> 15U);
2004 
2005   pCSD->WrBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00004000U) >> 14U);
2006 
2007   pCSD->RdBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00002000U) >> 13U);
2008 
2009   pCSD->DSRImpl = (uint8_t)((hsd->CSD[1] & 0x00001000U) >> 12U);
2010 
2011   pCSD->Reserved2 = 0U; /*!< Reserved */
2012 
2013   if(hsd->SdCard.CardType == CARD_SDSC)
2014   {
2015     pCSD->DeviceSize = (((hsd->CSD[1] & 0x000003FFU) << 2U) | ((hsd->CSD[2] & 0xC0000000U) >> 30U));
2016 
2017     pCSD->MaxRdCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x38000000U) >> 27U);
2018 
2019     pCSD->MaxRdCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x07000000U) >> 24U);
2020 
2021     pCSD->MaxWrCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x00E00000U) >> 21U);
2022 
2023     pCSD->MaxWrCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x001C0000U) >> 18U);
2024 
2025     pCSD->DeviceSizeMul = (uint8_t)((hsd->CSD[2] & 0x00038000U) >> 15U);
2026 
2027     hsd->SdCard.BlockNbr  = (pCSD->DeviceSize + 1U) ;
2028     hsd->SdCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2029     hsd->SdCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2030 
2031     hsd->SdCard.LogBlockNbr =  (hsd->SdCard.BlockNbr) * ((hsd->SdCard.BlockSize) / 512U);
2032     hsd->SdCard.LogBlockSize = 512U;
2033   }
2034   else if(hsd->SdCard.CardType == CARD_SDHC_SDXC)
2035   {
2036     /* Byte 7 */
2037     pCSD->DeviceSize = (((hsd->CSD[1] & 0x0000003FU) << 16U) | ((hsd->CSD[2] & 0xFFFF0000U) >> 16U));
2038 
2039     hsd->SdCard.BlockNbr = ((pCSD->DeviceSize + 1U) * 1024U);
2040     hsd->SdCard.LogBlockNbr = hsd->SdCard.BlockNbr;
2041     hsd->SdCard.BlockSize = 512U;
2042     hsd->SdCard.LogBlockSize = hsd->SdCard.BlockSize;
2043   }
2044   else
2045   {
2046     /* Clear all the static flags */
2047     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2048     hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2049     hsd->State = HAL_SD_STATE_READY;
2050     return HAL_ERROR;
2051   }
2052 
2053   pCSD->EraseGrSize = (uint8_t)((hsd->CSD[2] & 0x00004000U) >> 14U);
2054 
2055   pCSD->EraseGrMul = (uint8_t)((hsd->CSD[2] & 0x00003F80U) >> 7U);
2056 
2057   pCSD->WrProtectGrSize = (uint8_t)(hsd->CSD[2] & 0x0000007FU);
2058 
2059   pCSD->WrProtectGrEnable = (uint8_t)((hsd->CSD[3] & 0x80000000U) >> 31U);
2060 
2061   pCSD->ManDeflECC = (uint8_t)((hsd->CSD[3] & 0x60000000U) >> 29U);
2062 
2063   pCSD->WrSpeedFact = (uint8_t)((hsd->CSD[3] & 0x1C000000U) >> 26U);
2064 
2065   pCSD->MaxWrBlockLen= (uint8_t)((hsd->CSD[3] & 0x03C00000U) >> 22U);
2066 
2067   pCSD->WriteBlockPaPartial = (uint8_t)((hsd->CSD[3] & 0x00200000U) >> 21U);
2068 
2069   pCSD->Reserved3 = 0;
2070 
2071   pCSD->ContentProtectAppli = (uint8_t)((hsd->CSD[3] & 0x00010000U) >> 16U);
2072 
2073   pCSD->FileFormatGroup = (uint8_t)((hsd->CSD[3] & 0x00008000U) >> 15U);
2074 
2075   pCSD->CopyFlag = (uint8_t)((hsd->CSD[3] & 0x00004000U) >> 14U);
2076 
2077   pCSD->PermWrProtect = (uint8_t)((hsd->CSD[3] & 0x00002000U) >> 13U);
2078 
2079   pCSD->TempWrProtect = (uint8_t)((hsd->CSD[3] & 0x00001000U) >> 12U);
2080 
2081   pCSD->FileFormat = (uint8_t)((hsd->CSD[3] & 0x00000C00U) >> 10U);
2082 
2083   pCSD->ECC= (uint8_t)((hsd->CSD[3] & 0x00000300U) >> 8U);
2084 
2085   pCSD->CSD_CRC = (uint8_t)((hsd->CSD[3] & 0x000000FEU) >> 1U);
2086 
2087   pCSD->Reserved4 = 1;
2088 
2089   return HAL_OK;
2090 }
2091 
2092 /**
2093   * @brief  Gets the SD status info.
2094   * @param  hsd: Pointer to SD handle
2095   * @param  pStatus: Pointer to the HAL_SD_CardStatusTypeDef structure that
2096   *         will contain the SD card status information
2097   * @retval HAL status
2098   */
HAL_SD_GetCardStatus(SD_HandleTypeDef * hsd,HAL_SD_CardStatusTypeDef * pStatus)2099 HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus)
2100 {
2101   uint32_t sd_status[16];
2102   uint32_t errorstate;
2103   HAL_StatusTypeDef status = HAL_OK;
2104 
2105   errorstate = SD_SendSDStatus(hsd, sd_status);
2106   if(errorstate != HAL_SD_ERROR_NONE)
2107   {
2108     /* Clear all the static flags */
2109     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2110     hsd->ErrorCode |= errorstate;
2111     hsd->State = HAL_SD_STATE_READY;
2112     status = HAL_ERROR;
2113   }
2114   else
2115   {
2116     pStatus->DataBusWidth = (uint8_t)((sd_status[0] & 0xC0U) >> 6U);
2117 
2118     pStatus->SecuredMode = (uint8_t)((sd_status[0] & 0x20U) >> 5U);
2119 
2120     pStatus->CardType = (uint16_t)(((sd_status[0] & 0x00FF0000U) >> 8U) | ((sd_status[0] & 0xFF000000U) >> 24U));
2121 
2122     pStatus->ProtectedAreaSize = (((sd_status[1] & 0xFFU) << 24U)    | ((sd_status[1] & 0xFF00U) << 8U) |
2123                                   ((sd_status[1] & 0xFF0000U) >> 8U) | ((sd_status[1] & 0xFF000000U) >> 24U));
2124 
2125     pStatus->SpeedClass = (uint8_t)(sd_status[2] & 0xFFU);
2126 
2127     pStatus->PerformanceMove = (uint8_t)((sd_status[2] & 0xFF00U) >> 8U);
2128 
2129     pStatus->AllocationUnitSize = (uint8_t)((sd_status[2] & 0xF00000U) >> 20U);
2130 
2131     pStatus->EraseSize = (uint16_t)(((sd_status[2] & 0xFF000000U) >> 16U) | (sd_status[3] & 0xFFU));
2132 
2133     pStatus->EraseTimeout = (uint8_t)((sd_status[3] & 0xFC00U) >> 10U);
2134 
2135     pStatus->EraseOffset = (uint8_t)((sd_status[3] & 0x0300U) >> 8U);
2136   }
2137 
2138   /* Set Block Size for Card */
2139   errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
2140   if(errorstate != HAL_SD_ERROR_NONE)
2141   {
2142     /* Clear all the static flags */
2143     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2144     hsd->ErrorCode = errorstate;
2145     hsd->State = HAL_SD_STATE_READY;
2146     status = HAL_ERROR;
2147   }
2148 
2149   return status;
2150 }
2151 
2152 /**
2153   * @brief  Gets the SD card info.
2154   * @param  hsd: Pointer to SD handle
2155   * @param  pCardInfo: Pointer to the HAL_SD_CardInfoTypeDef structure that
2156   *         will contain the SD card status information
2157   * @retval HAL status
2158   */
HAL_SD_GetCardInfo(SD_HandleTypeDef * hsd,HAL_SD_CardInfoTypeDef * pCardInfo)2159 HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo)
2160 {
2161   pCardInfo->CardType     = (uint32_t)(hsd->SdCard.CardType);
2162   pCardInfo->CardVersion  = (uint32_t)(hsd->SdCard.CardVersion);
2163   pCardInfo->Class        = (uint32_t)(hsd->SdCard.Class);
2164   pCardInfo->RelCardAdd   = (uint32_t)(hsd->SdCard.RelCardAdd);
2165   pCardInfo->BlockNbr     = (uint32_t)(hsd->SdCard.BlockNbr);
2166   pCardInfo->BlockSize    = (uint32_t)(hsd->SdCard.BlockSize);
2167   pCardInfo->LogBlockNbr  = (uint32_t)(hsd->SdCard.LogBlockNbr);
2168   pCardInfo->LogBlockSize = (uint32_t)(hsd->SdCard.LogBlockSize);
2169 
2170   return HAL_OK;
2171 }
2172 
2173 /**
2174   * @brief  Enables wide bus operation for the requested card if supported by
2175   *         card.
2176   * @param  hsd: Pointer to SD handle
2177   * @param  WideMode: Specifies the SD card wide bus mode
2178   *          This parameter can be one of the following values:
2179   *            @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
2180   *            @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
2181   *            @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
2182   * @retval HAL status
2183   */
HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef * hsd,uint32_t WideMode)2184 HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode)
2185 {
2186   SDIO_InitTypeDef Init;
2187   uint32_t errorstate;
2188   HAL_StatusTypeDef status = HAL_OK;
2189 
2190   /* Check the parameters */
2191   assert_param(IS_SDIO_BUS_WIDE(WideMode));
2192 
2193   /* Change State */
2194   hsd->State = HAL_SD_STATE_BUSY;
2195 
2196   if(hsd->SdCard.CardType != CARD_SECURED)
2197   {
2198     if(WideMode == SDIO_BUS_WIDE_8B)
2199     {
2200       hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2201     }
2202     else if(WideMode == SDIO_BUS_WIDE_4B)
2203     {
2204       errorstate = SD_WideBus_Enable(hsd);
2205 
2206       hsd->ErrorCode |= errorstate;
2207     }
2208     else if(WideMode == SDIO_BUS_WIDE_1B)
2209     {
2210       errorstate = SD_WideBus_Disable(hsd);
2211 
2212       hsd->ErrorCode |= errorstate;
2213     }
2214     else
2215     {
2216       /* WideMode is not a valid argument*/
2217       hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
2218     }
2219   }
2220   else
2221   {
2222     /* MMC Card does not support this feature */
2223     hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2224   }
2225 
2226   if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
2227   {
2228     /* Clear all the static flags */
2229     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2230     hsd->State = HAL_SD_STATE_READY;
2231     status = HAL_ERROR;
2232   }
2233   else
2234   {
2235     /* Configure the SDIO peripheral */
2236     Init.ClockEdge           = hsd->Init.ClockEdge;
2237     Init.ClockBypass         = hsd->Init.ClockBypass;
2238     Init.ClockPowerSave      = hsd->Init.ClockPowerSave;
2239     Init.BusWide             = WideMode;
2240     Init.HardwareFlowControl = hsd->Init.HardwareFlowControl;
2241     Init.ClockDiv            = hsd->Init.ClockDiv;
2242     (void)SDIO_Init(hsd->Instance, Init);
2243   }
2244 
2245   /* Set Block Size for Card */
2246   errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
2247   if(errorstate != HAL_SD_ERROR_NONE)
2248   {
2249     /* Clear all the static flags */
2250     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2251     hsd->ErrorCode |= errorstate;
2252     status = HAL_ERROR;
2253   }
2254 
2255   /* Change State */
2256   hsd->State = HAL_SD_STATE_READY;
2257 
2258   return status;
2259 }
2260 
2261 /**
2262   * @brief  Gets the current sd card data state.
2263   * @param  hsd: pointer to SD handle
2264   * @retval Card state
2265   */
HAL_SD_GetCardState(SD_HandleTypeDef * hsd)2266 HAL_SD_CardStateTypeDef HAL_SD_GetCardState(SD_HandleTypeDef *hsd)
2267 {
2268   uint32_t cardstate;
2269   uint32_t errorstate;
2270   uint32_t resp1 = 0;
2271 
2272   errorstate = SD_SendStatus(hsd, &resp1);
2273   if(errorstate != HAL_SD_ERROR_NONE)
2274   {
2275     hsd->ErrorCode |= errorstate;
2276   }
2277 
2278   cardstate = ((resp1 >> 9U) & 0x0FU);
2279 
2280   return (HAL_SD_CardStateTypeDef)cardstate;
2281 }
2282 
2283 /**
2284   * @brief  Abort the current transfer and disable the SD.
2285   * @param  hsd: pointer to a SD_HandleTypeDef structure that contains
2286   *                the configuration information for SD module.
2287   * @retval HAL status
2288   */
HAL_SD_Abort(SD_HandleTypeDef * hsd)2289 HAL_StatusTypeDef HAL_SD_Abort(SD_HandleTypeDef *hsd)
2290 {
2291   HAL_SD_CardStateTypeDef CardState;
2292   uint32_t context = hsd->Context;
2293 
2294   /* DIsable All interrupts */
2295   __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2296                            SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2297 
2298   /* Clear All flags */
2299   __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2300 
2301   CLEAR_BIT(hsd->Instance->DCTRL, SDIO_DCTRL_DTEN);
2302 
2303   if ((context & SD_CONTEXT_DMA) != 0U)
2304   {
2305     /* Disable the SD DMA request */
2306     hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2307 
2308     /* Abort the SD DMA Tx channel */
2309     if (((context & SD_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
2310     {
2311       if(HAL_DMA_Abort(hsd->hdmatx) != HAL_OK)
2312       {
2313         hsd->ErrorCode |= HAL_SD_ERROR_DMA;
2314       }
2315     }
2316     /* Abort the SD DMA Rx channel */
2317     else if (((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
2318     {
2319       if(HAL_DMA_Abort(hsd->hdmarx) != HAL_OK)
2320       {
2321         hsd->ErrorCode |= HAL_SD_ERROR_DMA;
2322       }
2323     }
2324     else
2325     {
2326       /* Nothing to do */
2327     }
2328   }
2329 
2330   hsd->State = HAL_SD_STATE_READY;
2331 
2332   /* Initialize the SD operation */
2333   hsd->Context = SD_CONTEXT_NONE;
2334 
2335   CardState = HAL_SD_GetCardState(hsd);
2336   if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
2337   {
2338     hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance);
2339   }
2340   if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
2341   {
2342     return HAL_ERROR;
2343   }
2344   return HAL_OK;
2345 }
2346 
2347 /**
2348   * @brief  Abort the current transfer and disable the SD (IT mode).
2349   * @param  hsd: pointer to a SD_HandleTypeDef structure that contains
2350   *                the configuration information for SD module.
2351   * @retval HAL status
2352   */
HAL_SD_Abort_IT(SD_HandleTypeDef * hsd)2353 HAL_StatusTypeDef HAL_SD_Abort_IT(SD_HandleTypeDef *hsd)
2354 {
2355   HAL_SD_CardStateTypeDef CardState;
2356   uint32_t context = hsd->Context;
2357 
2358   /* Disable All interrupts */
2359   __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2360                            SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2361 
2362   CLEAR_BIT(hsd->Instance->DCTRL, SDIO_DCTRL_DTEN);
2363 
2364   if ((context & SD_CONTEXT_DMA) != 0U)
2365   {
2366     /* Disable the SD DMA request */
2367     hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2368 
2369     /* Abort the SD DMA Tx channel */
2370     if (((context & SD_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
2371     {
2372       hsd->hdmatx->XferAbortCallback = SD_DMATxAbort;
2373       if(HAL_DMA_Abort_IT(hsd->hdmatx) != HAL_OK)
2374       {
2375         hsd->hdmatx = NULL;
2376       }
2377     }
2378     /* Abort the SD DMA Rx channel */
2379     else if (((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
2380     {
2381       hsd->hdmarx->XferAbortCallback = SD_DMARxAbort;
2382       if(HAL_DMA_Abort_IT(hsd->hdmarx) != HAL_OK)
2383       {
2384         hsd->hdmarx = NULL;
2385       }
2386     }
2387     else
2388     {
2389       /* Nothing to do */
2390     }
2391   }
2392   /* No transfer ongoing on both DMA channels*/
2393   else
2394   {
2395     /* Clear All flags */
2396     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2397 
2398     CardState = HAL_SD_GetCardState(hsd);
2399     hsd->State = HAL_SD_STATE_READY;
2400     hsd->Context = SD_CONTEXT_NONE;
2401     if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
2402     {
2403       hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance);
2404     }
2405     if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
2406     {
2407       return HAL_ERROR;
2408     }
2409     else
2410     {
2411 #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
2412       hsd->AbortCpltCallback(hsd);
2413 #else
2414       HAL_SD_AbortCallback(hsd);
2415 #endif /* USE_HAL_SD_REGISTER_CALLBACKS */
2416     }
2417   }
2418 
2419   return HAL_OK;
2420 }
2421 
2422 /**
2423   * @}
2424   */
2425 
2426 /**
2427   * @}
2428   */
2429 
2430 /* Private function ----------------------------------------------------------*/
2431 /** @addtogroup SD_Private_Functions
2432   * @{
2433   */
2434 
2435 /**
2436   * @brief  DMA SD transmit process complete callback
2437   * @param  hdma: DMA handle
2438   * @retval None
2439   */
SD_DMATransmitCplt(DMA_HandleTypeDef * hdma)2440 static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2441 {
2442   SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
2443 
2444   /* Enable DATAEND Interrupt */
2445   __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DATAEND));
2446 }
2447 
2448 /**
2449   * @brief  DMA SD receive process complete callback
2450   * @param  hdma: DMA handle
2451   * @retval None
2452   */
SD_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2453 static void SD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2454 {
2455   SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
2456   uint32_t errorstate;
2457 
2458   /* Send stop command in multiblock write */
2459   if(hsd->Context == (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA))
2460   {
2461     errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
2462     if(errorstate != HAL_SD_ERROR_NONE)
2463     {
2464       hsd->ErrorCode |= errorstate;
2465 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2466       hsd->ErrorCallback(hsd);
2467 #else
2468       HAL_SD_ErrorCallback(hsd);
2469 #endif
2470     }
2471   }
2472 
2473   /* Disable the DMA transfer for transmit request by setting the DMAEN bit
2474   in the SD DCTRL register */
2475   hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2476 
2477   /* Clear all the static flags */
2478   __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2479 
2480   hsd->State = HAL_SD_STATE_READY;
2481   hsd->Context = SD_CONTEXT_NONE;
2482 
2483 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2484   hsd->RxCpltCallback(hsd);
2485 #else
2486   HAL_SD_RxCpltCallback(hsd);
2487 #endif
2488 }
2489 
2490 /**
2491   * @brief  DMA SD communication error callback
2492   * @param  hdma: DMA handle
2493   * @retval None
2494   */
SD_DMAError(DMA_HandleTypeDef * hdma)2495 static void SD_DMAError(DMA_HandleTypeDef *hdma)
2496 {
2497   SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
2498   HAL_SD_CardStateTypeDef CardState;
2499   uint32_t RxErrorCode, TxErrorCode;
2500 
2501   /* if DMA error is FIFO error ignore it */
2502   if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
2503   {
2504     RxErrorCode = hsd->hdmarx->ErrorCode;
2505     TxErrorCode = hsd->hdmatx->ErrorCode;
2506     if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE))
2507     {
2508       /* Clear All flags */
2509       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2510 
2511       /* Disable All interrupts */
2512       __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2513         SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2514 
2515       hsd->ErrorCode |= HAL_SD_ERROR_DMA;
2516       CardState = HAL_SD_GetCardState(hsd);
2517       if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
2518       {
2519         hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
2520       }
2521 
2522       hsd->State= HAL_SD_STATE_READY;
2523       hsd->Context = SD_CONTEXT_NONE;
2524     }
2525 
2526 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2527     hsd->ErrorCallback(hsd);
2528 #else
2529     HAL_SD_ErrorCallback(hsd);
2530 #endif
2531   }
2532 }
2533 
2534 /**
2535   * @brief  DMA SD Tx Abort callback
2536   * @param  hdma: DMA handle
2537   * @retval None
2538   */
SD_DMATxAbort(DMA_HandleTypeDef * hdma)2539 static void SD_DMATxAbort(DMA_HandleTypeDef *hdma)
2540 {
2541   SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
2542   HAL_SD_CardStateTypeDef CardState;
2543 
2544   /* Clear All flags */
2545   __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2546 
2547   CardState = HAL_SD_GetCardState(hsd);
2548   hsd->State = HAL_SD_STATE_READY;
2549   hsd->Context = SD_CONTEXT_NONE;
2550   if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
2551   {
2552     hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
2553   }
2554 
2555   if(hsd->ErrorCode == HAL_SD_ERROR_NONE)
2556   {
2557 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2558     hsd->AbortCpltCallback(hsd);
2559 #else
2560     HAL_SD_AbortCallback(hsd);
2561 #endif
2562   }
2563   else
2564   {
2565 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2566     hsd->ErrorCallback(hsd);
2567 #else
2568     HAL_SD_ErrorCallback(hsd);
2569 #endif
2570   }
2571 }
2572 
2573 /**
2574   * @brief  DMA SD Rx Abort callback
2575   * @param  hdma: DMA handle
2576   * @retval None
2577   */
SD_DMARxAbort(DMA_HandleTypeDef * hdma)2578 static void SD_DMARxAbort(DMA_HandleTypeDef *hdma)
2579 {
2580   SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
2581   HAL_SD_CardStateTypeDef CardState;
2582 
2583   /* Clear All flags */
2584   __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2585 
2586   CardState = HAL_SD_GetCardState(hsd);
2587   hsd->State = HAL_SD_STATE_READY;
2588   hsd->Context = SD_CONTEXT_NONE;
2589   if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
2590   {
2591     hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
2592   }
2593 
2594   if(hsd->ErrorCode == HAL_SD_ERROR_NONE)
2595   {
2596 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2597     hsd->AbortCpltCallback(hsd);
2598 #else
2599     HAL_SD_AbortCallback(hsd);
2600 #endif
2601   }
2602   else
2603   {
2604 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2605     hsd->ErrorCallback(hsd);
2606 #else
2607     HAL_SD_ErrorCallback(hsd);
2608 #endif
2609   }
2610 }
2611 
2612 /**
2613   * @brief  Initializes the sd card.
2614   * @param  hsd: Pointer to SD handle
2615   * @retval SD Card error state
2616   */
SD_InitCard(SD_HandleTypeDef * hsd)2617 static uint32_t SD_InitCard(SD_HandleTypeDef *hsd)
2618 {
2619   HAL_SD_CardCSDTypeDef CSD;
2620   uint32_t errorstate;
2621   uint16_t sd_rca = 1U;
2622 
2623   /* Check the power State */
2624   if(SDIO_GetPowerState(hsd->Instance) == 0U)
2625   {
2626     /* Power off */
2627     return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
2628   }
2629 
2630   if(hsd->SdCard.CardType != CARD_SECURED)
2631   {
2632     /* Send CMD2 ALL_SEND_CID */
2633     errorstate = SDMMC_CmdSendCID(hsd->Instance);
2634     if(errorstate != HAL_SD_ERROR_NONE)
2635     {
2636       return errorstate;
2637     }
2638     else
2639     {
2640       /* Get Card identification number data */
2641       hsd->CID[0U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
2642       hsd->CID[1U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP2);
2643       hsd->CID[2U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP3);
2644       hsd->CID[3U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP4);
2645     }
2646   }
2647 
2648   if(hsd->SdCard.CardType != CARD_SECURED)
2649   {
2650     /* Send CMD3 SET_REL_ADDR with argument 0 */
2651     /* SD Card publishes its RCA. */
2652     errorstate = SDMMC_CmdSetRelAdd(hsd->Instance, &sd_rca);
2653     if(errorstate != HAL_SD_ERROR_NONE)
2654     {
2655       return errorstate;
2656     }
2657   }
2658   if(hsd->SdCard.CardType != CARD_SECURED)
2659   {
2660     /* Get the SD card RCA */
2661     hsd->SdCard.RelCardAdd = sd_rca;
2662 
2663     /* Send CMD9 SEND_CSD with argument as card's RCA */
2664     errorstate = SDMMC_CmdSendCSD(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
2665     if(errorstate != HAL_SD_ERROR_NONE)
2666     {
2667       return errorstate;
2668     }
2669     else
2670     {
2671       /* Get Card Specific Data */
2672       hsd->CSD[0U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
2673       hsd->CSD[1U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP2);
2674       hsd->CSD[2U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP3);
2675       hsd->CSD[3U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP4);
2676     }
2677   }
2678 
2679   /* Get the Card Class */
2680   hsd->SdCard.Class = (SDIO_GetResponse(hsd->Instance, SDIO_RESP2) >> 20U);
2681 
2682   /* Get CSD parameters */
2683   if (HAL_SD_GetCardCSD(hsd, &CSD) != HAL_OK)
2684   {
2685     return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2686   }
2687 
2688   /* Select the Card */
2689   errorstate = SDMMC_CmdSelDesel(hsd->Instance, (uint32_t)(((uint32_t)hsd->SdCard.RelCardAdd) << 16U));
2690   if(errorstate != HAL_SD_ERROR_NONE)
2691   {
2692     return errorstate;
2693   }
2694 
2695   /* Configure SDIO peripheral interface */
2696   (void)SDIO_Init(hsd->Instance, hsd->Init);
2697 
2698   /* All cards are initialized */
2699   return HAL_SD_ERROR_NONE;
2700 }
2701 
2702 /**
2703   * @brief  Enquires cards about their operating voltage and configures clock
2704   *         controls and stores SD information that will be needed in future
2705   *         in the SD handle.
2706   * @param  hsd: Pointer to SD handle
2707   * @retval error state
2708   */
SD_PowerON(SD_HandleTypeDef * hsd)2709 static uint32_t SD_PowerON(SD_HandleTypeDef *hsd)
2710 {
2711   __IO uint32_t count = 0U;
2712   uint32_t response = 0U, validvoltage = 0U;
2713   uint32_t errorstate;
2714 
2715   /* CMD0: GO_IDLE_STATE */
2716   errorstate = SDMMC_CmdGoIdleState(hsd->Instance);
2717   if(errorstate != HAL_SD_ERROR_NONE)
2718   {
2719     return errorstate;
2720   }
2721 
2722   /* CMD8: SEND_IF_COND: Command available only on V2.0 cards */
2723   errorstate = SDMMC_CmdOperCond(hsd->Instance);
2724   if(errorstate != HAL_SD_ERROR_NONE)
2725   {
2726     hsd->SdCard.CardVersion = CARD_V1_X;
2727     /* CMD0: GO_IDLE_STATE */
2728     errorstate = SDMMC_CmdGoIdleState(hsd->Instance);
2729     if(errorstate != HAL_SD_ERROR_NONE)
2730     {
2731       return errorstate;
2732     }
2733 
2734   }
2735   else
2736   {
2737     hsd->SdCard.CardVersion = CARD_V2_X;
2738   }
2739 
2740   if( hsd->SdCard.CardVersion == CARD_V2_X)
2741   {
2742     /* SEND CMD55 APP_CMD with RCA as 0 */
2743     errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0);
2744     if(errorstate != HAL_SD_ERROR_NONE)
2745     {
2746       return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2747     }
2748   }
2749   /* SD CARD */
2750   /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */
2751   while((count < SDMMC_MAX_VOLT_TRIAL) && (validvoltage == 0U))
2752   {
2753     /* SEND CMD55 APP_CMD with RCA as 0 */
2754     errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0);
2755     if(errorstate != HAL_SD_ERROR_NONE)
2756     {
2757       return errorstate;
2758     }
2759 
2760     /* Send CMD41 */
2761     errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY | SD_SWITCH_1_8V_CAPACITY);
2762     if(errorstate != HAL_SD_ERROR_NONE)
2763     {
2764       return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2765     }
2766 
2767     /* Get command response */
2768     response = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
2769 
2770     /* Get operating voltage*/
2771     validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
2772 
2773     count++;
2774   }
2775 
2776   if(count >= SDMMC_MAX_VOLT_TRIAL)
2777   {
2778     return HAL_SD_ERROR_INVALID_VOLTRANGE;
2779   }
2780 
2781   if((response & SDMMC_HIGH_CAPACITY) == SDMMC_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */
2782   {
2783     hsd->SdCard.CardType = CARD_SDHC_SDXC;
2784   }
2785   else
2786   {
2787     hsd->SdCard.CardType = CARD_SDSC;
2788   }
2789 
2790 
2791   return HAL_SD_ERROR_NONE;
2792 }
2793 
2794 /**
2795   * @brief  Turns the SDIO output signals off.
2796   * @param  hsd: Pointer to SD handle
2797   * @retval None
2798   */
SD_PowerOFF(SD_HandleTypeDef * hsd)2799 static void SD_PowerOFF(SD_HandleTypeDef *hsd)
2800 {
2801   /* Set Power State to OFF */
2802   (void)SDIO_PowerState_OFF(hsd->Instance);
2803 }
2804 
2805 /**
2806   * @brief  Send Status info command.
2807   * @param  hsd: pointer to SD handle
2808   * @param  pSDstatus: Pointer to the buffer that will contain the SD card status
2809   *         SD Status register)
2810   * @retval error state
2811   */
SD_SendSDStatus(SD_HandleTypeDef * hsd,uint32_t * pSDstatus)2812 static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus)
2813 {
2814   SDIO_DataInitTypeDef config;
2815   uint32_t errorstate;
2816   uint32_t tickstart = HAL_GetTick();
2817   uint32_t count;
2818   uint32_t *pData = pSDstatus;
2819 
2820   /* Check SD response */
2821   if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
2822   {
2823     return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
2824   }
2825 
2826   /* Set block size for card if it is not equal to current block size for card */
2827   errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U);
2828   if(errorstate != HAL_SD_ERROR_NONE)
2829   {
2830     hsd->ErrorCode |= HAL_SD_ERROR_NONE;
2831     return errorstate;
2832   }
2833 
2834   /* Send CMD55 */
2835   errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
2836   if(errorstate != HAL_SD_ERROR_NONE)
2837   {
2838     hsd->ErrorCode |= HAL_SD_ERROR_NONE;
2839     return errorstate;
2840   }
2841 
2842   /* Configure the SD DPSM (Data Path State Machine) */
2843   config.DataTimeOut   = SDMMC_DATATIMEOUT;
2844   config.DataLength    = 64U;
2845   config.DataBlockSize = SDIO_DATABLOCK_SIZE_64B;
2846   config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
2847   config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
2848   config.DPSM          = SDIO_DPSM_ENABLE;
2849   (void)SDIO_ConfigData(hsd->Instance, &config);
2850 
2851   /* Send ACMD13 (SD_APP_STAUS)  with argument as card's RCA */
2852   errorstate = SDMMC_CmdStatusRegister(hsd->Instance);
2853   if(errorstate != HAL_SD_ERROR_NONE)
2854   {
2855     hsd->ErrorCode |= HAL_SD_ERROR_NONE;
2856     return errorstate;
2857   }
2858 
2859   /* Get status data */
2860   while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND))
2861   {
2862     if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))
2863     {
2864       for(count = 0U; count < 8U; count++)
2865       {
2866         *pData = SDIO_ReadFIFO(hsd->Instance);
2867         pData++;
2868       }
2869     }
2870 
2871     if((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2872     {
2873       return HAL_SD_ERROR_TIMEOUT;
2874     }
2875   }
2876 
2877   if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
2878   {
2879     return HAL_SD_ERROR_DATA_TIMEOUT;
2880   }
2881   else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
2882   {
2883     return HAL_SD_ERROR_DATA_CRC_FAIL;
2884   }
2885   else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
2886   {
2887     return HAL_SD_ERROR_RX_OVERRUN;
2888   }
2889   else
2890   {
2891     /* Nothing to do */
2892   }
2893 
2894   while ((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)))
2895   {
2896     *pData = SDIO_ReadFIFO(hsd->Instance);
2897     pData++;
2898 
2899     if((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2900     {
2901       return HAL_SD_ERROR_TIMEOUT;
2902     }
2903   }
2904 
2905   /* Clear all the static status flags*/
2906   __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2907 
2908   return HAL_SD_ERROR_NONE;
2909 }
2910 
2911 /**
2912   * @brief  Returns the current card's status.
2913   * @param  hsd: Pointer to SD handle
2914   * @param  pCardStatus: pointer to the buffer that will contain the SD card
2915   *         status (Card Status register)
2916   * @retval error state
2917   */
SD_SendStatus(SD_HandleTypeDef * hsd,uint32_t * pCardStatus)2918 static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus)
2919 {
2920   uint32_t errorstate;
2921 
2922   if(pCardStatus == NULL)
2923   {
2924     return HAL_SD_ERROR_PARAM;
2925   }
2926 
2927   /* Send Status command */
2928   errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
2929   if(errorstate != HAL_SD_ERROR_NONE)
2930   {
2931     return errorstate;
2932   }
2933 
2934   /* Get SD card status */
2935   *pCardStatus = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
2936 
2937   return HAL_SD_ERROR_NONE;
2938 }
2939 
2940 /**
2941   * @brief  Enables the SDIO wide bus mode.
2942   * @param  hsd: pointer to SD handle
2943   * @retval error state
2944   */
SD_WideBus_Enable(SD_HandleTypeDef * hsd)2945 static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd)
2946 {
2947   uint32_t scr[2U] = {0U, 0U};
2948   uint32_t errorstate;
2949 
2950   if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
2951   {
2952     return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
2953   }
2954 
2955   /* Get SCR Register */
2956   errorstate = SD_FindSCR(hsd, scr);
2957   if(errorstate != HAL_SD_ERROR_NONE)
2958   {
2959     return errorstate;
2960   }
2961 
2962   /* If requested card supports wide bus operation */
2963   if((scr[1U] & SDMMC_WIDE_BUS_SUPPORT) != SDMMC_ALLZERO)
2964   {
2965     /* Send CMD55 APP_CMD with argument as card's RCA.*/
2966     errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
2967     if(errorstate != HAL_SD_ERROR_NONE)
2968     {
2969       return errorstate;
2970     }
2971 
2972     /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
2973     errorstate = SDMMC_CmdBusWidth(hsd->Instance, 2U);
2974     if(errorstate != HAL_SD_ERROR_NONE)
2975     {
2976       return errorstate;
2977     }
2978 
2979     return HAL_SD_ERROR_NONE;
2980   }
2981   else
2982   {
2983     return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
2984   }
2985 }
2986 
2987 /**
2988   * @brief  Disables the SDIO wide bus mode.
2989   * @param  hsd: Pointer to SD handle
2990   * @retval error state
2991   */
SD_WideBus_Disable(SD_HandleTypeDef * hsd)2992 static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd)
2993 {
2994   uint32_t scr[2U] = {0U, 0U};
2995   uint32_t errorstate;
2996 
2997   if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
2998   {
2999     return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
3000   }
3001 
3002   /* Get SCR Register */
3003   errorstate = SD_FindSCR(hsd, scr);
3004   if(errorstate != HAL_SD_ERROR_NONE)
3005   {
3006     return errorstate;
3007   }
3008 
3009   /* If requested card supports 1 bit mode operation */
3010   if((scr[1U] & SDMMC_SINGLE_BUS_SUPPORT) != SDMMC_ALLZERO)
3011   {
3012     /* Send CMD55 APP_CMD with argument as card's RCA */
3013     errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
3014     if(errorstate != HAL_SD_ERROR_NONE)
3015     {
3016       return errorstate;
3017     }
3018 
3019     /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */
3020     errorstate = SDMMC_CmdBusWidth(hsd->Instance, 0U);
3021     if(errorstate != HAL_SD_ERROR_NONE)
3022     {
3023       return errorstate;
3024     }
3025 
3026     return HAL_SD_ERROR_NONE;
3027   }
3028   else
3029   {
3030     return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
3031   }
3032 }
3033 
3034 
3035 /**
3036   * @brief  Finds the SD card SCR register value.
3037   * @param  hsd: Pointer to SD handle
3038   * @param  pSCR: pointer to the buffer that will contain the SCR value
3039   * @retval error state
3040   */
SD_FindSCR(SD_HandleTypeDef * hsd,uint32_t * pSCR)3041 static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR)
3042 {
3043   SDIO_DataInitTypeDef config;
3044   uint32_t errorstate;
3045   uint32_t tickstart = HAL_GetTick();
3046   uint32_t index = 0U;
3047   uint32_t tempscr[2U] = {0U, 0U};
3048   uint32_t *scr = pSCR;
3049 
3050   /* Set Block Size To 8 Bytes */
3051   errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8U);
3052   if(errorstate != HAL_SD_ERROR_NONE)
3053   {
3054     return errorstate;
3055   }
3056 
3057   /* Send CMD55 APP_CMD with argument as card's RCA */
3058   errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)((hsd->SdCard.RelCardAdd) << 16U));
3059   if(errorstate != HAL_SD_ERROR_NONE)
3060   {
3061     return errorstate;
3062   }
3063 
3064   config.DataTimeOut   = SDMMC_DATATIMEOUT;
3065   config.DataLength    = 8U;
3066   config.DataBlockSize = SDIO_DATABLOCK_SIZE_8B;
3067   config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
3068   config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
3069   config.DPSM          = SDIO_DPSM_ENABLE;
3070   (void)SDIO_ConfigData(hsd->Instance, &config);
3071 
3072   /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */
3073   errorstate = SDMMC_CmdSendSCR(hsd->Instance);
3074   if(errorstate != HAL_SD_ERROR_NONE)
3075   {
3076     return errorstate;
3077   }
3078 
3079   while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT))
3080   {
3081     if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL))
3082     {
3083       *(tempscr + index) = SDIO_ReadFIFO(hsd->Instance);
3084       index++;
3085     }
3086     else if(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXACT))
3087     {
3088       break;
3089     }
3090 
3091     if((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
3092     {
3093       return HAL_SD_ERROR_TIMEOUT;
3094     }
3095   }
3096 
3097   if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
3098   {
3099     __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);
3100 
3101     return HAL_SD_ERROR_DATA_TIMEOUT;
3102   }
3103   else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
3104   {
3105     __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);
3106 
3107     return HAL_SD_ERROR_DATA_CRC_FAIL;
3108   }
3109   else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
3110   {
3111     __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);
3112 
3113     return HAL_SD_ERROR_RX_OVERRUN;
3114   }
3115   else
3116   {
3117     /* No error flag set */
3118     /* Clear all the static flags */
3119     __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
3120 
3121     *scr = (((tempscr[1] & SDMMC_0TO7BITS) << 24)  | ((tempscr[1] & SDMMC_8TO15BITS) << 8) |\
3122             ((tempscr[1] & SDMMC_16TO23BITS) >> 8) | ((tempscr[1] & SDMMC_24TO31BITS) >> 24));
3123     scr++;
3124     *scr = (((tempscr[0] & SDMMC_0TO7BITS) << 24)  | ((tempscr[0] & SDMMC_8TO15BITS) << 8) |\
3125             ((tempscr[0] & SDMMC_16TO23BITS) >> 8) | ((tempscr[0] & SDMMC_24TO31BITS) >> 24));
3126 
3127   }
3128 
3129   return HAL_SD_ERROR_NONE;
3130 }
3131 
3132 /**
3133   * @brief  Wrap up reading in non-blocking mode.
3134   * @param  hsd: pointer to a SD_HandleTypeDef structure that contains
3135   *              the configuration information.
3136   * @retval None
3137   */
SD_Read_IT(SD_HandleTypeDef * hsd)3138 static void SD_Read_IT(SD_HandleTypeDef *hsd)
3139 {
3140   uint32_t count, data, dataremaining;
3141   uint8_t* tmp;
3142 
3143   tmp = hsd->pRxBuffPtr;
3144   dataremaining = hsd->RxXferSize;
3145 
3146   if (dataremaining > 0U)
3147   {
3148     /* Read data from SDIO Rx FIFO */
3149     for(count = 0U; count < 8U; count++)
3150     {
3151       data = SDIO_ReadFIFO(hsd->Instance);
3152       *tmp = (uint8_t)(data & 0xFFU);
3153       tmp++;
3154       dataremaining--;
3155       *tmp = (uint8_t)((data >> 8U) & 0xFFU);
3156       tmp++;
3157       dataremaining--;
3158       *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3159       tmp++;
3160       dataremaining--;
3161       *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3162       tmp++;
3163       dataremaining--;
3164     }
3165 
3166     hsd->pRxBuffPtr = tmp;
3167     hsd->RxXferSize = dataremaining;
3168   }
3169 }
3170 
3171 /**
3172   * @brief  Wrap up writing in non-blocking mode.
3173   * @param  hsd: pointer to a SD_HandleTypeDef structure that contains
3174   *              the configuration information.
3175   * @retval None
3176   */
SD_Write_IT(SD_HandleTypeDef * hsd)3177 static void SD_Write_IT(SD_HandleTypeDef *hsd)
3178 {
3179   uint32_t count, data, dataremaining;
3180   uint8_t* tmp;
3181 
3182   tmp = hsd->pTxBuffPtr;
3183   dataremaining = hsd->TxXferSize;
3184 
3185   if (dataremaining > 0U)
3186   {
3187     /* Write data to SDIO Tx FIFO */
3188     for(count = 0U; count < 8U; count++)
3189     {
3190       data = (uint32_t)(*tmp);
3191       tmp++;
3192       dataremaining--;
3193       data |= ((uint32_t)(*tmp) << 8U);
3194       tmp++;
3195       dataremaining--;
3196       data |= ((uint32_t)(*tmp) << 16U);
3197       tmp++;
3198       dataremaining--;
3199       data |= ((uint32_t)(*tmp) << 24U);
3200       tmp++;
3201       dataremaining--;
3202       (void)SDIO_WriteFIFO(hsd->Instance, &data);
3203     }
3204 
3205     hsd->pTxBuffPtr = tmp;
3206     hsd->TxXferSize = dataremaining;
3207   }
3208 }
3209 
3210 /**
3211   * @}
3212   */
3213 
3214 #endif /* HAL_SD_MODULE_ENABLED */
3215 
3216 /**
3217   * @}
3218   */
3219 
3220 /**
3221   * @}
3222   */
3223 
3224 #endif /* SDIO */
3225