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