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