1 /**
2 ******************************************************************************
3 * @file stm32u5xx_hal_sdio.c
4 * @author MCD Application Team
5 * @brief SDIO HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Secure Digital Input Output (SDIO) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 * + Peripheral State functions
12 *
13 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2021 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 @verbatim
25 ==============================================================================
26 ##### How to use this driver #####
27 ==============================================================================
28 [..]
29 This driver implements a high level communication layer for read and write from/to
30 this SDIO card. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
31 the user in HAL_SDIO_MspInit() function (MSP layer).
32 Basically, the MSP layer configuration should be the same as we provide in the
33 examples.
34 You can easily tailor this configuration according to hardware resources.
35
36 [..]
37 This driver is a generic layered driver for SDMMC memories which uses the HAL
38 SDMMC driver functions to interface with SDIO cards devices.
39 It is used as follows:
40
41 (#)Initialize the SDMMC low level resources by implementing the HAL_SDIO_MspInit() API:
42 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
43 (##) SDMMC pins configuration for SDIO card
44 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
45 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
46 and according to your pin assignment;
47 (##) NVIC configuration if you need to use interrupt process (HAL_SDIO_ReadExtended_DMA()
48 and HAL_SDIO_WriteExtended_DMA() APIs).
49 (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
50 (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
51 (+++) SDMMC interrupts are managed using the macros __HAL_SDIO_ENABLE_IT()
52 and __HAL_SDIO_DISABLE_IT() inside the communication process.
53 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_SDIO_GET_IT().
54 (##) No general propose DMA Configuration is needed, an Internal DMA for SDMMC Peripheral are used.
55
56 (#) At this stage, you can perform SDIO read/write/erase operations after SDIO card initialization.
57
58 *** SDIO Card Initialization and configuration ***
59 ================================================
60 [..]
61 To initialize the SDIO Card, use the HAL_SDIO_Init() function. It Initializes
62 SDMMC Peripheral(STM32 side) and the SDIO Card, and put it into StandBy State (Ready for data transfer).
63 This function provide the following operations:
64
65 (#) Apply the SDIO Card initialization process at 400KHz. You can change or adapt this
66 frequency by adjusting the "ClockDiv" field.
67 The SDIO Card frequency (SDMMC_CK) is computed as follows:
68
69 SDMMC_CK = SDMMCCLK / (2 * ClockDiv)
70
71 In initialization mode and according to the SDIO Card standard,
72 make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
73
74 This phase of initialization is done through SDMMC_Init() and
75 SDMMC_PowerState_ON() SDMMC low level APIs.
76
77 (#) Initialize the SDIO card. The API used is HAL_SDIO_Init().
78 This phase allows the card initialization and identification.
79
80 (#) Configure the SDIO Card Data transfer frequency. You can change or adapt this
81 frequency by adjusting the "ClockDiv" field by the API HAL_SDIO_ConfigFrequency().
82
83 (#) Configure the SDIO Card in wide bus mode: 4-bits data by the API HAL_SDIO_SetDataBusWidth().
84
85 (#) Configure the SDIO Card data block size by the API : HAL_SDIO_SetBlockSize().
86
87 (#) Configure the SDIO Card speed mode by the API : HAL_SDIO_SetSpeedMode().
88
89 (#) To custumize the SDIO Init card function for the enumeration card sequence, you can register a user callback
90 function by calling the HAL_SDIO_RegisterIdentifyCardCallback before the HAL_SDIO_Init() function.
91
92 *** SDIO Card Read operation ***
93 ==============================
94 [..]
95 (+) You can read from SDIO card in polling mode by using function HAL_SDIO_ReadExtended().
96 This function support only 2048-bytes block length (the block size should be
97 chosen by using the API HAL_SDIO_SetBlockSize).
98
99 (+) You can read from SDIO card in DMA mode by using function HAL_SDIO_ReadExtended_DMA().
100 This function support only 2048-bytes block length (the block size should be
101 chosen by using the API HAL_SDIO_SetBlockSize).
102 After this, you have to ensure that the transfer is done correctly.
103 You could also check the DMA transfer process through the SDIO Rx interrupt event.
104
105 *** SDIO Card Write operation ***
106 ===============================
107 [..]
108 (+) You can write to SDIO card in polling mode by using function HAL_SDIO_WriteExtended().
109 This function support only 2048-bytes block length (the block size should be
110 chosen by using the API HAL_SDIO_SetBlockSize).
111
112 (+) You can write to SDIO card in DMA mode by using function HAL_SDIO_WriteExtended_DMA().
113 This function support only 2048-bytes block length (the block size should be
114 chosen by using the API HAL_SDIO_SetBlockSize).
115 You could also check the DMA transfer process through the SDIO Tx interrupt event.
116
117
118 *** SDIO card common control register (CCCR) ***
119 ======================
120 [..]
121 (+) The SDIO CCCR allow for quick host checking and control of an IO card's enable and interrupts on a per card and
122 per function basis.
123 To get the Card common control registers field, you can use the API HAL_SDIO_GetCardCommonControlRegister().
124
125 *** SDIO card Function basic register (FBR) ***
126 ===========================
127 [..]
128 (+) The SDIO card function basic register are used to allow the host to quickly determine the abilities and
129 requirements of each function.
130 (+) To get the SDIO function basic register information, you can use the API HAL_SDIO_GetCardFBRRegister().
131
132 *** SDIO HAL driver macros list ***
133 ==================================
134 [..]
135 Below the list of most used macros in SDIO HAL driver.
136
137 (+) __HAL_SDIO_ENABLE_IT: Enable the SDIO device interrupt
138 (+) __HAL_SDIO_DISABLE_IT: Disable the SDIO device interrupt
139 (+) __HAL_SDIO_GET_FLAG: Check whether the specified SDIO flag is set or not
140 (+) __HAL_SDIO_CLEAR_FLAG: Clear the SDIO's pending flags
141 (+) __HAL_SDIO_GET_IT: Check whether the specified SDIO interrupt has occurred or not
142 (+) __HAL_SDIO_GET_IT_SOURCE: Checks whether the specified SDIO interrupt is enabled or not
143
144 (@) You can refer to the SDIO HAL driver header file for more useful macros
145
146 *** Callback registration ***
147 =============================================
148 [..]
149 The compilation define USE_HAL_SDIO_REGISTER_CALLBACKS when set to 1
150 allows the user to configure dynamically the driver callbacks.
151
152 Use Functions HAL_SDIO_RegisterCallback() to register a user callback,
153 it allows to register following callbacks:
154 (+) TxCpltCallback : callback when a transmission transfer is completed.
155 (+) RxCpltCallback : callback when a reception transfer is completed.
156 (+) ErrorCallback : callback when error occurs.
157 (+) MspInitCallback : SDIO MspInit.
158 (+) MspDeInitCallback : SDIO MspDeInit.
159 This function takes as parameters the HAL peripheral handle, the Callback ID
160 and a pointer to the user callback function.
161 For specific callbacks TransceiverCallback use dedicated register callbacks:
162 respectively HAL_SDIO_RegisterTransceiverCallback().
163
164 Use function HAL_SDIO_UnRegisterCallback() to reset a callback to the default
165 weak (overridden) function. It allows to reset following callbacks:
166 (+) TxCpltCallback : callback when a transmission transfer is completed.
167 (+) RxCpltCallback : callback when a reception transfer is completed.
168 (+) ErrorCallback : callback when error occurs.
169 (+) MspInitCallback : SDIO MspInit.
170 (+) MspDeInitCallback : SDIO MspDeInit.
171 This function) takes as parameters the HAL peripheral handle and the Callback ID.
172 For specific callbacks TransceiverCallback use dedicated unregister callbacks:
173 respectively HAL_SDIO_UnRegisterTransceiverCallback().
174
175 By default, after the HAL_SDIO_Init and if the state is HAL_SDIO_STATE_RESET
176 all callbacks are reset to the corresponding legacy weak (overridden) functions.
177 Exception done for MspInit and MspDeInit callbacks that are respectively
178 reset to the legacy weak (overridden) functions in the HAL_SDIO_Init
179 and HAL_SDIO_DeInit only when these callbacks are null (not registered beforehand).
180 If not, MspInit or MspDeInit are not null, the HAL_SDIO_Init and HAL_SDIO_DeInit
181 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
182
183 Callbacks can be registered/unregistered in READY state only.
184 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
185 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
186 during the Init/DeInit.
187 In that case first register the MspInit/MspDeInit user callbacks
188 using HAL_SDIO_RegisterCallback before calling HAL_SDIO_DeInit
189 or HAL_SDIO_Init function.
190
191 When The compilation define USE_HAL_SDIO_REGISTER_CALLBACKS is set to 0 or
192 not defined, the callback registering feature is not available
193 and weak (overridden) callbacks are used.
194
195 *** SDIO peripheral IO interrupt ***
196 =============================================
197 [..]
198 (+) Below the list of most used SDIO function to check and control the IO card's enable and interrupts on a per
199 functions basis.
200
201 (+) HAL_SDIO_EnableIOFunctionInterrupt: Enable SDIO IO interrupt.
202 (+) HAL_SDIO_DisableIOFunctionInterrupt: Disable SDIO IO interrupt.
203 (+) HAL_SDIO_EnableIOFunction: Enable Function number(0-7)
204 (+) HAL_SDIO_DisableIOFunction: Disable Function number(0-7)
205 (+) HAL_SDIO_SelectIOFunction: Select a function number(0-7)
206 (+) HAL_SDIO_AbortIOFunction: Abort an IO read or write operation and free the SDIO bus.
207 (+) HAL_SDIO_EnableIOAsynInterrupt: Enable Bit of asynchronous interrupt
208 (+) HAL_SDIO_DisableIOAsynInterrupt: Disable Bit of asynchronous interrupt
209
210 @endverbatim
211 ******************************************************************************
212 */
213
214 /* Includes ----------------------------------------------------------------------------------------------------------*/
215 #include "stm32u5xx_hal.h"
216
217 /** @addtogroup STM32U5xx_HAL_Driver
218 * @{
219 */
220
221 /** @addtogroup SDIO
222 * @{
223 */
224 #if defined (SDMMC1) || defined (SDMMC2)
225 #ifdef HAL_SDIO_MODULE_ENABLED
226
227 /* Private define ----------------------------------------------------------------------------------------------------*/
228 /** @addtogroup SDIO_Private_Defines
229 * @{
230 */
231 #define SDIO_INIT_FREQ 400000U /*!< Initialization phase : 400 kHz max */
232 #define SDIO_TIMEOUT 1000U /*!< SDIO timeout millisecond */
233
234 #define SDIO_FUNCTION_0 0x00U /*!< SDIO_Functions 0 */
235 #define SDIO_FUNCTION_1 0x01U /*!< SDIO_Functions 1 */
236
237 #define SDIO_READ 0x0U /*!< Read flag for cmd52 and cmd53 */
238 #define SDIO_WRITE 0x1U /*!< Write flag for cmd52 and cmd53 */
239
240 #define SDIO_BUS_SPEED_SDR12 0x00U /*!< SDIO bus speed mode SDR12 */
241 #define SDIO_BUS_SPEED_SDR25 0x02U /*!< SDIO bus speed mode SDR25 */
242 #define SDIO_BUS_SPEED_SDR50 0x04U /*!< SDIO bus speed mode SDR50 */
243 #define SDIO_BUS_SPEED_DDR50 0x08U /*!< SDIO bus speed mode DDR50 */
244
245 #define SDIO_CCCR_REG_NUMBER 0x16U /*!< SDIO card cccr register number */
246
247 #define SDIO_OCR_VDD_32_33 (1U << 20U)
248 #define SDIO_OCR_SDIO_S18R (1U << 24U)
249 /**
250 * @}
251 */
252
253 /* Private macro -----------------------------------------------------------------------------------------------------*/
254 #define IS_SDIO_RAW_FLAG(ReadAfterWrite) (((ReadAfterWrite) == HAL_SDIO_WRITE_ONLY) || \
255 ((ReadAfterWrite) == HAL_SDIO_READ_AFTER_WRITE))
256
257 #define IS_SDIO_FUNCTION(FN) (((FN) >= HAL_SDIO_FUNCTION_1) && ((FN) <= HAL_SDIO_FUNCTION_7))
258
259 #define IS_SDIO_SUPPORTED_BLOCK_SIZE(BLOCKSIZE) (((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_1BYTE) || \
260 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_2BYTE) || \
261 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_4BYTE) || \
262 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_8BYTE) || \
263 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_16BYTE) || \
264 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_32BYTE) || \
265 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_64BYTE) || \
266 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_128BYTE) || \
267 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_256BYTE) || \
268 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) || \
269 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_1024BYTE) || \
270 ((BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_2048BYTE))
271
272 /* Private functions -------------------------------------------------------------------------------------------------*/
273 /** @defgroup SDIO_Private_Functions SDIO Private Functions
274 * @{
275 */
276 static HAL_StatusTypeDef SDIO_InitCard(SDIO_HandleTypeDef *hsdio);
277 static HAL_StatusTypeDef SDIO_ReadDirect(SDIO_HandleTypeDef *hsdio, uint32_t addr, uint32_t raw, uint32_t function_nbr,
278 uint8_t *pData);
279 static HAL_StatusTypeDef SDIO_WriteDirect(SDIO_HandleTypeDef *hsdio, uint32_t addr, uint32_t raw, uint32_t function_nbr,
280 uint8_t *pData);
281 static HAL_StatusTypeDef SDIO_WriteExtended(SDIO_HandleTypeDef *hsdio, HAL_SDIO_ExtendedCmd_TypeDef *cmd_arg,
282 uint8_t *pData, uint16_t Size_byte);
283 static uint8_t SDIO_Convert_Block_Size(SDIO_HandleTypeDef *hsdio, uint32_t block_size);
284 static HAL_StatusTypeDef SDIO_IOFunction_IRQHandler(SDIO_HandleTypeDef *hsdio);
285 /**
286 * @}
287 */
288
289 /* Exported functions --------------------------------------------------------*/
290 /** @addtogroup SDIO_Exported_Functions
291 * @{
292 */
293 /** @addtogroup SDIO_Exported_Functions_Group1
294 * @brief Initialization and de-initialization functions
295 *
296 @verbatim
297 ==============================================================================
298 ##### Initialization and de-initialization functions #####
299 ==============================================================================
300 [..]
301 This section provides functions allowing to initialize/de-initialize the SDIO
302 device to be ready for use.
303
304 @endverbatim
305 * @{
306 */
307 /**
308 * @brief Initializes the SDIO according to the specified parameters in the
309 SDIO_HandleTypeDef and create the associated handle.
310 * @param hsdio: Pointer to the SDIO handle
311 * @retval HAL status
312 */
HAL_SDIO_Init(SDIO_HandleTypeDef * hsdio)313 HAL_StatusTypeDef HAL_SDIO_Init(SDIO_HandleTypeDef *hsdio)
314 {
315 SDIO_InitTypeDef Init;
316 uint32_t sdmmc_clk;
317 uint8_t data;
318
319 /* Check the parameters */
320 assert_param(hsdio != NULL);
321 assert_param(IS_SDMMC_ALL_INSTANCE(hsdio->Instance));
322 assert_param(IS_SDMMC_CLOCK_EDGE(hsdio->Init.ClockEdge));
323 assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hsdio->Init.ClockPowerSave));
324 assert_param(IS_SDMMC_BUS_WIDE(hsdio->Init.BusWide));
325 assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hsdio->Init.HardwareFlowControl));
326 assert_param(IS_SDMMC_CLKDIV(hsdio->Init.ClockDiv));
327
328 /* Check the SDIO handle allocation */
329 if (hsdio == NULL)
330 {
331 return HAL_ERROR;
332 }
333
334 if (hsdio->State == HAL_SDIO_STATE_RESET)
335 {
336 #if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1U)
337 /* Reset Callback pointers in HAL_SDIO_STATE_RESET only */
338 hsdio->TxCpltCallback = HAL_SDIO_TxCpltCallback;
339 hsdio->RxCpltCallback = HAL_SDIO_RxCpltCallback;
340 hsdio->ErrorCallback = HAL_SDIO_ErrorCallback;
341 #if (USE_SDIO_TRANSCEIVER != 0U)
342 if (hsdio->Init.TranceiverPresent == SDMMC_TRANSCEIVER_PRESENT)
343 {
344 hsdio->DriveTransceiver_1_8V_Callback = HAL_SDIO_DriveTransceiver_1_8V_Callback;
345 }
346 #endif /* USE_SDIO_TRANSCEIVER */
347
348 if (hsdio->MspInitCallback == NULL)
349 {
350 hsdio->MspInitCallback = HAL_SDIO_MspInit;
351 }
352 /* Init the low level hardware */
353 hsdio->MspInitCallback(hsdio);
354 #else
355 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
356 HAL_SDIO_MspInit(hsdio);
357 #endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
358 }
359
360 Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
361 Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
362 Init.BusWide = SDMMC_BUS_WIDE_1B;
363 Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
364
365 sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
366 if (sdmmc_clk == 0U)
367 {
368 hsdio->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER;
369 return HAL_ERROR;
370 }
371 Init.ClockDiv = sdmmc_clk / (2U * SDIO_INIT_FREQ);
372 /* Initialize SDMMC peripheral interface with default configuration */
373 (void)SDMMC_Init(hsdio->Instance, Init);
374
375 /* Set Power State to ON */
376 (void)SDMMC_PowerState_ON(hsdio->Instance);
377
378 /* wait 74 Cycles: required power up waiting time before starting the SDIO initialization sequence */
379 sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv);
380 HAL_Delay(1U + (74U * 1000U / (sdmmc_clk)));
381
382 if (hsdio->SDIO_IdentifyCard == NULL)
383 {
384 hsdio->SDIO_IdentifyCard = SDIO_InitCard;
385 }
386 /* SDIO enumeration sequence */
387 if (hsdio->SDIO_IdentifyCard(hsdio) != HAL_OK)
388 {
389 hsdio->State = HAL_SDIO_STATE_RESET;
390 return HAL_ERROR;
391 }
392
393 /* Configure the SDMMC user parameters */
394 Init.ClockEdge = hsdio->Init.ClockEdge;
395 Init.ClockPowerSave = hsdio->Init.ClockPowerSave;
396 Init.BusWide = hsdio->Init.BusWide;
397 Init.HardwareFlowControl = hsdio->Init.HardwareFlowControl;
398 Init.ClockDiv = hsdio->Init.ClockDiv;
399 (void)SDMMC_Init(hsdio->Instance, Init);
400
401 data = (hsdio->Init.BusWide == HAL_SDIO_4_WIRES_MODE) ? 2U : 0U;
402 if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR4_SD_BYTE3, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &data) != HAL_OK)
403 {
404 return HAL_ERROR;
405 }
406
407 hsdio->Context = SDIO_CONTEXT_NONE;
408 hsdio->State = HAL_SDIO_STATE_READY;
409
410 return HAL_OK;
411 }
412
413 /**
414 * @brief De-Initializes the SDIO device.
415 * @param hsdio: Pointer to the SDIO handle
416 * @retval HAL status
417 */
HAL_SDIO_DeInit(SDIO_HandleTypeDef * hsdio)418 HAL_StatusTypeDef HAL_SDIO_DeInit(SDIO_HandleTypeDef *hsdio)
419 {
420 /* Check the parameters */
421 assert_param(IS_SDMMC_ALL_INSTANCE(hsdio->Instance));
422
423 /* Check the SDIO handle allocation */
424 if (hsdio == NULL)
425 {
426 return HAL_ERROR;
427 }
428
429 /* Set Power State to OFF */
430 (void)SDMMC_PowerState_OFF(hsdio->Instance);
431
432 #if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1U)
433 if (hsdio->MspDeInitCallback == NULL)
434 {
435 hsdio->MspDeInitCallback = HAL_SDIO_MspDeInit;
436 }
437
438 /* DeInit the low level hardware */
439 hsdio->MspDeInitCallback(hsdio);
440 #else
441 /* De-Initialize the MSP layer */
442 HAL_SDIO_MspDeInit(hsdio);
443 #endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
444
445 hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
446 hsdio->State = HAL_SDIO_STATE_RESET;
447
448 return HAL_OK;
449 }
450
451 /**
452 * @brief Initializes the SDIO MSP.
453 * @param hsdio: Pointer to SDIO handle
454 * @retval None
455 */
HAL_SDIO_MspInit(SDIO_HandleTypeDef * hsdio)456 __weak void HAL_SDIO_MspInit(SDIO_HandleTypeDef *hsdio)
457 {
458 /* Prevent unused argument(s) compilation warning */
459 UNUSED(hsdio);
460
461 /* NOTE : This function should not be modified, when the callback is needed,
462 the HAL_SDIO_MspInit could be implemented in the user file
463 */
464 }
465
466 /**
467 * @brief De-Initialize SDIO MSP.
468 * @param hsdio: Pointer to SDIO handle
469 * @retval None
470 */
HAL_SDIO_MspDeInit(SDIO_HandleTypeDef * hsdio)471 __weak void HAL_SDIO_MspDeInit(SDIO_HandleTypeDef *hsdio)
472 {
473 /* Prevent unused argument(s) compilation warning */
474 UNUSED(hsdio);
475
476 /* NOTE : This function should not be modified, when the callback is needed,
477 the HAL_SDIO_MspDeInit could be implemented in the user file
478 */
479 }
480 /**
481 * @}
482 */
483
484 /** @addtogroup SDIO_Exported_Functions_Group2
485 * @brief
486 *
487 @verbatim
488 ==============================================================================
489 ##### Initialization and de-initialization functions #####
490 ==============================================================================
491 [..]
492 This subsection provides a set of functions allowing to re-configure the SDIO peripheral.
493
494 @endverbatim
495 * @{
496 */
497 /**
498 * @brief Enables wide bus operation for the requested card if supported by card.
499 * @param hsdio: Pointer to SDIO handle
500 * @param BusWide: Specifies the SDIO card wide bus mode
501 * This parameter can be one of the following values:
502 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
503 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
504 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
505 * @retval HAL status
506 */
HAL_SDIO_SetDataBusWidth(SDIO_HandleTypeDef * hsdio,uint32_t BusWide)507 HAL_StatusTypeDef HAL_SDIO_SetDataBusWidth(SDIO_HandleTypeDef *hsdio, uint32_t BusWide)
508 {
509 uint8_t data;
510 HAL_StatusTypeDef error_state = HAL_OK;
511
512 /* Check the parameters */
513 assert_param(hsdio != NULL);
514
515 /* Check the SDIO peripheral handle parameter */
516 if (hsdio == NULL)
517 {
518 return HAL_ERROR;
519 }
520
521 if (hsdio->State == HAL_SDIO_STATE_READY)
522 {
523 data = (BusWide == HAL_SDIO_4_WIRES_MODE) ? 2U : 0U;
524 MODIFY_REG(hsdio->Instance->CLKCR, SDMMC_CLKCR_WIDBUS,
525 (BusWide == HAL_SDIO_4_WIRES_MODE) ? SDMMC_BUS_WIDE_4B : SDMMC_BUS_WIDE_1B);
526
527 if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR4_SD_BYTE3, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &data) != HAL_OK)
528 {
529 error_state = HAL_ERROR;
530 }
531 }
532 else
533 {
534 error_state = HAL_ERROR;
535 }
536
537 return error_state;
538 }
539
540 /**
541 * @brief Update the SDIO Clock.
542 * @param hsdio: Pointer to SDIO handle.
543 * @param ClockSpeed: SDIO Clock speed.
544 * @retval HAL status
545 */
HAL_SDIO_ConfigFrequency(SDIO_HandleTypeDef * hsdio,uint32_t ClockSpeed)546 HAL_StatusTypeDef HAL_SDIO_ConfigFrequency(SDIO_HandleTypeDef *hsdio, uint32_t ClockSpeed)
547 {
548 uint32_t ClockDiv;
549
550 /* Check the parameters */
551 assert_param(hsdio != NULL);
552
553 /* Check the SDIO peripheral handle parameter */
554 if (hsdio == NULL)
555 {
556 return HAL_ERROR;
557 }
558
559 if (hsdio->State == HAL_SDIO_STATE_READY)
560 {
561 ClockDiv = (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC)) / (2U * ClockSpeed);
562 MODIFY_REG(hsdio->Instance->CLKCR, SDMMC_CLKCR_CLKDIV, ClockDiv);
563 }
564 else
565 {
566 return HAL_ERROR;
567 }
568
569 return HAL_OK;
570 }
571
572 /**
573 * @brief Set the SDIO block size.
574 * @param hsdio: Pointer to SDIO handle
575 * @param function_nbr: Specifies the SDIO function number.
576 * @param BlockSize: Specifies the SDIO Block size to set.
577 * This parameter can be one of the following values @ref SDIO_Exported_Constansts_Group7.
578 * @retval HAL status
579 */
HAL_SDIO_SetBlockSize(SDIO_HandleTypeDef * hsdio,uint8_t function_nbr,uint16_t BlockSize)580 HAL_StatusTypeDef HAL_SDIO_SetBlockSize(SDIO_HandleTypeDef *hsdio, uint8_t function_nbr, uint16_t BlockSize)
581 {
582 HAL_SDIO_ExtendedCmd_TypeDef cmd53;
583
584 /* Check the parameters */
585 assert_param(hsdio != NULL);
586 assert_param(IS_SDIO_FUNCTION(function_nbr));
587 assert_param(IS_SDIO_SUPPORTED_BLOCK_SIZE(BlockSize));
588
589 /* Check the SDIO peripheral handle parameter */
590 if (hsdio == NULL)
591 {
592 return HAL_ERROR;
593 }
594
595 /* Set SDIO F1 block size */
596 cmd53.IOFunctionNbr = SDIO_FUNCTION_0;
597 cmd53.OpCode = HAL_SDIO_OP_CODE_AUTO_INC;
598 cmd53.Block_Mode = HAL_SDIO_MODE_BYTE;
599 cmd53.Reg_Addr = (function_nbr * 0x100UL) + 0x10UL;
600 if (SDIO_WriteExtended(hsdio, &cmd53, (uint8_t *)(&BlockSize), 2U) != HAL_OK)
601 {
602 return HAL_ERROR;
603 }
604
605 hsdio->block_size = BlockSize;
606
607 return HAL_OK;
608 }
609
610 /**
611 * @brief Configure the data rate.
612 * @param hsdio: Pointer to SDIO handle
613 * @param DataRate: Specifies the SDIO data rate to set.
614 * @retval HAL status
615 */
HAL_SDIO_SetSpeedMode(SDIO_HandleTypeDef * hsdio,uint32_t DataRate)616 HAL_StatusTypeDef HAL_SDIO_SetSpeedMode(SDIO_HandleTypeDef *hsdio, uint32_t DataRate)
617 {
618 HAL_StatusTypeDef errorstate = HAL_OK;
619 uint8_t data;
620
621 /* Check the parameters */
622 assert_param(hsdio != NULL);
623
624 /* Check the SDIO peripheral handle parameter */
625 if (hsdio == NULL)
626 {
627 return HAL_ERROR;
628 }
629
630 switch (DataRate)
631 {
632 case HAL_SDIOS_DATA_RATE_SDR25:
633 data = SDIO_BUS_SPEED_SDR25;
634 errorstate = SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR16_SD_BYTE3, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &data);
635 break;
636
637 case HAL_SDIOS_DATA_RATE_SDR50:
638 data = SDIO_BUS_SPEED_SDR50;
639 errorstate = SDIO_WriteDirect(hsdio, ((SDIO_FUNCTION_0 << 2U) | (SDIO_FUNCTION_0 << 1U) | (SDIO_FUNCTION_0 << 14U)
640 | SDMMC_SDIO_CCCR16_SD_BYTE3), HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &data);
641 MODIFY_REG(hsdio->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED, SDMMC_CLKCR_BUSSPEED);
642 break;
643
644 case HAL_SDIOS_DATA_RATE_DDR50:
645 data = SDIO_BUS_SPEED_DDR50;
646 errorstate = SDIO_WriteDirect(hsdio, ((SDIO_FUNCTION_0 << 2) | (SDIO_FUNCTION_0 << 1) | (SDIO_FUNCTION_0 << 14) |
647 SDMMC_SDIO_CCCR16_SD_BYTE3), HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &data);
648 MODIFY_REG(hsdio->Instance->CLKCR, SDMMC_CLKCR_DDR | SDMMC_CLKCR_BUSSPEED,
649 SDMMC_CLKCR_DDR | SDMMC_CLKCR_BUSSPEED);
650 break;
651 default: /* SDR12 */
652 break;
653 }
654
655 return (errorstate != HAL_OK) ? HAL_ERROR : HAL_OK;
656 }
657
658 /**
659 * @brief Reset SDIO Card
660 * @param hsdio: Pointer to SDIO handle
661 * @retval HAL status
662 */
HAL_SDIO_CardReset(SDIO_HandleTypeDef * hsdio)663 HAL_StatusTypeDef HAL_SDIO_CardReset(SDIO_HandleTypeDef *hsdio)
664 {
665 uint8_t data = 0U;
666
667 /* Check the parameters */
668 assert_param(hsdio != NULL);
669
670 /* Check the SDIO peripheral handle parameter */
671 if (hsdio == NULL)
672 {
673 return HAL_ERROR;
674 }
675
676 /** To reset the SDIO module by CMD52 with writing to RES in CCCR or send CMD0 the card shall change the speed mode
677 * default speed mode.
678 * The reset cmd (cmd0) is only used for memory. In order to reset an I/O card or the I/O portion of a combo card,
679 * Use CMD52 to write 1 to the RES bit in the CCC(bit3 of register 6).
680 */
681 if (SDIO_WriteDirect(hsdio, ((SDIO_FUNCTION_0 << 2) | (SDIO_FUNCTION_0 << 1) | (SDIO_FUNCTION_0 << 14) |
682 SDMMC_SDIO_CCCR4_SD_BYTE2),
683 HAL_SDIO_WRITE_ONLY,
684 0U,
685 &data) != HAL_OK)
686 {
687 return HAL_ERROR;
688 }
689
690 hsdio->State = HAL_SDIO_STATE_RESET;
691
692 return HAL_OK;
693 }
694
695 /**
696 * @brief Get Card Common Control register (CCCR).
697 * @param hsdio: Pointer to SDIO handle.
698 * @param pCccr: Pointer to Cccr register.
699 * @retval HAL status
700 */
HAL_SDIO_GetCardCommonControlRegister(SDIO_HandleTypeDef * hsdio,HAL_SDIO_CCCR_TypeDef * pCccr)701 HAL_StatusTypeDef HAL_SDIO_GetCardCommonControlRegister(SDIO_HandleTypeDef *hsdio, HAL_SDIO_CCCR_TypeDef *pCccr)
702 {
703 uint8_t tempBuffer[256] = {0U};
704 uint32_t count;
705
706 assert_param(hsdio != NULL);
707 assert_param(pCccr != NULL);
708
709 if ((hsdio == NULL) || (pCccr == NULL))
710 {
711 return HAL_ERROR;
712 }
713
714 for (count = 0U; count <= SDIO_CCCR_REG_NUMBER; count++)
715 {
716 if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR0 + count, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &tempBuffer[count]) !=
717 HAL_OK)
718 {
719 return HAL_ERROR;
720 }
721 }
722
723 pCccr->cccr_revision = tempBuffer[0] & 0x0FU;
724 pCccr->sdio_revision = (tempBuffer[0] & 0xF0U) >> 4U;
725 pCccr->sd_spec_revision = tempBuffer[0x01U] & 0x0FU;
726 pCccr->bus_width_8Bit = ((tempBuffer[0x07U] & 0x04U) != 0U) ? HAL_SDIO_BUS_WIDTH_8BIT_SUPPORTED
727 : HAL_SDIO_BUS_WIDTH_8BIT_NOT_SUPPORTED;
728 pCccr->card_capability = (tempBuffer[0x08U] & 0xDFUL);
729 /* common CIS pointer */
730 pCccr->commonCISPointer = tempBuffer[0x09U] | ((uint32_t)tempBuffer[(uint32_t)0x09U + 1U] << 8U) |
731 ((uint32_t)tempBuffer[(uint32_t)0x09U + 2U] << 16U);
732
733 return HAL_OK;
734 }
735
736 /**
737 * @brief Get Card Function Basic register(FBR).
738 * @param hsdio: Pointer to SDIO handle.
739 * @param pFbr: Pointer to Fbr register.
740 * @retval HAL status
741 */
HAL_SDIO_GetCardFBRRegister(SDIO_HandleTypeDef * hsdio,HAL_SDIO_FBR_t * pFbr)742 HAL_StatusTypeDef HAL_SDIO_GetCardFBRRegister(SDIO_HandleTypeDef *hsdio, HAL_SDIO_FBR_t *pFbr)
743 {
744 uint8_t tempBuffer[256] = {0U};
745 uint32_t count;
746 uint8_t func_idx;
747
748 assert_param(hsdio != NULL);
749 assert_param(pFbr != NULL);
750
751 if ((hsdio == NULL) || (pFbr == NULL))
752 {
753 return HAL_ERROR;
754 }
755
756 for (func_idx = 2U; func_idx <= SDIO_MAX_IO_NUMBER; func_idx++)
757 {
758 for (count = 0U; count <= SDIO_CCCR_REG_NUMBER; count++)
759 {
760 if (SDIO_ReadDirect(hsdio, (((uint32_t)SDMMC_SDIO_F1BR0 * (uint32_t)func_idx) + count),
761 HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &tempBuffer[count]) != HAL_OK)
762 {
763 return HAL_ERROR;
764 }
765 }
766 pFbr[(uint32_t)func_idx - 1U].ioStdFunctionCode = tempBuffer[0U] & 0x0FU;
767 pFbr[(uint32_t)func_idx - 1U].ioExtFunctionCode = tempBuffer[1U];
768 pFbr[(uint32_t)func_idx - 1U].ioPointerToCIS = tempBuffer[9U] | ((uint32_t)tempBuffer[10U] << 8U) |
769 ((uint32_t)tempBuffer[11U] << 16U);
770 pFbr[(uint32_t)func_idx - 1U].ioPointerToCSA = tempBuffer[12U] | ((uint32_t)tempBuffer[13U] << 8U) |
771 ((uint32_t)tempBuffer[14U] << 16U);
772 if ((tempBuffer[2U] & 0x01U) != 0U)
773 {
774 pFbr[(uint32_t)func_idx - 1U].flags |= (uint8_t)HAL_SDIO_FBR_SUPPORT_POWER_SELECTION;
775 }
776 if ((tempBuffer[0U] & 0x40U) != 0U)
777 {
778 pFbr[(uint32_t)func_idx - 1U].flags |= (uint8_t)HAL_SDIO_FBR_SUPPORT_CSA;
779 }
780 }
781
782 return HAL_OK;
783 }
784 /**
785 * @}
786 */
787
788 /** @addtogroup SDIO_Exported_Functions_Group3
789 * @brief
790 *
791 @verbatim
792 ==============================================================================
793 ##### Data management functions #####
794 ==============================================================================
795 [..]
796 This subsection provides a set of functions allowing to manage the data transfer from/to SDIO card.
797
798 @endverbatim
799 * @{
800 */
801 /**
802 * @brief Read data from a specified address using the direct mode through cmd52.
803 * @param hsdio: Pointer to SDIO handle
804 * @param Argument: Specifies the SDIO Argument.
805 * @param pData: pointer to the buffer that will contain the received data.
806 * @retval HAL status
807 */
HAL_SDIO_ReadDirect(SDIO_HandleTypeDef * hsdio,HAL_SDIO_DirectCmd_TypeDef * Argument,uint8_t * pData)808 HAL_StatusTypeDef HAL_SDIO_ReadDirect(SDIO_HandleTypeDef *hsdio, HAL_SDIO_DirectCmd_TypeDef *Argument, uint8_t *pData)
809 {
810 uint32_t cmd;
811 uint32_t errorstate;
812
813 /* Check the parameters */
814 assert_param(hsdio != NULL);
815 assert_param(Argument != NULL);
816 assert_param(pData != NULL);
817 assert_param(IS_SDIO_RAW_FLAG(Argument->ReadAfterWrite));
818
819 if ((hsdio == NULL) || (Argument == NULL) || (NULL == pData))
820 {
821 return HAL_ERROR;
822 }
823
824 if (hsdio->State == HAL_SDIO_STATE_READY)
825 {
826 hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
827 hsdio->State = HAL_SDIO_STATE_BUSY;
828
829 cmd = SDIO_READ << 31U;
830 cmd |= (((uint32_t)Argument->IOFunctionNbr) << 28U);
831 cmd |= (((uint32_t)Argument->ReadAfterWrite) << 27U);
832 cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
833 cmd |= 0U;
834 errorstate = SDMMC_SDIO_CmdReadWriteDirect(hsdio->Instance, cmd, pData);
835
836 if (errorstate != HAL_SDIO_ERROR_NONE)
837 {
838 hsdio->ErrorCode |= errorstate;
839 if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
840 SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
841 {
842 /* Clear all the static flags */
843 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
844 hsdio->State = HAL_SDIO_STATE_READY;
845 hsdio->Context = SDIO_CONTEXT_NONE;
846 return HAL_ERROR;
847 }
848 }
849
850 __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
851
852 /* Clear all the static flags */
853 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
854
855 hsdio->State = HAL_SDIO_STATE_READY;
856 }
857 else
858 {
859 return HAL_BUSY;
860 }
861
862 return HAL_OK;
863 }
864
865
866 /**
867 * @brief Read data from a specified address using the direct mode through cmd52.
868 * @param hsdio: Pointer to SDIO handle
869 * @param Argument: Specifies the SDIO Argument.
870 * @param Data: pointer to the buffer that will contain the received data.
871 * @retval HAL status
872 */
HAL_SDIO_WriteDirect(SDIO_HandleTypeDef * hsdio,HAL_SDIO_DirectCmd_TypeDef * Argument,uint8_t Data)873 HAL_StatusTypeDef HAL_SDIO_WriteDirect(SDIO_HandleTypeDef *hsdio, HAL_SDIO_DirectCmd_TypeDef *Argument, uint8_t Data)
874 {
875 uint32_t cmd;
876 uint32_t errorstate;
877
878 /* Check the parameters */
879 assert_param(hsdio != NULL);
880 assert_param(Argument != NULL);
881 assert_param(IS_SDIO_RAW_FLAG(Argument->ReadAfterWrite));
882
883 if ((hsdio == NULL) || (Argument == NULL))
884 {
885 return HAL_ERROR;
886 }
887
888 if (hsdio->State == HAL_SDIO_STATE_READY)
889 {
890 hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
891 hsdio->State = HAL_SDIO_STATE_BUSY;
892
893 cmd = SDIO_WRITE << 31U;
894 cmd |= ((uint32_t)Argument->IOFunctionNbr) << 28U;
895 cmd |= ((uint32_t)Argument->ReadAfterWrite) << 27U;
896 cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
897 cmd |= Data;
898 errorstate = SDMMC_SDIO_CmdReadWriteDirect(hsdio->Instance, cmd, &Data);
899 if (errorstate != HAL_SDIO_ERROR_NONE)
900 {
901 hsdio->ErrorCode |= errorstate;
902 if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
903 SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
904 {
905 /* Clear all the static flags */
906 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
907 hsdio->State = HAL_SDIO_STATE_READY;
908 hsdio->Context = SDIO_CONTEXT_NONE;
909 return HAL_ERROR;
910 }
911 }
912
913 __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
914
915 /* Clear all the static flags */
916 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
917
918 hsdio->State = HAL_SDIO_STATE_READY;
919 }
920 else
921 {
922 return HAL_BUSY;
923 }
924
925 return HAL_OK;
926 }
927
928 /**
929 * @brief Read data from a specified address using extended mode through cmd53.
930 * @param hsdio: Pointer to SDIO handle
931 * @param Argument: Pointer to SDIO argument
932 * @param pData: pointer to the buffer that will contain the data to transmit
933 * @param Size_byte: size to read.
934 * @param Timeout_Ms: Specify timeout value
935 * @retval HAL status
936 */
HAL_SDIO_ReadExtended(SDIO_HandleTypeDef * hsdio,HAL_SDIO_ExtendedCmd_TypeDef * Argument,uint8_t * pData,uint32_t Size_byte,uint32_t Timeout_Ms)937 HAL_StatusTypeDef HAL_SDIO_ReadExtended(SDIO_HandleTypeDef *hsdio, HAL_SDIO_ExtendedCmd_TypeDef *Argument,
938 uint8_t *pData, uint32_t Size_byte, uint32_t Timeout_Ms)
939 {
940 uint32_t cmd;
941 SDMMC_DataInitTypeDef config;
942 uint32_t errorstate;
943 uint32_t tickstart = HAL_GetTick();
944 uint32_t regCount;
945 uint8_t byteCount;
946 uint32_t data;
947 uint32_t dataremaining;
948 uint8_t *tempbuff = pData;
949 uint32_t nbr_of_block;
950
951 /* Check the parameters */
952 assert_param(hsdio != NULL);
953 assert_param(Argument != NULL);
954 assert_param(pData != NULL);
955
956 if ((hsdio == NULL) || (Argument == NULL) || (pData == NULL))
957 {
958 return HAL_ERROR;
959 }
960
961 if (hsdio->State == HAL_SDIO_STATE_READY)
962 {
963 hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
964 hsdio->State = HAL_SDIO_STATE_BUSY;
965
966 /* Compute how many blocks are to be send for pData of length data_size to be send */
967 nbr_of_block = (Size_byte & ~(hsdio->block_size & 1U)) >> __CLZ(__RBIT(hsdio->block_size));
968
969 /* Initialize data control register */
970 if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
971 {
972 hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
973 }
974 else
975 {
976 hsdio->Instance->DCTRL = 0U;
977 }
978
979 /* Configure the SDIO DPSM (Data Path State Machine) */
980 config.DataTimeOut = SDMMC_DATATIMEOUT;
981 /* (HAL_SDIO_MODE_BLOCK << 27) corresponds to the block mode bit of the CMD argument */
982 if (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK)
983 {
984 /* (Argument & 0x1FFU) is to get the 9 bits of Block/Byte counts */
985 config.DataLength = (uint32_t)(nbr_of_block * hsdio->block_size);
986 config.DataBlockSize = SDIO_Convert_Block_Size(hsdio, hsdio->block_size);
987 }
988 else
989 {
990 /* (Argument & 0x1FFU) is to get the 9 bits of Block/Byte counts */
991 config.DataLength = (Size_byte > 0U) ? Size_byte : HAL_SDIO_DATA_BLOCK_SIZE_512BYTE;
992 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
993 }
994
995 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC ;
996 /* (HAL_SDIO_MODE_BLOCK << 27) corresponds to the block mode bit of the CMD argument */
997 config.TransferMode = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDMMC_TRANSFER_MODE_BLOCK :
998 SDMMC_TRANSFER_MODE_SDIO;
999 config.DPSM = SDMMC_DPSM_DISABLE;
1000 (void)SDMMC_ConfigData(hsdio->Instance, &config);
1001 __SDMMC_CMDTRANS_ENABLE(hsdio->Instance);
1002
1003 /* Correspond to the write or read bit of the CMD argument */
1004 /* Read */
1005 hsdio->Context = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDIO_CONTEXT_READ_MULTIPLE_BLOCK :
1006 SDIO_CONTEXT_READ_SINGLE_BLOCK;
1007 cmd = SDIO_READ << 31U;
1008 cmd |= Argument->IOFunctionNbr << 28U;
1009 cmd |= Argument->Block_Mode << 27U;
1010 cmd |= Argument->OpCode << 26U;
1011 cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
1012 cmd |= (Size_byte & 0x1FFU);
1013 errorstate = SDMMC_SDIO_CmdReadWriteExtended(hsdio->Instance, cmd);
1014 if (errorstate != HAL_SDIO_ERROR_NONE)
1015 {
1016 hsdio->ErrorCode |= errorstate;
1017 if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
1018 SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
1019 {
1020 MODIFY_REG(hsdio->Instance->DCTRL, SDMMC_DCTRL_FIFORST, SDMMC_DCTRL_FIFORST);
1021 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1022 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
1023 hsdio->State = HAL_SDIO_STATE_READY;
1024 hsdio->Context = SDIO_CONTEXT_NONE;
1025 return HAL_ERROR;
1026 }
1027 }
1028 /* (SDIO_WRITE << 31) correspond to the write or read bit of the CMD argument */
1029 /* Poll on SDMMC flags */
1030 dataremaining = config.DataLength;
1031
1032 while (!__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL |
1033 SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
1034 {
1035 if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= 32U))
1036 {
1037 /* Read data from SDMMC Rx FIFO */
1038 for (regCount = 0U; regCount < 8U; regCount++)
1039 {
1040 data = SDMMC_ReadFIFO(hsdio->Instance);
1041 *tempbuff = (uint8_t)(data & 0xFFU);
1042 tempbuff++;
1043 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
1044 tempbuff++;
1045 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
1046 tempbuff++;
1047 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
1048 tempbuff++;
1049 }
1050 dataremaining -= 32U;
1051 }
1052 else if (dataremaining < 32U)
1053 {
1054 while ((dataremaining > 0U) && !(__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_RXFIFOE)))
1055 {
1056 data = SDMMC_ReadFIFO(hsdio->Instance);
1057 for (byteCount = 0U; byteCount < 4U; byteCount++)
1058 {
1059 if (dataremaining > 0U)
1060 {
1061 *tempbuff = (uint8_t)((data >> (byteCount * 8U)) & 0xFFU);
1062 tempbuff++;
1063 dataremaining--;
1064 }
1065 }
1066 }
1067 }
1068 else
1069 {
1070 /* Nothing to do */
1071 }
1072 if ((HAL_GetTick() - tickstart) >= Timeout_Ms)
1073 {
1074 /* Clear all the static flags */
1075 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1076 hsdio->ErrorCode |= HAL_SDIO_ERROR_TIMEOUT;
1077 hsdio->State = HAL_SDIO_STATE_READY;
1078 hsdio->Context = SDIO_CONTEXT_NONE;
1079 return HAL_TIMEOUT;
1080 }
1081 }
1082 __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
1083 /* Get error state */
1084 if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DTIMEOUT))
1085 {
1086 /* Clear all the static flags */
1087 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1088 hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_TIMEOUT;
1089 hsdio->State = HAL_SDIO_STATE_READY;
1090 hsdio->Context = SDIO_CONTEXT_NONE;
1091 return HAL_ERROR;
1092 }
1093 else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DCRCFAIL))
1094 {
1095 /* Clear all the static flags */
1096 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1097 hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_CRC_FAIL;
1098 hsdio->State = HAL_SDIO_STATE_READY;
1099 hsdio->Context = SDIO_CONTEXT_NONE;
1100 return HAL_ERROR;
1101 }
1102 else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_RXOVERR))
1103 {
1104 /* Clear all the static flags */
1105 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1106 /* (SDIO_WRITE << 31) correspond to the write or read bit of the CMD argument */
1107 hsdio->ErrorCode |= HAL_SDIO_ERROR_RX_OVERRUN;
1108 hsdio->State = HAL_SDIO_STATE_READY;
1109 hsdio->Context = SDIO_CONTEXT_NONE;
1110 return HAL_ERROR;
1111 }
1112 else if (hsdio->ErrorCode == SDMMC_ERROR_INVALID_PARAMETER)
1113 {
1114 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
1115 hsdio->State = HAL_SDIO_STATE_READY;
1116 hsdio->Context = SDIO_CONTEXT_NONE;
1117 return HAL_ERROR;
1118 }
1119 else
1120 {
1121 /* Nothing to do */
1122 }
1123
1124 /* Clear all the static flags */
1125 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
1126
1127 hsdio->State = HAL_SDIO_STATE_READY;
1128 }
1129 else
1130 {
1131 return HAL_BUSY;
1132 }
1133
1134 return HAL_OK;
1135 }
1136
1137 /**
1138 * @brief Write data from a specified address using extended mode through cmd53.
1139 * @param hsdio: Pointer to SDIO handle
1140 * @param Argument: Pointer to SDIO argument
1141 * @param pData: pointer to the buffer that will contain the data to transmit
1142 * @param Size_byte: Block size to write.
1143 * @param Timeout_Ms: Specify timeout value
1144 * @retval HAL status
1145 */
HAL_SDIO_WriteExtended(SDIO_HandleTypeDef * hsdio,HAL_SDIO_ExtendedCmd_TypeDef * Argument,uint8_t * pData,uint32_t Size_byte,uint32_t Timeout_Ms)1146 HAL_StatusTypeDef HAL_SDIO_WriteExtended(SDIO_HandleTypeDef *hsdio, HAL_SDIO_ExtendedCmd_TypeDef *Argument,
1147 uint8_t *pData, uint32_t Size_byte, uint32_t Timeout_Ms)
1148 {
1149 uint32_t cmd;
1150 SDMMC_DataInitTypeDef config;
1151 uint32_t errorstate;
1152 uint32_t tickstart = HAL_GetTick();
1153 uint32_t regCount;
1154 uint8_t byteCount;
1155 uint32_t data;
1156 uint32_t dataremaining;
1157 uint8_t *u32tempbuff = pData;
1158 uint32_t nbr_of_block;
1159
1160 /* Check the parameters */
1161 assert_param(hsdio != NULL);
1162 assert_param(Argument != NULL);
1163 assert_param(pData != NULL);
1164
1165 if ((hsdio == NULL) || (Argument == NULL) || (pData == NULL))
1166 {
1167 return HAL_ERROR;
1168 }
1169
1170 if (hsdio->State == HAL_SDIO_STATE_READY)
1171 {
1172 hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
1173 hsdio->State = HAL_SDIO_STATE_BUSY;
1174
1175 /* Compute how many blocks are to be send for pData of length data_size to be send */
1176 nbr_of_block = (Size_byte & ~(hsdio->block_size & 1U)) >> __CLZ(__RBIT(hsdio->block_size));
1177
1178 /* Initialize data control register */
1179 if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
1180 {
1181 hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
1182 }
1183 else
1184 {
1185 hsdio->Instance->DCTRL = 0U;
1186 }
1187
1188 /* Configure the SDIO DPSM (Data Path State Machine) */
1189 config.DataTimeOut = SDMMC_DATATIMEOUT;
1190 if (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK)
1191 {
1192 config.DataLength = (uint32_t)(nbr_of_block * hsdio->block_size);
1193 config.DataBlockSize = SDIO_Convert_Block_Size(hsdio, hsdio->block_size);
1194 }
1195 else
1196 {
1197 config.DataLength = (Size_byte > 0U) ? Size_byte : HAL_SDIO_DATA_BLOCK_SIZE_512BYTE;
1198 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
1199 }
1200
1201 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1202 /* (HAL_SDIO_MODE_BLOCK << 27) corresponds to the block mode bit of the CMD argument */
1203 config.TransferMode = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDMMC_TRANSFER_MODE_BLOCK :
1204 SDMMC_TRANSFER_MODE_SDIO;
1205 config.DPSM = SDMMC_DPSM_DISABLE;
1206 (void)SDMMC_ConfigData(hsdio->Instance, &config);
1207 __SDMMC_CMDTRANS_ENABLE(hsdio->Instance);
1208
1209 /* Correspond to the write or read bit of the CMD argument */
1210 hsdio->Context = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDIO_CONTEXT_WRITE_MULTIPLE_BLOCK :
1211 SDIO_CONTEXT_WRITE_SINGLE_BLOCK;
1212 cmd = SDIO_WRITE << 31U;
1213 cmd |= Argument->IOFunctionNbr << 28U;
1214 cmd |= Argument->Block_Mode << 27U;
1215 cmd |= Argument->OpCode << 26U;
1216 cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
1217 cmd |= (Size_byte & 0x1FFU);
1218 errorstate = SDMMC_SDIO_CmdReadWriteExtended(hsdio->Instance, cmd);
1219 if (errorstate != HAL_SDIO_ERROR_NONE)
1220 {
1221 hsdio->ErrorCode |= errorstate;
1222 if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
1223 SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
1224 {
1225 MODIFY_REG(hsdio->Instance->DCTRL, SDMMC_DCTRL_FIFORST, SDMMC_DCTRL_FIFORST);
1226 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1227 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
1228 hsdio->State = HAL_SDIO_STATE_READY;
1229 hsdio->Context = SDIO_CONTEXT_NONE;
1230 return HAL_ERROR;
1231 }
1232 }
1233 /* Write block(s) in polling mode */
1234 dataremaining = config.DataLength;
1235 while (!__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT |
1236 SDMMC_FLAG_DATAEND))
1237 {
1238
1239 if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= 32U))
1240 {
1241 /* Read data from SDMMC Rx FIFO */
1242 for (regCount = 0U; regCount < 8U; regCount++)
1243 {
1244 hsdio->Instance->FIFO = *u32tempbuff;
1245 u32tempbuff++;
1246 }
1247 dataremaining -= 32U;
1248 }
1249 else if ((dataremaining < 32U) && (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXFIFOHE | SDMMC_FLAG_TXFIFOE)))
1250 {
1251 uint8_t *u8buff = (uint8_t *)u32tempbuff;
1252 while (dataremaining > 0U)
1253 {
1254 data = 0U;
1255 for (byteCount = 0U; (byteCount < 4U) && (dataremaining > 0U); byteCount++)
1256 {
1257 data |= ((uint32_t)(*u8buff) << (byteCount << 3U));
1258 u8buff++;
1259 dataremaining--;
1260 }
1261 hsdio->Instance->FIFO = data;
1262 }
1263 }
1264 if (((HAL_GetTick() - tickstart) >= Timeout_Ms))
1265 {
1266 /* Clear all the static flags */
1267 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1268 hsdio->ErrorCode |= HAL_SDIO_ERROR_TIMEOUT;
1269 hsdio->State = HAL_SDIO_STATE_READY;
1270 hsdio->Context = SDIO_CONTEXT_NONE;
1271 return HAL_TIMEOUT;
1272 }
1273 }
1274
1275 __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
1276 /* Get error state */
1277 if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DTIMEOUT))
1278 {
1279 /* Clear all the static flags */
1280 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1281 hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_TIMEOUT;
1282 hsdio->State = HAL_SDIO_STATE_READY;
1283 hsdio->Context = SDIO_CONTEXT_NONE;
1284 return HAL_ERROR;
1285 }
1286 else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DCRCFAIL))
1287 {
1288 /* Clear all the static flags */
1289 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1290 hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_CRC_FAIL;
1291 hsdio->State = HAL_SDIO_STATE_READY;
1292 hsdio->Context = SDIO_CONTEXT_NONE;
1293 return HAL_ERROR;
1294 }
1295 else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXUNDERR))
1296 {
1297 /* Clear all the static flags */
1298 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1299 /* (SDIO_WRITE << 31) correspond to the write or read bit of the CMD argument */
1300 hsdio->ErrorCode |= HAL_SDIO_ERROR_TX_UNDERRUN;
1301 hsdio->State = HAL_SDIO_STATE_READY;
1302 hsdio->Context = SDIO_CONTEXT_NONE;
1303 return HAL_ERROR;
1304 }
1305 else if (hsdio->ErrorCode == SDMMC_ERROR_INVALID_PARAMETER)
1306 {
1307 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
1308 hsdio->State = HAL_SDIO_STATE_READY;
1309 hsdio->Context = SDIO_CONTEXT_NONE;
1310 return HAL_ERROR;
1311 }
1312 else
1313 {
1314 /* Nothing to do */
1315 }
1316
1317 /* Clear all the static flags */
1318 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
1319
1320 hsdio->State = HAL_SDIO_STATE_READY;
1321 }
1322 else
1323 {
1324 return HAL_BUSY;
1325 }
1326
1327 return HAL_OK;
1328 }
1329
1330 /**
1331 * @brief Read data from a specified address using extended mode through cmd53 in DMA mode.
1332 * @param hsdio: Pointer to SDIO handle
1333 * @param Argument: Pointer to SDIO argument
1334 * @param pData: pointer to the buffer that will contain the data to transmit
1335 * @param Size_byte: Block size to write.
1336 * @retval HAL status
1337 */
HAL_SDIO_ReadExtended_DMA(SDIO_HandleTypeDef * hsdio,HAL_SDIO_ExtendedCmd_TypeDef * Argument,uint8_t * pData,uint32_t Size_byte)1338 HAL_StatusTypeDef HAL_SDIO_ReadExtended_DMA(SDIO_HandleTypeDef *hsdio, HAL_SDIO_ExtendedCmd_TypeDef *Argument,
1339 uint8_t *pData, uint32_t Size_byte)
1340 {
1341 SDMMC_DataInitTypeDef config;
1342 uint32_t errorstate;
1343 uint8_t *p_dma_buffer;
1344 uint32_t cmd;
1345 uint32_t nbr_of_block;
1346
1347 /* Check the parameters */
1348 assert_param(hsdio != NULL);
1349 assert_param(Argument != NULL);
1350 assert_param(pData != NULL);
1351
1352 if ((hsdio == NULL) || (Argument == NULL) || (pData == NULL))
1353 {
1354 return HAL_ERROR;
1355 }
1356
1357 if (hsdio->State == HAL_SDIO_STATE_READY)
1358 {
1359 hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
1360 hsdio->State = HAL_SDIO_STATE_BUSY;
1361
1362 /* Initialize data control register */
1363 if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
1364 {
1365 hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
1366 }
1367 else
1368 {
1369 hsdio->Instance->DCTRL = 0U;
1370 }
1371
1372 p_dma_buffer = (uint8_t *)pData;
1373 hsdio->pRxBuffPtr = (uint8_t *)pData;
1374 hsdio->RxXferSize = Size_byte;
1375 hsdio->next_data_addr = (uint32_t)pData;
1376
1377 /* Compute how many blocks are to be send for pData of length data_size to be send */
1378 nbr_of_block = (Size_byte & ~(hsdio->block_size & 1U)) >> __CLZ(__RBIT(hsdio->block_size));
1379
1380 if (nbr_of_block != 0U)
1381 {
1382 hsdio->remaining_data = (Size_byte - (hsdio->block_size * nbr_of_block));
1383 hsdio->next_reg_addr = (Argument->Reg_Addr) | ((((nbr_of_block * hsdio->block_size) >> 1U) & 0x3FFFU) << 1U)
1384 | ((hsdio->remaining_data <= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? 1U : 0U);
1385 hsdio->next_data_addr += (nbr_of_block * hsdio->block_size);
1386 }
1387 else
1388 {
1389 hsdio->next_data_addr += (Size_byte < HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? Size_byte :
1390 HAL_SDIO_DATA_BLOCK_SIZE_512BYTE;
1391 if (hsdio->remaining_data != 0U)
1392 {
1393 hsdio->remaining_data = (Size_byte >= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ?
1394 (Size_byte - HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) :
1395 (Size_byte - hsdio->remaining_data);
1396 hsdio->next_reg_addr += (Size_byte >= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? \
1397 (HAL_SDIO_DATA_BLOCK_SIZE_512BYTE + 1U) : (Size_byte + 1U);
1398 }
1399 }
1400
1401 /* DMA configuration (use single buffer) */
1402 hsdio->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1403 hsdio->Instance->IDMABASER = (uint32_t)p_dma_buffer;
1404
1405 /* Configure the SD DPSM (Data Path State Machine) */
1406 config.DataTimeOut = SDMMC_DATATIMEOUT;
1407 if (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK)
1408 {
1409 config.DataLength = (uint32_t)(nbr_of_block * hsdio->block_size);
1410 config.DataBlockSize = SDIO_Convert_Block_Size(hsdio, hsdio->block_size);
1411 }
1412 else
1413 {
1414 config.DataLength = (Size_byte > 0U) ? Size_byte : HAL_SDIO_DATA_BLOCK_SIZE_512BYTE;
1415 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
1416 }
1417
1418 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC ;
1419 config.TransferMode = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDMMC_TRANSFER_MODE_BLOCK :
1420 SDMMC_TRANSFER_MODE_SDIO;
1421 config.DPSM = SDMMC_DPSM_DISABLE;
1422 (void)SDMMC_ConfigData(hsdio->Instance, &config);
1423
1424 __SDMMC_CMDTRANS_ENABLE(hsdio->Instance);
1425
1426 /* Read */
1427 hsdio->Context = (uint32_t)((Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDIO_CONTEXT_READ_MULTIPLE_BLOCK :
1428 SDIO_CONTEXT_READ_SINGLE_BLOCK) | SDIO_CONTEXT_DMA;
1429
1430 cmd = SDIO_READ << 31U;
1431 cmd |= Argument->IOFunctionNbr << 28U;
1432 cmd |= Argument->Block_Mode << 27U;
1433 cmd |= Argument->OpCode << 26U;
1434 cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
1435 cmd |= ((nbr_of_block == 0U) ? Size_byte : nbr_of_block) & 0x1FFU;
1436 errorstate = SDMMC_SDIO_CmdReadWriteExtended(hsdio->Instance, cmd);
1437 if (errorstate != HAL_SDIO_ERROR_NONE)
1438 {
1439 hsdio->ErrorCode |= errorstate;
1440 if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
1441 SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
1442 {
1443 MODIFY_REG(hsdio->Instance->DCTRL, SDMMC_DCTRL_FIFORST, SDMMC_DCTRL_FIFORST);
1444 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1445 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
1446 hsdio->State = HAL_SDIO_STATE_READY;
1447 hsdio->Context = SDIO_CONTEXT_NONE;
1448 return HAL_ERROR;
1449 }
1450 }
1451 /* Enable interrupt */
1452 __HAL_SDIO_ENABLE_IT(hsdio, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1453 }
1454 else
1455 {
1456 return HAL_BUSY;
1457 }
1458
1459 return HAL_OK;
1460 }
1461
1462 /**
1463 * @brief Write data from a specified address using extended mode through cmd53 in DMA mode.
1464 * @param hsdio: Pointer to SDIO handle
1465 * @param Argument: Pointer to SDIO argument
1466 * @param pData: pointer to the buffer that will contain the data to transmit
1467 * @param Size_byte: Block size to write.
1468 * @retval HAL status
1469 */
HAL_SDIO_WriteExtended_DMA(SDIO_HandleTypeDef * hsdio,HAL_SDIO_ExtendedCmd_TypeDef * Argument,uint8_t * pData,uint32_t Size_byte)1470 HAL_StatusTypeDef HAL_SDIO_WriteExtended_DMA(SDIO_HandleTypeDef *hsdio, HAL_SDIO_ExtendedCmd_TypeDef *Argument,
1471 uint8_t *pData, uint32_t Size_byte)
1472 {
1473 uint32_t cmd;
1474 SDMMC_DataInitTypeDef config;
1475 uint32_t errorstate;
1476 uint8_t *p_dma_buffer;
1477 uint32_t nbr_of_block;
1478
1479 /* Check the parameters */
1480 assert_param(hsdio != NULL);
1481 assert_param(Argument != NULL);
1482 assert_param(pData != NULL);
1483
1484 if ((hsdio == NULL) || (Argument == NULL) || (pData == NULL))
1485 {
1486 return HAL_ERROR;
1487 }
1488
1489 if (hsdio->State == HAL_SDIO_STATE_READY)
1490 {
1491 hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
1492 hsdio->State = HAL_SDIO_STATE_BUSY;
1493
1494 /* Initialize data control register */
1495 if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
1496 {
1497 hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
1498 }
1499 else
1500 {
1501 hsdio->Instance->DCTRL = 0U;
1502 }
1503
1504 p_dma_buffer = (uint8_t *)pData;
1505 hsdio->pTxBuffPtr = (uint8_t *)pData;
1506 hsdio->TxXferSize = Size_byte;
1507 hsdio->next_data_addr = (uint32_t)pData;
1508
1509 nbr_of_block = (Size_byte & ~(hsdio->block_size & 1U)) >> __CLZ(__RBIT(hsdio->block_size));
1510
1511 if (nbr_of_block != 0U)
1512 {
1513 hsdio->remaining_data = (Size_byte - (hsdio->block_size * nbr_of_block));
1514 if (hsdio->block_size <= 128U)
1515 {
1516 hsdio->next_reg_addr = (Argument->Reg_Addr) |
1517 ((((nbr_of_block * hsdio->block_size) >> 1U) & 0x3FFFU) << 1U) |
1518 ((hsdio->remaining_data <= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? 1U : 0U);
1519 }
1520 else
1521 {
1522 hsdio->next_reg_addr = (nbr_of_block * hsdio->block_size) >> 1U;
1523 }
1524 hsdio->next_data_addr += (nbr_of_block * hsdio->block_size);
1525 }
1526 else
1527 {
1528 hsdio->remaining_data = (Size_byte >= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ?
1529 (Size_byte - HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) :
1530 (Size_byte - hsdio->remaining_data);
1531 if (hsdio->remaining_data != 0U)
1532 {
1533 hsdio->remaining_data = (Size_byte >= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ?
1534 (Size_byte - HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) :
1535 (Size_byte - hsdio->remaining_data);
1536 hsdio->next_reg_addr += ((Size_byte >= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? \
1537 (HAL_SDIO_DATA_BLOCK_SIZE_512BYTE >> 1U) : (Size_byte >> 1U)) |
1538 (((hsdio->remaining_data > 0U) ? 0U : 1U));
1539 }
1540 hsdio->next_data_addr += (Size_byte < HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? Size_byte :
1541 HAL_SDIO_DATA_BLOCK_SIZE_512BYTE;
1542 }
1543
1544 /* DMA configuration (use single buffer) */
1545 hsdio->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1546 hsdio->Instance->IDMABASER = (uint32_t)p_dma_buffer;
1547
1548 /* Configure the SDIO DPSM (Data Path State Machine) */
1549 config.DataTimeOut = SDMMC_DATATIMEOUT;
1550 if (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK)
1551 {
1552 config.DataLength = (uint32_t)(nbr_of_block * hsdio->block_size);
1553 config.DataBlockSize = SDIO_Convert_Block_Size(hsdio, hsdio->block_size);
1554 }
1555 else
1556 {
1557 config.DataLength = (Size_byte > HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? HAL_SDIO_DATA_BLOCK_SIZE_512BYTE : Size_byte;
1558 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
1559 }
1560
1561 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1562 config.TransferMode = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDMMC_TRANSFER_MODE_BLOCK
1563 : SDMMC_TRANSFER_MODE_SDIO;
1564 config.DPSM = SDMMC_DPSM_DISABLE;
1565 (void)SDMMC_ConfigData(hsdio->Instance, &config);
1566
1567 __SDMMC_CMDTRANS_ENABLE(hsdio->Instance);
1568
1569 /* Write */
1570 hsdio->Context = (uint32_t)((Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ?
1571 SDIO_CONTEXT_WRITE_MULTIPLE_BLOCK :
1572 SDIO_CONTEXT_WRITE_SINGLE_BLOCK) | SDIO_CONTEXT_DMA;
1573 cmd = SDIO_WRITE << 31U;
1574 cmd |= Argument->IOFunctionNbr << 28U;
1575 cmd |= Argument->Block_Mode << 27U;
1576 cmd |= Argument->OpCode << 26U;
1577 cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
1578 cmd |= ((nbr_of_block == 0U) ? ((Size_byte > HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ?
1579 HAL_SDIO_DATA_BLOCK_SIZE_512BYTE : Size_byte) : nbr_of_block) & 0x1FFU;
1580 errorstate = SDMMC_SDIO_CmdReadWriteExtended(hsdio->Instance, cmd);
1581 if (errorstate != HAL_SDIO_ERROR_NONE)
1582 {
1583 hsdio->ErrorCode |= errorstate;
1584 if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
1585 SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
1586 {
1587 MODIFY_REG(hsdio->Instance->DCTRL, SDMMC_DCTRL_FIFORST, SDMMC_DCTRL_FIFORST);
1588 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
1589 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
1590 hsdio->State = HAL_SDIO_STATE_READY;
1591 hsdio->Context = SDIO_CONTEXT_NONE;
1592 return HAL_ERROR;
1593 }
1594 }
1595 /* Enable interrupt */
1596 __HAL_SDIO_ENABLE_IT(hsdio, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1597 }
1598 else
1599 {
1600 return HAL_BUSY;
1601 }
1602
1603 return HAL_OK;
1604 }
1605
1606 /**
1607 * @}
1608 */
1609
1610 /** @addtogroup SDIO_Exported_Functions_Group4
1611 * @brief
1612 *
1613 @verbatim
1614 ==============================================================================
1615 ##### IO operation functions #####
1616 ==============================================================================
1617 [..]
1618 This subsection provides a set callback functions allowing to manage the data transfer from/to SDIO card.
1619
1620 @endverbatim
1621 * @{
1622 */
1623 /**
1624 * @brief This function handles SDIO device interrupt request.
1625 * @param hsdio: Pointer to SDIO handle
1626 * @retval None
1627 */
HAL_SDIO_IRQHandler(SDIO_HandleTypeDef * hsdio)1628 void HAL_SDIO_IRQHandler(SDIO_HandleTypeDef *hsdio)
1629 {
1630 HAL_SDIO_ExtendedCmd_TypeDef CMD53_desc;
1631 HAL_StatusTypeDef errorstate;
1632 uint32_t ctx = hsdio->Context;
1633 uint32_t flags;
1634
1635 flags = READ_REG(((SDMMC_TypeDef *)((uint32_t)(hsdio)->Instance))->STA);
1636
1637 if (READ_BIT(flags, SDMMC_FLAG_SDIOIT) != 0U)
1638 {
1639 (void)SDIO_IOFunction_IRQHandler(hsdio);
1640 }
1641
1642 if (READ_BIT(flags, SDMMC_FLAG_DATAEND) != 0U)
1643 {
1644 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_FLAG_DATAEND);
1645
1646 hsdio->State = HAL_SDIO_STATE_READY;
1647
1648 __HAL_SDIO_DISABLE_IT(hsdio, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR |
1649 SDMMC_IT_RXOVERR | SDMMC_IT_TXFIFOHE | SDMMC_IT_RXFIFOHF);
1650
1651 __HAL_SDIO_DISABLE_IT(hsdio, SDMMC_IT_IDMABTC);
1652 __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
1653
1654 if ((ctx & SDIO_CONTEXT_DMA) != 0U)
1655 {
1656 hsdio->Instance->DLEN = 0;
1657 hsdio->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
1658 if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
1659 {
1660 hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
1661 }
1662 else
1663 {
1664 hsdio->Instance->DCTRL = 0U;
1665 }
1666
1667 hsdio->Context = SDIO_CONTEXT_NONE;
1668 hsdio->State = HAL_SDIO_STATE_READY;
1669 }
1670
1671 if (hsdio->remaining_data != 0U)
1672 {
1673 CMD53_desc.Block_Mode = HAL_SDIO_MODE_BYTE;
1674 CMD53_desc.Reg_Addr = hsdio->next_reg_addr;
1675 CMD53_desc.IOFunctionNbr = 1;
1676 CMD53_desc.OpCode = 1;
1677 if (((ctx & SDIO_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((ctx & SDIO_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1678 {
1679 hsdio->pRxBuffPtr = (uint8_t *)hsdio->next_data_addr;
1680 errorstate = HAL_SDIO_ReadExtended_DMA(hsdio, &CMD53_desc, hsdio->pRxBuffPtr, hsdio->remaining_data);
1681 }
1682 else
1683 {
1684 hsdio->pTxBuffPtr = (uint8_t *)hsdio->next_data_addr;
1685 errorstate = HAL_SDIO_WriteExtended_DMA(hsdio, &CMD53_desc, hsdio->pTxBuffPtr, hsdio->remaining_data);
1686 }
1687 if (errorstate != HAL_OK)
1688 {
1689 #if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1)
1690 hsdio->ErrorCallback(hsdio);
1691 #else
1692 HAL_SDIO_ErrorCallback(hsdio);
1693 #endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
1694 }
1695 }
1696 else if (((ctx & SDIO_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((ctx & SDIO_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1697 {
1698 #if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1U)
1699 hsdio->RxCpltCallback(hsdio);
1700 #else
1701 HAL_SDIO_RxCpltCallback(hsdio);
1702 #endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
1703 }
1704 else
1705 {
1706 #if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1U)
1707 hsdio->TxCpltCallback(hsdio);
1708 #else
1709 HAL_SDIO_TxCpltCallback(hsdio);
1710 #endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
1711 }
1712 }
1713
1714 if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR))
1715 {
1716 #if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1)
1717 hsdio->ErrorCallback(hsdio);
1718 #else
1719 HAL_SDIO_ErrorCallback(hsdio);
1720 #endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
1721 }
1722 }
1723
1724 /**
1725 * @brief Tx Transfer completed callbacks
1726 * @param hsdio: Pointer to SDIO handle
1727 * @retval None
1728 */
HAL_SDIO_TxCpltCallback(SDIO_HandleTypeDef * hsdio)1729 __weak void HAL_SDIO_TxCpltCallback(SDIO_HandleTypeDef *hsdio)
1730 {
1731 /* Prevent unused argument(s) compilation warning */
1732 UNUSED(hsdio);
1733
1734 /* NOTE : This function should not be modified, when the callback is needed,
1735 the HAL_SDIO_TxCpltCallback can be implemented in the user file
1736 */
1737 }
1738
1739 /**
1740 * @brief Rx Transfer completed callbacks
1741 * @param hsdio: Pointer SDIO handle
1742 * @retval None
1743 */
HAL_SDIO_RxCpltCallback(SDIO_HandleTypeDef * hsdio)1744 __weak void HAL_SDIO_RxCpltCallback(SDIO_HandleTypeDef *hsdio)
1745 {
1746 /* Prevent unused argument(s) compilation warning */
1747 UNUSED(hsdio);
1748
1749 /* NOTE : This function should not be modified, when the callback is needed,
1750 the HAL_SDIO_RxCpltCallback can be implemented in the user file
1751 */
1752 }
1753
1754 /**
1755 * @brief SDIO error callbacks
1756 * @param hsdio: Pointer SDIO handle
1757 * @retval None
1758 */
HAL_SDIO_ErrorCallback(SDIO_HandleTypeDef * hsdio)1759 __weak void HAL_SDIO_ErrorCallback(SDIO_HandleTypeDef *hsdio)
1760 {
1761 /* Prevent unused argument(s) compilation warning */
1762 UNUSED(hsdio);
1763
1764 /* NOTE : This function should not be modified, when the callback is needed,
1765 the HAL_SDIO_ErrorCallback can be implemented in the user file
1766 */
1767 }
1768
1769 /**
1770 * @brief SDIO IO Function complete callback
1771 * @param hsdio: Pointer SDIO handle
1772 * @param func: SDIO IO Function
1773 * @retval None
1774 */
HAL_SDIO_IOFunctionCallback(SDIO_HandleTypeDef * hsdio,uint32_t func)1775 __weak void HAL_SDIO_IOFunctionCallback(SDIO_HandleTypeDef *hsdio, uint32_t func)
1776 {
1777 /* Prevent unused argument(s) compilation warning */
1778 UNUSED(hsdio);
1779 UNUSED(func);
1780
1781 /* NOTE : This function should not be modified, when the callback is needed,
1782 the HAL_SDIO_ErrorCallback can be implemented in the user file
1783 */
1784 }
1785
1786 #if (USE_SDIO_TRANSCEIVER != 0U)
1787 /**
1788 * @brief Enable/Disable the SDIO Transceiver 1.8V Mode Callback.
1789 * @param hsdio: Pointer SDIO handle
1790 * @param status: Voltage Switch State
1791 * @retval None
1792 */
HAL_SDIO_DriveTransceiver_1_8V_Callback(SDIO_HandleTypeDef * hsdio,FlagStatus status)1793 __weak void HAL_SDIO_DriveTransceiver_1_8V_Callback(SDIO_HandleTypeDef *hsdio, FlagStatus status)
1794 {
1795 /* Prevent unused argument(s) compilation warning */
1796 UNUSED(hsdio);
1797 UNUSED(status);
1798 /* NOTE : This function should not be modified, when the callback is needed,
1799 the HAL_SDIO_EnableTransceiver could be implemented in the user file
1800 */
1801 }
1802 #endif /* USE_SDIO_TRANSCEIVER */
1803
1804 #if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1U)
1805 /**
1806 * @brief Register a User SDIO Callback
1807 * To be used instead of the weak (overridden) predefined callback
1808 * @param hsdio : SDIO handle
1809 * @param CallbackID : ID of the callback to be registered
1810 * This parameter can be one of the following values:
1811 * @arg @ref HAL_SDIO_TX_CPLT_CB_ID SDIO Tx Complete Callback ID
1812 * @arg @ref HAL_SDIO_RX_CPLT_CB_ID SDIO Rx Complete Callback ID
1813 * @arg @ref HAL_SDIO_ERROR_CB_ID SDIO Error Callback ID
1814 * @arg @ref HAL_SDIO_MSP_INIT_CB_ID SDIO MspInit Callback ID
1815 * @arg @ref HAL_SDIO_MSP_DEINIT_CB_ID SDIO MspDeInit Callback ID
1816 * @param pCallback : pointer to the Callback function
1817 * @retval status
1818 */
HAL_SDIO_RegisterCallback(SDIO_HandleTypeDef * hsdio,HAL_SDIO_CallbackIDTypeDef CallbackID,pSDIO_CallbackTypeDef pCallback)1819 HAL_StatusTypeDef HAL_SDIO_RegisterCallback(SDIO_HandleTypeDef *hsdio, HAL_SDIO_CallbackIDTypeDef CallbackID,
1820 pSDIO_CallbackTypeDef pCallback)
1821 {
1822 HAL_StatusTypeDef status = HAL_OK;
1823
1824 /* Check the parameters */
1825 assert_param(hsdio != NULL);
1826 assert_param(pCallback != NULL);
1827
1828 if (pCallback == NULL)
1829 {
1830 /* Update the error code */
1831 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
1832 return HAL_ERROR;
1833 }
1834
1835 if (hsdio->State == HAL_SDIO_STATE_READY)
1836 {
1837 switch (CallbackID)
1838 {
1839 case HAL_SDIO_TX_CPLT_CB_ID :
1840 hsdio->TxCpltCallback = pCallback;
1841 break;
1842 case HAL_SDIO_RX_CPLT_CB_ID :
1843 hsdio->RxCpltCallback = pCallback;
1844 break;
1845 case HAL_SDIO_ERROR_CB_ID :
1846 hsdio->ErrorCallback = pCallback;
1847 break;
1848 case HAL_SDIO_MSP_INIT_CB_ID :
1849 hsdio->MspInitCallback = pCallback;
1850 break;
1851 case HAL_SDIO_MSP_DEINIT_CB_ID :
1852 hsdio->MspDeInitCallback = pCallback;
1853 break;
1854 default :
1855 /* Update the error code */
1856 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
1857 /* update return status */
1858 status = HAL_ERROR;
1859 break;
1860 }
1861 }
1862 else if (hsdio->State == HAL_SDIO_STATE_RESET)
1863 {
1864 switch (CallbackID)
1865 {
1866 case HAL_SDIO_MSP_INIT_CB_ID :
1867 hsdio->MspInitCallback = pCallback;
1868 break;
1869 case HAL_SDIO_MSP_DEINIT_CB_ID :
1870 hsdio->MspDeInitCallback = pCallback;
1871 break;
1872 default :
1873 /* Update the error code */
1874 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
1875 /* update return status */
1876 status = HAL_ERROR;
1877 break;
1878 }
1879 }
1880 else
1881 {
1882 /* Update the error code */
1883 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
1884 /* update return status */
1885 status = HAL_ERROR;
1886 }
1887
1888 return status;
1889 }
1890
1891 /**
1892 * @brief Unregister a User SDIO Callback
1893 * SDIO Callback is redirected to the weak (overridden) predefined callback.
1894 * @note The HAL_SDIO_UnRegisterCallback() may be called before HAL_SDIO_Init() in
1895 * HAL_SDIO_STATE_RESET to register callbacks for HAL_SDIO_MSP_INIT_CB_ID
1896 * and HAL_SDIO_MSP_DEINIT_CB_ID.
1897 * @param hsdio : SDIO handle
1898 * @param CallbackID : ID of the callback to be unregistered
1899 * This parameter can be one of the following values @ref SDIO_Exported_Types_Group3.
1900 * @retval status
1901 */
HAL_SDIO_UnRegisterCallback(SDIO_HandleTypeDef * hsdio,HAL_SDIO_CallbackIDTypeDef CallbackID)1902 HAL_StatusTypeDef HAL_SDIO_UnRegisterCallback(SDIO_HandleTypeDef *hsdio, HAL_SDIO_CallbackIDTypeDef CallbackID)
1903 {
1904 HAL_StatusTypeDef status = HAL_OK;
1905
1906 assert_param(hsdio != NULL);
1907
1908 /* Check the SDIO peripheral handle parameter */
1909 if (hsdio == NULL)
1910 {
1911 return HAL_ERROR;
1912 }
1913
1914 if (hsdio->State == HAL_SDIO_STATE_READY)
1915 {
1916 switch (CallbackID)
1917 {
1918 case HAL_SDIO_TX_CPLT_CB_ID :
1919 hsdio->TxCpltCallback = HAL_SDIO_TxCpltCallback;
1920 break;
1921 case HAL_SDIO_RX_CPLT_CB_ID :
1922 hsdio->RxCpltCallback = HAL_SDIO_RxCpltCallback;
1923 break;
1924 case HAL_SDIO_ERROR_CB_ID :
1925 hsdio->ErrorCallback = HAL_SDIO_ErrorCallback;
1926 break;
1927 case HAL_SDIO_MSP_INIT_CB_ID :
1928 hsdio->MspInitCallback = HAL_SDIO_MspInit;
1929 break;
1930 case HAL_SDIO_MSP_DEINIT_CB_ID :
1931 hsdio->MspDeInitCallback = HAL_SDIO_MspDeInit;
1932 break;
1933 default :
1934 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
1935 status = HAL_ERROR;
1936 break;
1937 }
1938 }
1939 else if (hsdio->State == HAL_SDIO_STATE_RESET)
1940 {
1941 switch (CallbackID)
1942 {
1943 case HAL_SDIO_MSP_INIT_CB_ID :
1944 hsdio->MspInitCallback = HAL_SDIO_MspInit;
1945 break;
1946 case HAL_SDIO_MSP_DEINIT_CB_ID :
1947 hsdio->MspDeInitCallback = HAL_SDIO_MspDeInit;
1948 break;
1949 default :
1950 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
1951 status = HAL_ERROR;
1952 break;
1953 }
1954 }
1955 else
1956 {
1957 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
1958 status = HAL_ERROR;
1959 }
1960
1961 return status;
1962 }
1963 #endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
1964
1965 #if (USE_SDIO_TRANSCEIVER != 0U)
1966 /**
1967 * @brief Register a User SDIO Transceiver Callback
1968 * To be used instead of the weak (overridden) predefined callback
1969 * @param hsdio : SDIO handle
1970 * @param pCallback : pointer to the Callback function
1971 * @retval status
1972 */
HAL_SDIO_RegisterTransceiverCallback(SDIO_HandleTypeDef * hsdio,pSDIO_TransceiverCallbackTypeDef pCallback)1973 HAL_StatusTypeDef HAL_SDIO_RegisterTransceiverCallback(SDIO_HandleTypeDef *hsdio,
1974 pSDIO_TransceiverCallbackTypeDef pCallback)
1975 {
1976 HAL_StatusTypeDef status = HAL_OK;
1977
1978 if (pCallback == NULL)
1979 {
1980 /* Update the error code */
1981 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
1982 return HAL_ERROR;
1983 }
1984
1985 if (hsdio->State == HAL_SDIO_STATE_READY)
1986 {
1987 hsdio->DriveTransceiver_1_8V_Callback = pCallback;
1988 }
1989 else
1990 {
1991 /* Update the error code */
1992 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
1993 /* update return status */
1994 status = HAL_ERROR;
1995 }
1996
1997 return status;
1998 }
1999
2000 /**
2001 * @brief Unregister a User SDIO Transceiver Callback
2002 * SDIO Callback is redirected to the weak (overridden) predefined callback
2003 * @param hsdio : SDIO handle
2004 * @retval status
2005 */
HAL_SDIO_UnRegisterTransceiverCallback(SDIO_HandleTypeDef * hsdio)2006 HAL_StatusTypeDef HAL_SDIO_UnRegisterTransceiverCallback(SDIO_HandleTypeDef *hsdio)
2007 {
2008 HAL_StatusTypeDef status = HAL_OK;
2009
2010 if (hsdio->State == HAL_SDIO_STATE_READY)
2011 {
2012 hsdio->DriveTransceiver_1_8V_Callback = HAL_SDIO_DriveTransceiver_1_8V_Callback;
2013 }
2014 else
2015 {
2016 /* Update the error code */
2017 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
2018 /* update return status */
2019 status = HAL_ERROR;
2020 }
2021
2022 return status;
2023 }
2024 #endif /* USE_SDIO_TRANSCEIVER */
2025
2026 /**
2027 * @brief Register a User SDIO Identification Callback
2028 * @param hsdio: Pointer to SDIO handle
2029 * @param pCallback: pointer to the Callback function
2030 * @retval status
2031 */
HAL_SDIO_RegisterIdentifyCardCallback(SDIO_HandleTypeDef * hsdio,pSDIO_IdentifyCardCallbackTypeDef pCallback)2032 HAL_StatusTypeDef HAL_SDIO_RegisterIdentifyCardCallback(SDIO_HandleTypeDef *hsdio,
2033 pSDIO_IdentifyCardCallbackTypeDef pCallback)
2034 {
2035 /* Check the parameters */
2036 assert_param(hsdio != NULL);
2037 assert_param(pCallback != NULL);
2038
2039 if (pCallback == NULL)
2040 {
2041 /* Update the error code */
2042 hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
2043 return HAL_ERROR;
2044 }
2045
2046 hsdio->SDIO_IdentifyCard = pCallback;
2047
2048 return HAL_OK;
2049 }
2050 /**
2051 * @}
2052 */
2053
2054 /** @addtogroup SDIO_Exported_Functions_Group5
2055 * @brief
2056 *
2057 @verbatim
2058 ==============================================================================
2059 ##### Peripheral State and Errors functions #####
2060 ==============================================================================
2061 [..]
2062 This subsection provides a set of functions allowing to control the SDIO card operations.
2063
2064 @endverbatim
2065 * @{
2066 */
2067 /**
2068 * @brief return the SDIO state
2069 * @param hsdio: Pointer to SDIO handle
2070 * @retval HAL state
2071 */
HAL_SDIO_GetState(const SDIO_HandleTypeDef * hsdio)2072 HAL_SDIO_StateTypeDef HAL_SDIO_GetState(const SDIO_HandleTypeDef *hsdio)
2073 {
2074 return hsdio->State;
2075 }
2076
2077 /**
2078 * @brief Return the SDIO error code
2079 * @param hsdio : Pointer to a SDIO_HandleTypeDef structure that contains the configuration information.
2080 * @retval SDIO Error Code
2081 */
HAL_SDIO_GetError(const SDIO_HandleTypeDef * hsdio)2082 uint32_t HAL_SDIO_GetError(const SDIO_HandleTypeDef *hsdio)
2083 {
2084 return hsdio->ErrorCode;
2085 }
2086
2087 /**
2088 * @}
2089 */
2090
2091 /** @addtogroup SDIO_Exported_Functions_Group6
2092 * @brief
2093 *
2094 @verbatim
2095 ==============================================================================
2096 ##### Peripheral IO interrupt #####
2097 ==============================================================================
2098 [..]
2099 This subsection provides a set functions allowing to enable/disable IO functions interrupt features
2100 on the SDIO card.
2101
2102 @endverbatim
2103 * @{
2104 */
2105 /**
2106 * @brief Enable SDIO IO interrupt.
2107 * @param hsdio: Pointer to SDIO handle
2108 * @param IOFunction: Specifies the SDIO IO function.
2109 * @retval HAL status
2110 */
HAL_SDIO_EnableIOFunctionInterrupt(SDIO_HandleTypeDef * hsdio,uint32_t IOFunction)2111 HAL_StatusTypeDef HAL_SDIO_EnableIOFunctionInterrupt(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
2112 {
2113 uint8_t intEn = 0U;
2114
2115 /* Check the parameters */
2116 assert_param(hsdio != NULL);
2117 assert_param(IS_SDIO_FUNCTION(IOFunction));
2118
2119 /* Check the SDIO peripheral handle parameter */
2120 if (hsdio == NULL)
2121 {
2122 return HAL_ERROR;
2123 }
2124
2125 if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR4, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &intEn) != HAL_OK)
2126 {
2127 return HAL_ERROR;
2128 }
2129
2130 /* if already enable , do not need enable again */
2131 if ((((intEn >> (uint32_t)IOFunction) & 0x01U) == 0x01U) && ((intEn & 0x01U) != 0U))
2132 {
2133 return HAL_OK;
2134 }
2135 else
2136 {
2137 intEn |= (1U << (uint32_t)IOFunction) | 0x01U;
2138 hsdio->IOInterruptNbr++;
2139 }
2140
2141 if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR4, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0,
2142 &intEn) != HAL_OK)
2143 {
2144 return HAL_ERROR;
2145 }
2146
2147 __HAL_SDIO_ENABLE_IT(hsdio, SDMMC_IT_SDIOIT);
2148
2149 /* Enable host SDIO interrupt operations */
2150 __SDMMC_OPERATION_ENABLE(hsdio->Instance);
2151
2152 return HAL_OK;
2153 }
2154
2155 /**
2156 * @brief Enable SDIO IO interrupt.
2157 * @param hsdio: Pointer to SDIO handle
2158 * @param IOFunction: Specifies the SDIO IO function.
2159 * @retval HAL status
2160 */
HAL_SDIO_DisableIOFunctionInterrupt(SDIO_HandleTypeDef * hsdio,uint32_t IOFunction)2161 HAL_StatusTypeDef HAL_SDIO_DisableIOFunctionInterrupt(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
2162 {
2163 uint8_t intEn = 0U;
2164
2165 /* Check the parameters */
2166 assert_param(hsdio != NULL);
2167 assert_param(IS_SDIO_FUNCTION(IOFunction));
2168
2169 /* Check the SDIO peripheral handle parameter */
2170 if (hsdio == NULL)
2171 {
2172 return HAL_ERROR;
2173 }
2174
2175 if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR4, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &intEn) != HAL_OK)
2176 {
2177 return HAL_ERROR;
2178 }
2179
2180 /* if already disable , do not need enable again */
2181 if (((intEn >> (uint32_t)IOFunction) & 0x01U) == 0x00U)
2182 {
2183 return HAL_OK;
2184 }
2185 else
2186 {
2187 /* disable the interrupt, don't disable the interrupt master here */
2188 intEn &= ~(1U << (uint32_t)IOFunction);
2189 }
2190
2191 if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR4, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0,
2192 &intEn) != HAL_OK)
2193 {
2194 return HAL_ERROR;
2195 }
2196
2197 if (hsdio->IOInterruptNbr > 1U)
2198 {
2199 hsdio->IOInterruptNbr--;
2200 }
2201 else
2202 {
2203 hsdio->IOInterruptNbr = 0U;
2204 __HAL_SDIO_DISABLE_IT(hsdio, SDMMC_IT_SDIOIT);
2205 }
2206 return HAL_OK;
2207 }
2208
2209 /**
2210 * @brief Enable SDIO IO Enable.
2211 * @param hsdio: Pointer to SDIO handle
2212 * @param IOFunction: Specifies the SDIO IO function.
2213 * @retval HAL status
2214 */
HAL_SDIO_EnableIOFunction(SDIO_HandleTypeDef * hsdio,uint32_t IOFunction)2215 HAL_StatusTypeDef HAL_SDIO_EnableIOFunction(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
2216 {
2217 uint8_t ioEn = 0U;
2218 uint8_t ioReady = 0U;
2219
2220 /* Check the parameters */
2221 assert_param(hsdio != NULL);
2222 assert_param(IS_SDIO_FUNCTION(IOFunction));
2223
2224 /* Check the SDIO peripheral handle parameter */
2225 if (hsdio == NULL)
2226 {
2227 return HAL_ERROR;
2228 }
2229
2230 if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR0_SD_BYTE2, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &ioEn) != HAL_OK)
2231 {
2232 return HAL_ERROR;
2233 }
2234
2235 /* if already enable , do not need to enable again */
2236 if (((ioEn >> (uint32_t)IOFunction) & 0x01U) == 0x01U)
2237 {
2238 return HAL_OK;
2239 }
2240 else
2241 {
2242 ioEn |= (1U << (uint32_t)IOFunction);
2243 }
2244
2245 if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR0_SD_BYTE2, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0, &ioEn) != HAL_OK)
2246 {
2247 return HAL_ERROR;
2248 }
2249
2250 if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR0_SD_BYTE3, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &ioReady) != HAL_OK)
2251 {
2252 return HAL_ERROR;
2253 }
2254 /* check if IO ready */
2255 if ((ioReady & (1U << (uint32_t)IOFunction)) != 0U)
2256 {
2257 return HAL_OK;
2258 }
2259
2260 return HAL_ERROR;
2261 }
2262
2263 /**
2264 * @brief Disable SDIO IO Enable.
2265 * @param hsdio: Pointer to SDIO handle
2266 * @param IOFunction: Specifies the SDIO IO function.
2267 * @retval HAL status
2268 */
HAL_SDIO_DisableIOFunction(SDIO_HandleTypeDef * hsdio,uint32_t IOFunction)2269 HAL_StatusTypeDef HAL_SDIO_DisableIOFunction(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
2270 {
2271 uint8_t ioEn = 0U;
2272
2273 /* Check the parameters */
2274 assert_param(hsdio != NULL);
2275 assert_param(IS_SDIO_FUNCTION(IOFunction));
2276
2277 /* Check the SDIO peripheral handle parameter */
2278 if (hsdio == NULL)
2279 {
2280 return HAL_ERROR;
2281 }
2282
2283 if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR0_SD_BYTE2, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &ioEn) != HAL_OK)
2284 {
2285 return HAL_ERROR;
2286 }
2287
2288 /* if already enable , do not need enable again */
2289 if (((ioEn >> (uint32_t)IOFunction) & 0x01U) == 0x00U)
2290 {
2291 return HAL_OK;
2292 }
2293 else
2294 {
2295 ioEn &= ~(1U << (uint32_t)IOFunction);
2296 }
2297
2298 if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR0_SD_BYTE2, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0, &ioEn) != HAL_OK)
2299 {
2300 return HAL_ERROR;
2301 }
2302
2303 return HAL_OK;
2304 }
2305
2306 /**
2307 * @brief Select SDIO IO Enable.
2308 * @param hsdio: Pointer to SDIO handle
2309 * @param IOFunction: Specifies the SDIO IO function.
2310 * @retval HAL status
2311 */
HAL_SDIO_SelectIOFunction(SDIO_HandleTypeDef * hsdio,uint32_t IOFunction)2312 HAL_StatusTypeDef HAL_SDIO_SelectIOFunction(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
2313 {
2314 /* Check the parameters */
2315 assert_param(hsdio != NULL);
2316 assert_param(IS_SDIO_FUNCTION(IOFunction));
2317
2318 /* Check the SDIO peripheral handle parameter */
2319 if (hsdio == NULL)
2320 {
2321 return HAL_ERROR;
2322 }
2323
2324 if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR12_SD_BYTE1, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0,
2325 (uint8_t *)&IOFunction) != HAL_OK)
2326 {
2327 return HAL_ERROR;
2328 }
2329
2330 return HAL_OK;
2331 }
2332
2333 /**
2334 * @brief Abort IO transfer.
2335 * @param hsdio: Pointer to SDIO handle
2336 * @param IOFunction IO number
2337 * @retval HAL status
2338 */
HAL_SDIO_AbortIOFunction(SDIO_HandleTypeDef * hsdio,uint32_t IOFunction)2339 HAL_StatusTypeDef HAL_SDIO_AbortIOFunction(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
2340 {
2341 /* Check the parameters */
2342 assert_param(hsdio != NULL);
2343 assert_param(IS_SDIO_FUNCTION(IOFunction));
2344
2345 /* Check the SDIO peripheral handle parameter */
2346 if (hsdio == NULL)
2347 {
2348 return HAL_ERROR;
2349 }
2350
2351 if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR4_SD_BYTE2, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0,
2352 (uint8_t *)&IOFunction) != HAL_OK)
2353 {
2354 return HAL_ERROR;
2355 }
2356
2357 return HAL_OK;
2358 }
2359
2360 /**
2361 * @brief Enable Assynchrone interrupt.
2362 * @param hsdio: Pointer to SDIO handle
2363 * @retval HAL status
2364 */
HAL_SDIO_EnableIOAsynInterrupt(SDIO_HandleTypeDef * hsdio)2365 HAL_StatusTypeDef HAL_SDIO_EnableIOAsynInterrupt(SDIO_HandleTypeDef *hsdio)
2366 {
2367 uint8_t enable_asyn_it = 0U;
2368
2369 /* Check the parameters */
2370 assert_param(hsdio != NULL);
2371
2372 /* Check the SDIO peripheral handle parameter */
2373 if (hsdio == NULL)
2374 {
2375 return HAL_ERROR;
2376 }
2377
2378 if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR20_SD_BYTE2, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &enable_asyn_it)
2379 != HAL_OK)
2380 {
2381 return HAL_ERROR;
2382 }
2383
2384 /* if already enable , do not need enable again */
2385 if ((enable_asyn_it & 0x02U) == 0x02U)
2386 {
2387 return HAL_OK;
2388 }
2389 else
2390 {
2391 enable_asyn_it |= 0x02U;
2392 }
2393
2394 if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR20_SD_BYTE2, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0,
2395 &enable_asyn_it) != HAL_OK)
2396 {
2397 return HAL_ERROR;
2398 }
2399
2400 return HAL_OK;
2401 }
2402
2403 /**
2404 * @brief Disable Assynchrone interrupt.
2405 * @param hsdio: Pointer to SDIO handle
2406 * @retval HAL status
2407 */
HAL_SDIO_DisableIOAsynInterrupt(SDIO_HandleTypeDef * hsdio)2408 HAL_StatusTypeDef HAL_SDIO_DisableIOAsynInterrupt(SDIO_HandleTypeDef *hsdio)
2409 {
2410 uint8_t enable_asyn_it = 0U;
2411
2412 /* Check the parameters */
2413 assert_param(hsdio != NULL);
2414
2415 /* Check the SDIO peripheral handle parameter */
2416 if (hsdio == NULL)
2417 {
2418 return HAL_ERROR;
2419 }
2420
2421 if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR20_SD_BYTE2, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &enable_asyn_it)
2422 != HAL_OK)
2423 {
2424 return HAL_ERROR;
2425 }
2426
2427 /* if already disable , do not need disable again */
2428 if ((enable_asyn_it & 0x02U) == 0x00U)
2429 {
2430 return HAL_OK;
2431 }
2432 else
2433 {
2434 enable_asyn_it &= (uint8_t) ~(0x02U);
2435 }
2436
2437 if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR20_SD_BYTE2, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0,
2438 &enable_asyn_it) != HAL_OK)
2439 {
2440 return HAL_ERROR;
2441 }
2442
2443 return HAL_OK;
2444 }
2445
2446 /**
2447 * @brief sdio set io IRQ handler.
2448 * @param hsdio Pointer to SDIO handle
2449 * @param IOFunction IO function io number.
2450 * @param Callback io IRQ handler.
2451 */
HAL_SDIO_RegisterIOFunctionCallback(SDIO_HandleTypeDef * hsdio,uint32_t IOFunction,HAL_SDIO_IOFunction_CallbackTypeDef pCallback)2452 HAL_StatusTypeDef HAL_SDIO_RegisterIOFunctionCallback(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction,
2453 HAL_SDIO_IOFunction_CallbackTypeDef pCallback)
2454 {
2455 /* Check the parameters */
2456 assert_param(hsdio != NULL);
2457 assert_param(IS_SDIO_FUNCTION(IOFunction));
2458
2459 /* Check the SDIO peripheral handle parameter */
2460 if (hsdio == NULL)
2461 {
2462 return HAL_ERROR;
2463 }
2464
2465 hsdio->SDIO_IOFunction_Callback[(uint32_t)IOFunction] = pCallback;
2466 hsdio->IOFunctionMask |= (1U << (uint8_t)IOFunction);
2467
2468 return HAL_OK;
2469 }
2470 /**
2471 * @}
2472 */
2473
2474 /**
2475 * @}
2476 */
2477
2478 /* Private function --------------------------------------------------------------------------------------------------*/
2479 /** @addtogroup SDIO_Private_Functions
2480 * @{
2481 */
2482 /**
2483 * @brief Initializes the SDIO device.
2484 * @param hsdio: Pointer to the SDIO handle
2485 * @retval HAL status
2486 */
SDIO_InitCard(SDIO_HandleTypeDef * hsdio)2487 static HAL_StatusTypeDef SDIO_InitCard(SDIO_HandleTypeDef *hsdio)
2488 {
2489 uint32_t errorstate;
2490 uint32_t timeout = 0U;
2491 uint16_t sdio_rca = 1U;
2492 uint32_t Resp4;
2493 uint32_t nbr_of_func;
2494
2495 /* Identify card operating voltage */
2496 errorstate = SDMMC_CmdGoIdleState(hsdio->Instance);
2497 if (errorstate != HAL_SDIO_ERROR_NONE)
2498 {
2499 return HAL_ERROR;
2500 }
2501
2502 /* Check the power State */
2503 if (SDMMC_GetPowerState(hsdio->Instance) == 0U)
2504 {
2505 return HAL_ERROR;
2506 }
2507
2508 /* Send CMD5 */
2509 errorstate = SDMMC_CmdSendOperationcondition(hsdio->Instance, 0U, &Resp4);
2510 if (errorstate != HAL_SDIO_ERROR_NONE)
2511 {
2512 return HAL_ERROR;
2513 }
2514
2515 nbr_of_func = ((Resp4 & 0x70000000U) >> 28U);
2516 /* Check if Nbr of function > 0 and OCR valid */
2517 if (nbr_of_func > 0U)
2518 {
2519 /* Send CMD5 with arg= S18R, WV*/
2520 if (SDMMC_CmdSendOperationcondition(hsdio->Instance, (SDIO_OCR_VDD_32_33 | SDIO_OCR_SDIO_S18R), &Resp4)
2521 != HAL_SDIO_ERROR_NONE)
2522 {
2523 return HAL_ERROR;
2524 }
2525 /* Check if IORDY = 1 and S18A = 1 */
2526 if ((((Resp4 & 0x80000000U) >> 31U) != 0U) && (((Resp4 & 0x1000000U) >> 24U) != 0U))
2527 {
2528 /* Send CMD11 to switch 1.8V mode */
2529 errorstate = SDMMC_CmdVoltageSwitch(hsdio->Instance);
2530 if (errorstate != HAL_SDIO_ERROR_NONE)
2531 {
2532 return HAL_ERROR;
2533 }
2534 }
2535 else
2536 {
2537 /* S18A is not supported */
2538 }
2539 }
2540
2541 /** Cmd3 is sent while response is SDMMC_ERROR_ILLEGAL_CMD, due to the partial init test done before
2542 * (sending cmd0 after the sequence cmd0/cmd3 is sent is considered illegal).
2543 */
2544 do
2545 {
2546 errorstate = SDMMC_CmdSetRelAdd(hsdio->Instance, &sdio_rca);
2547 timeout++;
2548 HAL_Delay(1);
2549 } while ((errorstate == SDMMC_ERROR_ILLEGAL_CMD) && (timeout != SDIO_TIMEOUT));
2550
2551 if ((timeout == SDIO_TIMEOUT) || (errorstate != HAL_SDIO_ERROR_NONE))
2552 {
2553 return HAL_ERROR;
2554 }
2555
2556 /* Select the Card ( Sending CMD7)*/
2557 errorstate = SDMMC_CmdSelDesel(hsdio->Instance, (uint32_t)(((uint32_t)sdio_rca) << 16U));
2558 if (errorstate != HAL_SDIO_ERROR_NONE)
2559 {
2560 return HAL_ERROR;
2561 }
2562
2563 return HAL_OK;
2564 }
2565
2566 /**
2567 * @brief Read 1 byte data.
2568 * @param hsdio: Pointer to SDIO handle
2569 * @param cmd_arg: formatted CMD52 structure
2570 * @param pData: pointer to write or read data
2571 * @retval HAL status
2572 */
SDIO_ReadDirect(SDIO_HandleTypeDef * hsdio,uint32_t addr,uint32_t raw,uint32_t function_nbr,uint8_t * pData)2573 static HAL_StatusTypeDef SDIO_ReadDirect(SDIO_HandleTypeDef *hsdio, uint32_t addr, uint32_t raw,
2574 uint32_t function_nbr, uint8_t *pData)
2575 {
2576 uint32_t errorstate;
2577 uint32_t cmd;
2578
2579 cmd = SDIO_READ << 31U;
2580 cmd |= function_nbr << 28U;
2581 cmd |= raw << 27U;
2582 cmd |= (addr & 0x1FFFFU) << 9U;
2583 errorstate = SDMMC_SDIO_CmdReadWriteDirect(hsdio->Instance, cmd, pData);
2584 if (errorstate != HAL_SDIO_ERROR_NONE)
2585 {
2586 hsdio->ErrorCode |= errorstate;
2587 /* Clear all the static flags */
2588 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
2589 hsdio->State = HAL_SDIO_STATE_READY;
2590 hsdio->Context = SDIO_CONTEXT_NONE;
2591 return HAL_ERROR;
2592 }
2593 __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
2594
2595 /* Clear all the static flags */
2596 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
2597
2598 return HAL_OK;
2599 }
2600
2601 /**
2602 * @brief Write 1 byte data.
2603 * @param hsdio: Pointer to SDIO handle
2604 * @param cmd_arg: formatted CMD52 structure
2605 * @param pData: pointer to write or read data
2606 * @retval HAL status
2607 */
SDIO_WriteDirect(SDIO_HandleTypeDef * hsdio,uint32_t addr,uint32_t raw,uint32_t function_nbr,uint8_t * pData)2608 static HAL_StatusTypeDef SDIO_WriteDirect(SDIO_HandleTypeDef *hsdio, uint32_t addr, uint32_t raw,
2609 uint32_t function_nbr, uint8_t *pData)
2610 {
2611 uint32_t errorstate;
2612 uint32_t cmd;
2613 uint8_t response;
2614
2615 cmd = SDIO_WRITE << 31U;
2616 cmd |= function_nbr << 28U;
2617 cmd |= raw << 27U;
2618 cmd |= (addr & 0x1FFFFU) << 9U;
2619 cmd |= ((uint32_t) * pData & 0x000000FFU);
2620 errorstate = SDMMC_SDIO_CmdReadWriteDirect(hsdio->Instance, cmd, &response);
2621
2622 if (errorstate != HAL_SDIO_ERROR_NONE)
2623 {
2624 hsdio->ErrorCode |= errorstate;
2625 /* Clear all the static flags */
2626 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
2627 hsdio->State = HAL_SDIO_STATE_READY;
2628 hsdio->Context = SDIO_CONTEXT_NONE;
2629 return HAL_ERROR;
2630 }
2631 __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
2632
2633 /* Clear all the static flags */
2634 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
2635
2636 return HAL_OK;
2637 }
2638
2639 /**
2640 * @brief Write multiple data with a single command.
2641 * @param hsdio: Pointer to SDIO handle
2642 * @param cmd_arg: formatted cmd53 structure
2643 * @param Size_byte: block size if CMD53 defined in HAL_SDIO_MODE_BLOCK
2644 * @param pData: pointer to write or read data
2645 * @retval HAL status
2646 */
SDIO_WriteExtended(SDIO_HandleTypeDef * hsdio,HAL_SDIO_ExtendedCmd_TypeDef * cmd_arg,uint8_t * pData,uint16_t Size_byte)2647 static HAL_StatusTypeDef SDIO_WriteExtended(SDIO_HandleTypeDef *hsdio, HAL_SDIO_ExtendedCmd_TypeDef *cmd_arg,
2648 uint8_t *pData, uint16_t Size_byte)
2649 {
2650 SDMMC_DataInitTypeDef config;
2651 uint32_t errorstate;
2652 uint32_t tickstart = HAL_GetTick();
2653 uint32_t regCount;
2654 uint8_t byteCount;
2655 uint32_t data;
2656 uint32_t dataremaining;
2657 uint32_t *u32tempbuff = (uint32_t *)(uint32_t)pData;
2658 SDMMC_TypeDef *SDMMCx;
2659 uint32_t cmd;
2660 uint32_t nbr_of_block;
2661
2662 hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
2663
2664 /* Compute how many blocks are to be send for pData of length data_size to be send */
2665 nbr_of_block = (((uint32_t)Size_byte & ~((uint32_t)hsdio->block_size & 1U))) >> __CLZ(__RBIT(hsdio->block_size));
2666
2667 /* Initialize data control register */
2668 if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
2669 {
2670 hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
2671 }
2672 else
2673 {
2674 hsdio->Instance->DCTRL = 0U;
2675 }
2676
2677 /* Configure the SDIO DPSM (Data Path State Machine) */
2678 config.DataTimeOut = SDMMC_DATATIMEOUT;
2679 if (cmd_arg->Block_Mode == HAL_SDIO_MODE_BLOCK)
2680 {
2681 config.DataLength = (uint32_t)(nbr_of_block * hsdio->block_size);
2682 config.DataBlockSize = SDIO_Convert_Block_Size(hsdio, hsdio->block_size);
2683 }
2684 else
2685 {
2686 config.DataLength = Size_byte;
2687 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
2688 }
2689
2690 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
2691 config.TransferMode = (cmd_arg->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDMMC_TRANSFER_MODE_BLOCK :
2692 SDMMC_TRANSFER_MODE_SDIO;
2693 config.DPSM = SDMMC_DPSM_DISABLE;
2694 (void)SDMMC_ConfigData(hsdio->Instance, &config);
2695 __SDMMC_CMDTRANS_ENABLE(hsdio->Instance);
2696
2697 hsdio->Context = (cmd_arg->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDIO_CONTEXT_WRITE_MULTIPLE_BLOCK :
2698 SDIO_CONTEXT_WRITE_SINGLE_BLOCK;
2699 cmd = SDIO_WRITE << 31U;
2700 cmd |= cmd_arg->IOFunctionNbr << 28U;
2701 cmd |= cmd_arg->Block_Mode << 27U;
2702 cmd |= cmd_arg->OpCode << 26U;
2703 cmd |= (cmd_arg->Reg_Addr & 0x1FFFFU) << 9U;
2704 cmd |= (((uint32_t)Size_byte) & 0x1FFU);
2705 errorstate = SDMMC_SDIO_CmdReadWriteExtended(hsdio->Instance, cmd);
2706 if (errorstate != HAL_SDIO_ERROR_NONE)
2707 {
2708 MODIFY_REG(hsdio->Instance->DCTRL, SDMMC_DCTRL_FIFORST, SDMMC_DCTRL_FIFORST);
2709 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
2710 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
2711 hsdio->ErrorCode |= errorstate;
2712 hsdio->State = HAL_SDIO_STATE_READY;
2713 hsdio->Context = SDIO_CONTEXT_NONE;
2714 return HAL_ERROR;
2715 }
2716
2717 SDMMCx = hsdio->Instance;
2718 dataremaining = config.DataLength;
2719 while (!__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT |
2720 SDMMC_FLAG_DATAEND))
2721 {
2722 if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= 32U))
2723 {
2724 for (regCount = 8U; regCount > 0U; regCount--)
2725 {
2726 SDMMCx->FIFO = *u32tempbuff;
2727 u32tempbuff++;
2728 }
2729 dataremaining -= 32U;
2730 }
2731 else if ((dataremaining < 32U) && (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXFIFOHE | SDMMC_FLAG_TXFIFOE)))
2732 {
2733 uint8_t *u8buff = (uint8_t *)u32tempbuff;
2734 while (dataremaining > 0U)
2735 {
2736 data = 0U;
2737 for (byteCount = 0U; (byteCount < 4U) && (dataremaining > 0U); byteCount++)
2738 {
2739 data |= ((uint32_t)(*u8buff) << (byteCount << 3U));
2740 u8buff++;
2741 dataremaining--;
2742 }
2743 SDMMCx->FIFO = data;
2744 }
2745 }
2746 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
2747 {
2748 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
2749 hsdio->ErrorCode |= HAL_SDIO_ERROR_TIMEOUT;
2750 hsdio->State = HAL_SDIO_STATE_READY;
2751 hsdio->Context = SDIO_CONTEXT_NONE;
2752 return HAL_TIMEOUT;
2753 }
2754 }
2755
2756 __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
2757 if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DTIMEOUT))
2758 {
2759 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
2760 hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_TIMEOUT;
2761 hsdio->State = HAL_SDIO_STATE_READY;
2762 hsdio->Context = SDIO_CONTEXT_NONE;
2763 return HAL_ERROR;
2764 }
2765 else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DCRCFAIL))
2766 {
2767 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
2768 hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_CRC_FAIL;
2769 hsdio->State = HAL_SDIO_STATE_READY;
2770 hsdio->Context = SDIO_CONTEXT_NONE;
2771 return HAL_ERROR;
2772 }
2773 else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXUNDERR))
2774 {
2775 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
2776 hsdio->ErrorCode |= HAL_SDIO_ERROR_TX_UNDERRUN;
2777 hsdio->State = HAL_SDIO_STATE_READY;
2778 hsdio->Context = SDIO_CONTEXT_NONE;
2779 return HAL_ERROR;
2780 }
2781 else if (hsdio->ErrorCode == SDMMC_ERROR_INVALID_PARAMETER)
2782 {
2783 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
2784 hsdio->State = HAL_SDIO_STATE_READY;
2785 hsdio->Context = SDIO_CONTEXT_NONE;
2786 return HAL_ERROR;
2787 }
2788 else
2789 {
2790 /* Nothing to do */
2791 }
2792
2793 __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
2794
2795 return HAL_OK;
2796 }
2797
2798 /**
2799 * @brief Allows to convert a block size in the according SDMMC value for configuring the SDMMC when doing a CMD53
2800 * @param hsdio: Pointer to the SDIO handle.
2801 * @param block_size: block size in bytes
2802 * @retval block size as DBLOCKSIZE[3:0] bits format
2803 */
SDIO_Convert_Block_Size(SDIO_HandleTypeDef * hsdio,uint32_t block_size)2804 static uint8_t SDIO_Convert_Block_Size(SDIO_HandleTypeDef *hsdio, uint32_t block_size)
2805 {
2806 UNUSED(hsdio);
2807
2808 uint8_t most_bit = (uint8_t)__CLZ(__RBIT(block_size));
2809 /*(1 << most_bit) - 1) is the mask used for blocksize*/
2810 if (((uint8_t)block_size & ((1U << most_bit) - 1U)) != 0U)
2811 {
2812 return (uint8_t)SDMMC_DATABLOCK_SIZE_4B;
2813 }
2814 return most_bit << SDMMC_DCTRL_DBLOCKSIZE_Pos;
2815 }
2816
2817 /*!
2818 * @brief SDIO card io pending interrupt handle function.
2819 * @note This function is used to handle the pending io interrupt.
2820 * To register a IO IRQ handler, Use HAL_SDIO_EnableIOInterrupt and HAL_SDIO_SetIOIRQHandler
2821 * @param hsdio: Pointer to SDIO handle
2822 * @retval HAL status
2823 */
SDIO_IOFunction_IRQHandler(SDIO_HandleTypeDef * hsdio)2824 static HAL_StatusTypeDef SDIO_IOFunction_IRQHandler(SDIO_HandleTypeDef *hsdio)
2825 {
2826 uint8_t count;
2827 uint8_t pendingInt;
2828
2829 if (hsdio->IOInterruptNbr == 1U)
2830 {
2831 if ((hsdio->SDIO_IOFunction_Callback[hsdio->IOFunctionMask - 1U]) != NULL)
2832 {
2833 (hsdio->SDIO_IOFunction_Callback[hsdio->IOFunctionMask - 1U])(hsdio, hsdio->IOFunctionMask - 1U);
2834 }
2835 }
2836 else if ((hsdio->IOInterruptNbr > 1U) && (hsdio->IOFunctionMask != 0U))
2837 {
2838 /* Get pending int firstly */
2839 if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR4_SD_BYTE1, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &pendingInt) !=
2840 HAL_OK)
2841 {
2842 return HAL_ERROR;
2843 }
2844
2845 if ((pendingInt != 0U) && (hsdio->IOFunctionMask != 0U))
2846 {
2847 for (count = 1; count <= SDIO_MAX_IO_NUMBER; count++)
2848 {
2849 if (((pendingInt & (1U << count)) != 0U) && (((1U << count) & hsdio->IOFunctionMask) != 0U))
2850 {
2851 if ((hsdio->SDIO_IOFunction_Callback[count - 1U]) != NULL)
2852 {
2853 (hsdio->SDIO_IOFunction_Callback[count - 1U])(hsdio, count);
2854 }
2855 }
2856 }
2857 }
2858 }
2859 else
2860 {
2861 /* Nothing to do */
2862 }
2863
2864 return HAL_OK;
2865 }
2866 /**
2867 * @}
2868 */
2869 #endif /* HAL_SDIO_MODULE_ENABLED */
2870 #endif /* SDMMC1 || SDMMC2 */
2871 /**
2872 * @}
2873 */
2874
2875 /**
2876 * @}
2877 */
2878