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