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