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