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