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