source: S-port/trunk/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_mmc.c

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