comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_mmc.c @ 160:e3ca52b8e7fa

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