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