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>© 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