STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
stm32h7xx_hal_mmc.c
Go to the documentation of this file.
1/**
2 ******************************************************************************
3 * @file stm32h7xx_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 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2017 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 @verbatim
25 ==============================================================================
26 ##### How to use this driver #####
27 ==============================================================================
28 [..]
29 This driver implements a high level communication layer for read and write from/to
30 this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
31 the user in HAL_MMC_MspInit() function (MSP layer).
32 Basically, the MSP layer configuration should be the same as we provide in the
33 examples.
34 You can easily tailor this configuration according to hardware resources.
35
36 [..]
37 This driver is a generic layered driver for SDMMC memories which uses the HAL
38 SDMMC driver functions to interface with MMC and eMMC cards devices.
39 It is used as follows:
40
41 (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
42 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
43 (##) SDMMC pins configuration for MMC card
44 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
45 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
46 and according to your pin assignment;
47 (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
48 and HAL_MMC_WriteBlocks_IT() APIs).
49 (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
50 (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
51 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
52 and __HAL_MMC_DISABLE_IT() inside the communication process.
53 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
54 and __HAL_MMC_CLEAR_IT()
55 (##) No general propose DMA Configuration is needed, an Internal DMA for SDMMC Peripheral are used.
56
57 (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
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 default 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 / (2 * ClockDiv)
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 by adjusting the "ClockDiv" field.
89 In transfer mode and according to the MMC Card standard, make sure that the
90 SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch.
91
92 (#) Select the corresponding MMC Card according to the address read with the step 2.
93
94 (#) Configure the MMC Card in wide bus mode: 4-bits data.
95 (#) Select the MMC Card partition using HAL_MMC_SwitchPartition()
96
97 *** MMC Card Read operation ***
98 ==============================
99 [..]
100 (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
101 This function support only 512-bytes block length (the block size should be
102 chosen as 512 bytes).
103 You can choose either one block read operation or multiple block read operation
104 by adjusting the "NumberOfBlocks" parameter.
105 After this, you have to ensure that the transfer is done correctly. The check is done
106 through HAL_MMC_GetCardState() function for MMC card state.
107
108 (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
109 This function support only 512-bytes block length (the block size should be
110 chosen as 512 bytes).
111 You can choose either one block read operation or multiple block read operation
112 by adjusting the "NumberOfBlocks" parameter.
113 After this, you have to ensure that the transfer is done correctly. The check is done
114 through HAL_MMC_GetCardState() function for MMC card state.
115 You could also check the DMA transfer process through the MMC Rx interrupt event.
116
117 (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
118 This function allows the read of 512 bytes blocks.
119 You can choose either one block read operation or multiple block read operation
120 by adjusting the "NumberOfBlocks" parameter.
121 After this, you have to ensure that the transfer is done correctly. The check is done
122 through HAL_MMC_GetCardState() function for MMC card state.
123 You could also check the IT transfer process through the MMC Rx interrupt event.
124
125 *** MMC Card Write operation ***
126 ===============================
127 [..]
128 (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
129 This function support only 512-bytes block length (the block size should be
130 chosen as 512 bytes).
131 You can choose either one block read operation or multiple block read operation
132 by adjusting the "NumberOfBlocks" parameter.
133 After this, you have to ensure that the transfer is done correctly. The check is done
134 through HAL_MMC_GetCardState() function for MMC card state.
135
136 (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
137 This function support only 512-bytes block length (the block size should be
138 chosen as 512 byte).
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 information ***
154 ===========================
155 [..]
156 (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
157 It returns useful information about the MMC card such as block size, card type,
158 block number ...
159
160 *** MMC card CSD register ***
161 ============================
162 [..]
163 (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
164 Some of the CSD parameters are useful for card initialization and identification.
165
166 *** MMC card CID register ***
167 ============================
168 [..]
169 (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
170 Some of the CID parameters are useful for card initialization and identification.
171
172 *** MMC Card Reply Protected Memory Block (RPMB) Key Programming operation ***
173 ==============================
174 [..]
175 (+) You can program the authentication key of RPMB area in polling mode by using function
176 HAL_MMC_RPMB_ProgramAuthenticationKey().
177 This function is only used once during the life of an MMC card.
178 After this, you have to ensure that the transfer is done correctly. The check is done
179 through HAL_MMC_GetRPMBError() function for operation state.
180 (+) You can program the authentication key of RPMB area in Interrupt mode by using function
181 HAL_MMC_RPMB_ProgramAuthenticationKey_IT().
182 This function is only used once during the life of an MMC card.
183 After this, you have to ensure that the transfer is done correctly. The check is done
184 through HAL_MMC_GetRPMBError() function for operation state.
185
186 *** MMC Card Reply Protected Memory Block (RPMB) write counter operation ***
187 ==============================
188 [..]
189 (+) You can get the write counter value of RPMB area in polling mode by using function
190 HAL_MMC_RPMB_GetWriteCounter().
191 (+) You can get the write counter value of RPMB area in Interrupt mode by using function
192 HAL_MMC_RPMB_GetWriteCounter_IT().
193
194 *** MMC Card Reply Protected Memory Block (RPMB) write operation ***
195 ==============================
196 [..]
197 (+) You can write to the RPMB area of MMC card in polling mode by using function
198 HAL_MMC_WriteBlocks().
199 This function supports the one, two, or thirty two blocks write operation
200 (with 512-bytes block length).
201 You can choose the number of blocks at the multiple block read operation by adjusting
202 the "NumberOfBlocks" parameter.
203 After this, you have to ensure that the transfer is done correctly. The check is done
204 through HAL_MMC_GetRPMBError() function for operation state.
205 (+) You can write to the RPMB area of MMC card in Interrupt mode by using function
206 HAL_MMC_WriteBlocks_IT().
207 This function supports the one, two, or thirty two blocks write operation
208 (with 512-bytes block length).
209 You can choose the number of blocks at the multiple block read operation by adjusting
210 the "NumberOfBlocks" parameter.
211 After this, you have to ensure that the transfer is done correctly. The check is done
212 through HAL_MMC_GetRPMBError() function for operation state.
213
214 *** MMC Card Reply Protected Memory Block (RPMB) read operation ***
215 ==============================
216 [..]
217 (+) You can read from the RPMB area of MMC card in polling mode by using function
218 HAL_MMC_RPMB_ReadBlocks().
219 The block size should be chosen as multiple of 512 bytes.
220 You can choose the number of blocks by adjusting the "NumberOfBlocks" parameter.
221 After this, you have to ensure that the transfer is done correctly. The check is done
222 through HAL_MMC_GetRPMBError() function for MMC card state.
223 (+) You can read from the RPMB area of MMC card in Interrupt mode by using function
224 HAL_MMC_RPMB_ReadBlocks_IT().
225 The block size should be chosen as multiple of 512 bytes.
226 You can choose the number of blocks by adjusting the "NumberOfBlocks" parameter.
227 After this, you have to ensure that the transfer is done correctly. The check is done
228 through HAL_MMC_GetRPMBError() function for MMC card state.
229
230 *** MMC HAL driver macros list ***
231 ==================================
232 [..]
233 Below the list of most used macros in MMC HAL driver.
234
235 (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
236 (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
237 (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
238 (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
239
240 [..]
241 (@) You can refer to the MMC HAL driver header file for more useful macros
242
243 *** Callback registration ***
244 =============================================
245 [..]
246 The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
247 allows the user to configure dynamically the driver callbacks.
248
249 Use Functions HAL_MMC_RegisterCallback() to register a user callback,
250 it allows to register following callbacks:
251 (+) TxCpltCallback : callback when a transmission transfer is completed.
252 (+) RxCpltCallback : callback when a reception transfer is completed.
253 (+) ErrorCallback : callback when error occurs.
254 (+) AbortCpltCallback : callback when abort is completed.
255 (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
256 (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
257 (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
258 (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
259 (+) MspInitCallback : MMC MspInit.
260 (+) MspDeInitCallback : MMC MspDeInit.
261 This function takes as parameters the HAL peripheral handle, the Callback ID
262 and a pointer to the user callback function.
263
264 Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default
265 weak (overridden) function. It allows to reset following callbacks:
266 (+) TxCpltCallback : callback when a transmission transfer is completed.
267 (+) RxCpltCallback : callback when a reception transfer is completed.
268 (+) ErrorCallback : callback when error occurs.
269 (+) AbortCpltCallback : callback when abort is completed.
270 (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
271 (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
272 (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
273 (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
274 (+) MspInitCallback : MMC MspInit.
275 (+) MspDeInitCallback : MMC MspDeInit.
276 This function) takes as parameters the HAL peripheral handle and the Callback ID.
277
278 By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
279 all callbacks are reset to the corresponding legacy weak (overridden) functions.
280 Exception done for MspInit and MspDeInit callbacks that are respectively
281 reset to the legacy weak (overridden) functions in the HAL_MMC_Init
282 and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
283 If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit
284 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
285
286 Callbacks can be registered/unregistered in READY state only.
287 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
288 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
289 during the Init/DeInit.
290 In that case first register the MspInit/MspDeInit user callbacks
291 using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit
292 or HAL_MMC_Init function.
293
294 When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
295 not defined, the callback registering feature is not available
296 and weak (overridden) callbacks are used.
297
298 @endverbatim
299 ******************************************************************************
300 */
301
302/* Includes ------------------------------------------------------------------*/
303#include "stm32h7xx_hal.h"
304
305/** @addtogroup STM32H7xx_HAL_Driver
306 * @{
307 */
308
309/** @defgroup MMC MMC
310 * @brief MMC HAL module driver
311 * @{
312 */
313
314#if defined (SDMMC1) || defined (SDMMC2)
315#ifdef HAL_MMC_MODULE_ENABLED
316
317/* Private typedef -----------------------------------------------------------*/
318/* Private define ------------------------------------------------------------*/
319/** @addtogroup MMC_Private_Defines
320 * @{
321 */
322#if defined (VDD_VALUE) && (VDD_VALUE <= 1950U)
323#define MMC_VOLTAGE_RANGE EMMC_LOW_VOLTAGE_RANGE
324
325#define MMC_EXT_CSD_PWR_CL_26_INDEX 201
326#define MMC_EXT_CSD_PWR_CL_52_INDEX 200
327#define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238
328
329#define MMC_EXT_CSD_PWR_CL_26_POS 8
330#define MMC_EXT_CSD_PWR_CL_52_POS 0
331#define MMC_EXT_CSD_PWR_CL_DDR_52_POS 16
332#else
333#define MMC_VOLTAGE_RANGE EMMC_HIGH_VOLTAGE_RANGE
334
335#define MMC_EXT_CSD_PWR_CL_26_INDEX 203
336#define MMC_EXT_CSD_PWR_CL_52_INDEX 202
337#define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239
338
339#define MMC_EXT_CSD_PWR_CL_26_POS 24
340#define MMC_EXT_CSD_PWR_CL_52_POS 16
341#define MMC_EXT_CSD_PWR_CL_DDR_52_POS 24
342#endif /* (VDD_VALUE) && (VDD_VALUE <= 1950U)*/
343
344#define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX 216
345#define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS 0
346#define MMC_EXT_CSD_S_A_TIMEOUT_INDEX 217
347#define MMC_EXT_CSD_S_A_TIMEOUT_POS 8
348
349/* Frequencies used in the driver for clock divider calculation */
350#define MMC_INIT_FREQ 400000U /* Initialization phase : 400 kHz max */
351#define MMC_HIGH_SPEED_FREQ 52000000U /* High speed phase : 52 MHz max */
352
353/* The Data elements' postitions in the frame Frame for RPMB area */
354#define MMC_RPMB_KEYMAC_POSITION 196U
355#define MMC_RPMB_DATA_POSITION 228U
356#define MMC_RPMB_NONCE_POSITION 484U
357#define MMC_RPMB_WRITE_COUNTER_POSITION 500U
358/**
359 * @}
360 */
361
362/* Private macro -------------------------------------------------------------*/
363/* Private variables ---------------------------------------------------------*/
364/* Private function prototypes -----------------------------------------------*/
365/* Private functions ---------------------------------------------------------*/
366/** @defgroup MMC_Private_Functions MMC Private Functions
367 * @{
368 */
369static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
370static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
371static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
372static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
373static void MMC_Write_IT(MMC_HandleTypeDef *hmmc);
374static void MMC_Read_IT(MMC_HandleTypeDef *hmmc);
375static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state);
376static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state);
377static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex,
378 uint32_t Timeout);
379static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed);
380
381/**
382 * @}
383 */
384/* Exported functions --------------------------------------------------------*/
385/** @addtogroup MMC_Exported_Functions
386 * @{
387 */
388
389/** @addtogroup MMC_Exported_Functions_Group1
390 * @brief Initialization and de-initialization functions
391 *
392@verbatim
393 ==============================================================================
394 ##### Initialization and de-initialization functions #####
395 ==============================================================================
396 [..]
397 This section provides functions allowing to initialize/de-initialize the MMC
398 card device to be ready for use.
399
400@endverbatim
401 * @{
402 */
403
404/**
405 * @brief Initializes the MMC according to the specified parameters in the
406 MMC_HandleTypeDef and create the associated handle.
407 * @param hmmc: Pointer to the MMC handle
408 * @retval HAL status
409 */
410HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
411{
412 /* Check the MMC handle allocation */
413 if (hmmc == NULL)
414 {
415 return HAL_ERROR;
416 }
417
418 /* Check the parameters */
419 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
420 assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
421 assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
422 assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
423 assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
424 assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv));
425
426 if (hmmc->State == HAL_MMC_STATE_RESET)
427 {
428 /* Allocate lock resource and initialize it */
429 hmmc->Lock = HAL_UNLOCKED;
430#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
431 /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
432 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
433 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
434 hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
435 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
436 hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuf0CpltCallback;
437 hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuf1CpltCallback;
438 hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuf0CpltCallback;
439 hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuf1CpltCallback;
440
441 if (hmmc->MspInitCallback == NULL)
442 {
443 hmmc->MspInitCallback = HAL_MMC_MspInit;
444 }
445
446 /* Init the low level hardware */
447 hmmc->MspInitCallback(hmmc);
448#else
449 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
450 HAL_MMC_MspInit(hmmc);
451#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
452 }
453
454 hmmc->State = HAL_MMC_STATE_BUSY;
455
456 /* Initialize the Card parameters */
457 if (HAL_MMC_InitCard(hmmc) == HAL_ERROR)
458 {
459 return HAL_ERROR;
460 }
461
462 /* Initialize the error code */
463 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
464
465 /* Initialize the MMC operation */
466 hmmc->Context = MMC_CONTEXT_NONE;
467
468 /* Initialize the MMC state */
469 hmmc->State = HAL_MMC_STATE_READY;
470
471 /* Configure bus width */
472 if (hmmc->Init.BusWide != SDMMC_BUS_WIDE_1B)
473 {
474 if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK)
475 {
476 return HAL_ERROR;
477 }
478 }
479
480 return HAL_OK;
481}
482
483/**
484 * @brief Initializes the MMC Card.
485 * @param hmmc: Pointer to MMC handle
486 * @note This function initializes the MMC card. It could be used when a card
487 re-initialization is needed.
488 * @retval HAL status
489 */
490HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
491{
492 uint32_t errorstate;
493 MMC_InitTypeDef Init = {0U};
494 uint32_t sdmmc_clk;
495
496 /* Default SDMMC peripheral configuration for MMC card initialization */
497 Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
498 Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
499 Init.BusWide = SDMMC_BUS_WIDE_1B;
500 Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
501
502 /* Init Clock should be less or equal to 400Khz*/
504 if (sdmmc_clk == 0U)
505 {
506 hmmc->State = HAL_MMC_STATE_READY;
507 hmmc->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER;
508 return HAL_ERROR;
509 }
510 if (sdmmc_clk <= MMC_INIT_FREQ)
511 {
512 Init.ClockDiv = 0U;
513 }
514 else
515 {
516 Init.ClockDiv = (sdmmc_clk / (2U * MMC_INIT_FREQ)) + 1U;
517 }
518
519#if (USE_SD_TRANSCEIVER != 0U)
520 Init.TranceiverPresent = SDMMC_TRANSCEIVER_NOT_PRESENT;
521#endif /* USE_SD_TRANSCEIVER */
522
523 /* Initialize SDMMC peripheral interface with default configuration */
524 (void)SDMMC_Init(hmmc->Instance, Init);
525
526 /* Set Power State to ON */
527 (void)SDMMC_PowerState_ON(hmmc->Instance);
528
529 /* wait 74 Cycles: required power up waiting time before starting
530 the MMC initialization sequence */
531 if (Init.ClockDiv != 0U)
532 {
533 sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv);
534 }
535
536 if (sdmmc_clk != 0U)
537 {
538 HAL_Delay(1U + (74U * 1000U / (sdmmc_clk)));
539 }
540
541 /* Identify card operating voltage */
542 errorstate = MMC_PowerON(hmmc);
543 if (errorstate != HAL_MMC_ERROR_NONE)
544 {
545 hmmc->State = HAL_MMC_STATE_READY;
546 hmmc->ErrorCode |= errorstate;
547 return HAL_ERROR;
548 }
549
550 /* Card initialization */
551 errorstate = MMC_InitCard(hmmc);
552 if (errorstate != HAL_MMC_ERROR_NONE)
553 {
554 hmmc->State = HAL_MMC_STATE_READY;
555 hmmc->ErrorCode |= errorstate;
556 return HAL_ERROR;
557 }
558
559 /* Set Block Size for Card */
560 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
561 if (errorstate != HAL_MMC_ERROR_NONE)
562 {
563 /* Clear all the static flags */
564 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
565 hmmc->ErrorCode |= errorstate;
566 hmmc->State = HAL_MMC_STATE_READY;
567 return HAL_ERROR;
568 }
569
570 return HAL_OK;
571}
572
573/**
574 * @brief De-Initializes the MMC card.
575 * @param hmmc: Pointer to MMC handle
576 * @retval HAL status
577 */
578HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
579{
580 /* Check the MMC handle allocation */
581 if (hmmc == NULL)
582 {
583 return HAL_ERROR;
584 }
585
586 /* Check the parameters */
587 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
588
589 hmmc->State = HAL_MMC_STATE_BUSY;
590
591 /* Set MMC power state to off */
592 MMC_PowerOFF(hmmc);
593
594#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
595 if (hmmc->MspDeInitCallback == NULL)
596 {
597 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
598 }
599
600 /* DeInit the low level hardware */
601 hmmc->MspDeInitCallback(hmmc);
602#else
603 /* De-Initialize the MSP layer */
604 HAL_MMC_MspDeInit(hmmc);
605#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
606
607 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
608 hmmc->State = HAL_MMC_STATE_RESET;
609
610 return HAL_OK;
611}
612
613/**
614 * @brief Initializes the MMC MSP.
615 * @param hmmc: Pointer to MMC handle
616 * @retval None
617 */
618__weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
619{
620 /* Prevent unused argument(s) compilation warning */
621 UNUSED(hmmc);
622
623 /* NOTE : This function Should not be modified, when the callback is needed,
624 the HAL_MMC_MspInit could be implemented in the user file
625 */
626}
627
628/**
629 * @brief De-Initialize MMC MSP.
630 * @param hmmc: Pointer to MMC handle
631 * @retval None
632 */
633__weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
634{
635 /* Prevent unused argument(s) compilation warning */
636 UNUSED(hmmc);
637
638 /* NOTE : This function Should not be modified, when the callback is needed,
639 the HAL_MMC_MspDeInit could be implemented in the user file
640 */
641}
642
643/**
644 * @}
645 */
646
647/** @addtogroup MMC_Exported_Functions_Group2
648 * @brief Data transfer functions
649 *
650@verbatim
651 ==============================================================================
652 ##### IO operation functions #####
653 ==============================================================================
654 [..]
655 This subsection provides a set of functions allowing to manage the data
656 transfer from/to MMC card.
657
658@endverbatim
659 * @{
660 */
661
662/**
663 * @brief Reads block(s) from a specified address in a card. The Data transfer
664 * is managed by polling mode.
665 * @note This API should be followed by a check on the card state through
666 * HAL_MMC_GetCardState().
667 * @param hmmc: Pointer to MMC handle
668 * @param pData: pointer to the buffer that will contain the received data
669 * @param BlockAdd: Block Address from where data is to be read
670 * @param NumberOfBlocks: Number of MMC blocks to read
671 * @param Timeout: Specify timeout value
672 * @retval HAL status
673 */
674HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
675 uint32_t NumberOfBlocks,
676 uint32_t Timeout)
677{
678 SDMMC_DataInitTypeDef config;
679 uint32_t errorstate;
680 uint32_t tickstart = HAL_GetTick();
681 uint32_t count;
682 uint32_t data;
683 uint32_t dataremaining;
684 uint32_t add = BlockAdd;
685 uint8_t *tempbuff = pData;
686
687 if (NULL == pData)
688 {
689 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
690 return HAL_ERROR;
691 }
692
693 if (hmmc->State == HAL_MMC_STATE_READY)
694 {
695 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
696
697 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
698 {
699 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
700 return HAL_ERROR;
701 }
702
703 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
704 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS)
705 & 0x000000FFU) != 0x0U)
706 {
707 if ((NumberOfBlocks % 8U) != 0U)
708 {
709 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
710 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
711 return HAL_ERROR;
712 }
713
714 if ((BlockAdd % 8U) != 0U)
715 {
716 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
717 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
718 return HAL_ERROR;
719 }
720 }
721
722 hmmc->State = HAL_MMC_STATE_BUSY;
723
724 /* Initialize data control register */
725 hmmc->Instance->DCTRL = 0U;
726
727 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
728 {
729 add *= MMC_BLOCKSIZE;
730 }
731
732 /* Configure the MMC DPSM (Data Path State Machine) */
733 config.DataTimeOut = SDMMC_DATATIMEOUT;
734 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
735 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
736 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
737 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
738 config.DPSM = SDMMC_DPSM_DISABLE;
739 (void)SDMMC_ConfigData(hmmc->Instance, &config);
740 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
741
742 /* Read block(s) in polling mode */
743 if (NumberOfBlocks > 1U)
744 {
745 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
746
747 /* Read Multi Block command */
748 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
749 }
750 else
751 {
752 hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
753
754 /* Read Single Block command */
755 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
756 }
757 if (errorstate != HAL_MMC_ERROR_NONE)
758 {
759 /* Clear all the static flags */
760 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
761 hmmc->ErrorCode |= errorstate;
762 hmmc->State = HAL_MMC_STATE_READY;
763 return HAL_ERROR;
764 }
765
766 /* Poll on SDMMC flags */
767 dataremaining = config.DataLength;
768 while (!__HAL_MMC_GET_FLAG(hmmc,
769 SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
770 {
771 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
772 {
773 /* Read data from SDMMC Rx FIFO */
774 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
775 {
776 data = SDMMC_ReadFIFO(hmmc->Instance);
777 *tempbuff = (uint8_t)(data & 0xFFU);
778 tempbuff++;
779 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
780 tempbuff++;
781 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
782 tempbuff++;
783 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
784 tempbuff++;
785 }
786 dataremaining -= SDMMC_FIFO_SIZE;
787 }
788
789 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
790 {
791 /* Clear all the static flags */
792 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
793 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
794 hmmc->State = HAL_MMC_STATE_READY;
795 return HAL_TIMEOUT;
796 }
797 }
798 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
799
800 /* Send stop transmission command in case of multiblock read */
801 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
802 {
803 /* Send stop transmission command */
804 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
805 if (errorstate != HAL_MMC_ERROR_NONE)
806 {
807 /* Clear all the static flags */
808 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
809 hmmc->ErrorCode |= errorstate;
810 hmmc->State = HAL_MMC_STATE_READY;
811 return HAL_ERROR;
812 }
813 }
814
815 /* Get error state */
816 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
817 {
818 /* Clear all the static flags */
819 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
820 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
821 hmmc->State = HAL_MMC_STATE_READY;
822 return HAL_ERROR;
823 }
824 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
825 {
826 /* Clear all the static flags */
827 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
828 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
829 hmmc->State = HAL_MMC_STATE_READY;
830 return HAL_ERROR;
831 }
832 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
833 {
834 /* Clear all the static flags */
835 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
836 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
837 hmmc->State = HAL_MMC_STATE_READY;
838 return HAL_ERROR;
839 }
840 else
841 {
842 /* Nothing to do */
843 }
844
845 /* Clear all the static flags */
846 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
847
848 hmmc->State = HAL_MMC_STATE_READY;
849
850 return HAL_OK;
851 }
852 else
853 {
854 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
855 return HAL_ERROR;
856 }
857}
858
859/**
860 * @brief Allows to write block(s) to a specified address in a card. The Data
861 * transfer is managed by polling mode.
862 * @note This API should be followed by a check on the card state through
863 * HAL_MMC_GetCardState().
864 * @param hmmc: Pointer to MMC handle
865 * @param pData: pointer to the buffer that will contain the data to transmit
866 * @param BlockAdd: Block Address where data will be written
867 * @param NumberOfBlocks: Number of MMC blocks to write
868 * @param Timeout: Specify timeout value
869 * @retval HAL status
870 */
871HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint32_t BlockAdd,
872 uint32_t NumberOfBlocks, uint32_t Timeout)
873{
874 SDMMC_DataInitTypeDef config;
875 uint32_t errorstate;
876 uint32_t tickstart = HAL_GetTick();
877 uint32_t count;
878 uint32_t data;
879 uint32_t dataremaining;
880 uint32_t add = BlockAdd;
881 const uint8_t *tempbuff = pData;
882
883 if (NULL == pData)
884 {
885 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
886 return HAL_ERROR;
887 }
888
889 if (hmmc->State == HAL_MMC_STATE_READY)
890 {
891 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
892
893 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
894 {
895 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
896 return HAL_ERROR;
897 }
898
899 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
900 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
901 {
902 if ((NumberOfBlocks % 8U) != 0U)
903 {
904 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
905 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
906 return HAL_ERROR;
907 }
908
909 if ((BlockAdd % 8U) != 0U)
910 {
911 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
912 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
913 return HAL_ERROR;
914 }
915 }
916
917 hmmc->State = HAL_MMC_STATE_BUSY;
918
919 /* Initialize data control register */
920 hmmc->Instance->DCTRL = 0U;
921
922 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
923 {
924 add *= MMC_BLOCKSIZE;
925 }
926
927 /* Configure the MMC DPSM (Data Path State Machine) */
928 config.DataTimeOut = SDMMC_DATATIMEOUT;
929 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
930 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
931 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
932 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
933 config.DPSM = SDMMC_DPSM_DISABLE;
934 (void)SDMMC_ConfigData(hmmc->Instance, &config);
935 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
936
937 /* Write Blocks in Polling mode */
938 if (NumberOfBlocks > 1U)
939 {
940 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
941
942 /* Write Multi Block command */
943 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
944 }
945 else
946 {
947 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
948
949 /* Write Single Block command */
950 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
951 }
952 if (errorstate != HAL_MMC_ERROR_NONE)
953 {
954 /* Clear all the static flags */
955 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
956 hmmc->ErrorCode |= errorstate;
957 hmmc->State = HAL_MMC_STATE_READY;
958 return HAL_ERROR;
959 }
960
961 /* Write block(s) in polling mode */
962 dataremaining = config.DataLength;
963 while (!__HAL_MMC_GET_FLAG(hmmc,
964 SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
965 {
966 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
967 {
968 /* Write data to SDMMC Tx FIFO */
969 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
970 {
971 data = (uint32_t)(*tempbuff);
972 tempbuff++;
973 data |= ((uint32_t)(*tempbuff) << 8U);
974 tempbuff++;
975 data |= ((uint32_t)(*tempbuff) << 16U);
976 tempbuff++;
977 data |= ((uint32_t)(*tempbuff) << 24U);
978 tempbuff++;
979 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
980 }
981 dataremaining -= SDMMC_FIFO_SIZE;
982 }
983
984 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
985 {
986 /* Clear all the static flags */
987 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
988 hmmc->ErrorCode |= errorstate;
989 hmmc->State = HAL_MMC_STATE_READY;
990 return HAL_TIMEOUT;
991 }
992 }
993 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
994
995 /* Send stop transmission command in case of multiblock write */
996 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
997 {
998 /* Send stop transmission command */
999 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1000 if (errorstate != HAL_MMC_ERROR_NONE)
1001 {
1002 /* Clear all the static flags */
1003 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1004 hmmc->ErrorCode |= errorstate;
1005 hmmc->State = HAL_MMC_STATE_READY;
1006 return HAL_ERROR;
1007 }
1008 }
1009
1010 /* Get error state */
1011 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
1012 {
1013 /* Clear all the static flags */
1014 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1015 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1016 hmmc->State = HAL_MMC_STATE_READY;
1017 return HAL_ERROR;
1018 }
1019 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
1020 {
1021 /* Clear all the static flags */
1022 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1023 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1024 hmmc->State = HAL_MMC_STATE_READY;
1025 return HAL_ERROR;
1026 }
1027 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
1028 {
1029 /* Clear all the static flags */
1030 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1031 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1032 hmmc->State = HAL_MMC_STATE_READY;
1033 return HAL_ERROR;
1034 }
1035 else
1036 {
1037 /* Nothing to do */
1038 }
1039
1040 /* Clear all the static flags */
1041 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1042
1043 hmmc->State = HAL_MMC_STATE_READY;
1044
1045 return HAL_OK;
1046 }
1047 else
1048 {
1049 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
1050 return HAL_ERROR;
1051 }
1052}
1053
1054/**
1055 * @brief Reads block(s) from a specified address in a card. The Data transfer
1056 * is managed in interrupt mode.
1057 * @note This API should be followed by a check on the card state through
1058 * HAL_MMC_GetCardState().
1059 * @note You could also check the IT transfer process through the MMC Rx
1060 * interrupt event.
1061 * @param hmmc: Pointer to MMC handle
1062 * @param pData: Pointer to the buffer that will contain the received data
1063 * @param BlockAdd: Block Address from where data is to be read
1064 * @param NumberOfBlocks: Number of blocks to read.
1065 * @retval HAL status
1066 */
1067HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
1068 uint32_t NumberOfBlocks)
1069{
1070 SDMMC_DataInitTypeDef config;
1071 uint32_t errorstate;
1072 uint32_t add = BlockAdd;
1073
1074 if (NULL == pData)
1075 {
1076 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1077 return HAL_ERROR;
1078 }
1079
1080 if (hmmc->State == HAL_MMC_STATE_READY)
1081 {
1082 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1083
1084 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1085 {
1086 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1087 return HAL_ERROR;
1088 }
1089
1090 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1091 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1092 {
1093 if ((NumberOfBlocks % 8U) != 0U)
1094 {
1095 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1096 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1097 return HAL_ERROR;
1098 }
1099
1100 if ((BlockAdd % 8U) != 0U)
1101 {
1102 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1103 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1104 return HAL_ERROR;
1105 }
1106 }
1107
1108 hmmc->State = HAL_MMC_STATE_BUSY;
1109
1110 /* Initialize data control register */
1111 hmmc->Instance->DCTRL = 0U;
1112
1113 hmmc->pRxBuffPtr = pData;
1114 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1115
1116 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1117 {
1118 add *= MMC_BLOCKSIZE;
1119 }
1120
1121 /* Configure the MMC DPSM (Data Path State Machine) */
1122 config.DataTimeOut = SDMMC_DATATIMEOUT;
1123 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1124 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1125 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
1126 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1127 config.DPSM = SDMMC_DPSM_DISABLE;
1128 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1129 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1130
1131 /* Read Blocks in IT mode */
1132 if (NumberOfBlocks > 1U)
1133 {
1134 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1135
1136 /* Read Multi Block command */
1137 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1138 }
1139 else
1140 {
1141 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
1142
1143 /* Read Single Block command */
1144 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1145 }
1146
1147 if (errorstate != HAL_MMC_ERROR_NONE)
1148 {
1149 /* Clear all the static flags */
1150 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1151 hmmc->ErrorCode |= errorstate;
1152 hmmc->State = HAL_MMC_STATE_READY;
1153 return HAL_ERROR;
1154 }
1155
1156 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND |
1157 SDMMC_FLAG_RXFIFOHF));
1158
1159 return HAL_OK;
1160 }
1161 else
1162 {
1163 return HAL_BUSY;
1164 }
1165}
1166
1167/**
1168 * @brief Writes block(s) to a specified address in a card. The Data transfer
1169 * is managed in interrupt mode.
1170 * @note This API should be followed by a check on the card state through
1171 * HAL_MMC_GetCardState().
1172 * @note You could also check the IT transfer process through the MMC Tx
1173 * interrupt event.
1174 * @param hmmc: Pointer to MMC handle
1175 * @param pData: Pointer to the buffer that will contain the data to transmit
1176 * @param BlockAdd: Block Address where data will be written
1177 * @param NumberOfBlocks: Number of blocks to write
1178 * @retval HAL status
1179 */
1180HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, const uint8_t *pData,
1181 uint32_t BlockAdd, uint32_t NumberOfBlocks)
1182{
1183 SDMMC_DataInitTypeDef config;
1184 uint32_t errorstate;
1185 uint32_t add = BlockAdd;
1186
1187 if (NULL == pData)
1188 {
1189 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1190 return HAL_ERROR;
1191 }
1192
1193 if (hmmc->State == HAL_MMC_STATE_READY)
1194 {
1195 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1196
1197 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1198 {
1199 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1200 return HAL_ERROR;
1201 }
1202
1203 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1204 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1205 {
1206 if ((NumberOfBlocks % 8U) != 0U)
1207 {
1208 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1209 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1210 return HAL_ERROR;
1211 }
1212
1213 if ((BlockAdd % 8U) != 0U)
1214 {
1215 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1216 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1217 return HAL_ERROR;
1218 }
1219 }
1220
1221 hmmc->State = HAL_MMC_STATE_BUSY;
1222
1223 /* Initialize data control register */
1224 hmmc->Instance->DCTRL = 0U;
1225
1226 hmmc->pTxBuffPtr = pData;
1227 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1228
1229 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1230 {
1231 add *= MMC_BLOCKSIZE;
1232 }
1233
1234 /* Configure the MMC DPSM (Data Path State Machine) */
1235 config.DataTimeOut = SDMMC_DATATIMEOUT;
1236 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1237 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1238 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1239 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1240 config.DPSM = SDMMC_DPSM_DISABLE;
1241 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1242
1243 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1244
1245 /* Write Blocks in Polling mode */
1246 if (NumberOfBlocks > 1U)
1247 {
1248 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1249
1250 /* Write Multi Block command */
1251 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1252 }
1253 else
1254 {
1255 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1256
1257 /* Write Single Block command */
1258 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1259 }
1260 if (errorstate != HAL_MMC_ERROR_NONE)
1261 {
1262 /* Clear all the static flags */
1263 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1264 hmmc->ErrorCode |= errorstate;
1265 hmmc->State = HAL_MMC_STATE_READY;
1266 return HAL_ERROR;
1267 }
1268
1269 /* Enable transfer interrupts */
1270 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND |
1271 SDMMC_FLAG_TXFIFOHE));
1272
1273 return HAL_OK;
1274 }
1275 else
1276 {
1277 return HAL_BUSY;
1278 }
1279}
1280
1281/**
1282 * @brief Reads block(s) from a specified address in a card. The Data transfer
1283 * is managed by DMA mode.
1284 * @note This API should be followed by a check on the card state through
1285 * HAL_MMC_GetCardState().
1286 * @note You could also check the DMA transfer process through the MMC Rx
1287 * interrupt event.
1288 * @param hmmc: Pointer MMC handle
1289 * @param pData: Pointer to the buffer that will contain the received data
1290 * @param BlockAdd: Block Address from where data is to be read
1291 * @param NumberOfBlocks: Number of blocks to read.
1292 * @retval HAL status
1293 */
1294HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
1295 uint32_t NumberOfBlocks)
1296{
1297 SDMMC_DataInitTypeDef config;
1298 uint32_t errorstate;
1299 uint32_t add = BlockAdd;
1300
1301 if (NULL == pData)
1302 {
1303 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1304 return HAL_ERROR;
1305 }
1306
1307 if (hmmc->State == HAL_MMC_STATE_READY)
1308 {
1309 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1310
1311 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1312 {
1313 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1314 return HAL_ERROR;
1315 }
1316
1317 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1318 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1319 {
1320 if ((NumberOfBlocks % 8U) != 0U)
1321 {
1322 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1323 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1324 return HAL_ERROR;
1325 }
1326
1327 if ((BlockAdd % 8U) != 0U)
1328 {
1329 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1330 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1331 return HAL_ERROR;
1332 }
1333 }
1334
1335 hmmc->State = HAL_MMC_STATE_BUSY;
1336
1337 /* Initialize data control register */
1338 hmmc->Instance->DCTRL = 0U;
1339
1340 hmmc->pRxBuffPtr = pData;
1341 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1342
1343 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1344 {
1345 add *= MMC_BLOCKSIZE;
1346 }
1347
1348 /* Configure the MMC DPSM (Data Path State Machine) */
1349 config.DataTimeOut = SDMMC_DATATIMEOUT;
1350 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1351 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1352 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
1353 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1354 config.DPSM = SDMMC_DPSM_DISABLE;
1355 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1356
1357 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1358 hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1359 hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1360
1361 /* Read Blocks in DMA mode */
1362 if (NumberOfBlocks > 1U)
1363 {
1364 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1365
1366 /* Read Multi Block command */
1367 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1368 }
1369 else
1370 {
1371 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1372
1373 /* Read Single Block command */
1374 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1375 }
1376 if (errorstate != HAL_MMC_ERROR_NONE)
1377 {
1378 /* Clear all the static flags */
1379 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1380 hmmc->ErrorCode = errorstate;
1381 hmmc->State = HAL_MMC_STATE_READY;
1382 return HAL_ERROR;
1383 }
1384
1385 /* Enable transfer interrupts */
1386 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1387
1388 return HAL_OK;
1389 }
1390 else
1391 {
1392 return HAL_BUSY;
1393 }
1394}
1395
1396/**
1397 * @brief Writes block(s) to a specified address in a card. The Data transfer
1398 * is managed by DMA mode.
1399 * @note This API should be followed by a check on the card state through
1400 * HAL_MMC_GetCardState().
1401 * @note You could also check the DMA transfer process through the MMC Tx
1402 * interrupt event.
1403 * @param hmmc: Pointer to MMC handle
1404 * @param pData: Pointer to the buffer that will contain the data to transmit
1405 * @param BlockAdd: Block Address where data will be written
1406 * @param NumberOfBlocks: Number of blocks to write
1407 * @retval HAL status
1408 */
1409HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, const uint8_t *pData,
1410 uint32_t BlockAdd, uint32_t NumberOfBlocks)
1411{
1412 SDMMC_DataInitTypeDef config;
1413 uint32_t errorstate;
1414 uint32_t add = BlockAdd;
1415
1416 if (NULL == pData)
1417 {
1418 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1419 return HAL_ERROR;
1420 }
1421
1422 if (hmmc->State == HAL_MMC_STATE_READY)
1423 {
1424 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1425
1426 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1427 {
1428 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1429 return HAL_ERROR;
1430 }
1431
1432 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1433 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1434 {
1435 if ((NumberOfBlocks % 8U) != 0U)
1436 {
1437 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1438 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1439 return HAL_ERROR;
1440 }
1441
1442 if ((BlockAdd % 8U) != 0U)
1443 {
1444 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1445 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1446 return HAL_ERROR;
1447 }
1448 }
1449
1450 hmmc->State = HAL_MMC_STATE_BUSY;
1451
1452 /* Initialize data control register */
1453 hmmc->Instance->DCTRL = 0U;
1454
1455 hmmc->pTxBuffPtr = pData;
1456 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1457
1458 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1459 {
1460 add *= MMC_BLOCKSIZE;
1461 }
1462
1463 /* Configure the MMC DPSM (Data Path State Machine) */
1464 config.DataTimeOut = SDMMC_DATATIMEOUT;
1465 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1466 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1467 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1468 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1469 config.DPSM = SDMMC_DPSM_DISABLE;
1470 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1471
1472 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1473
1474 hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1475 hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1476
1477 /* Write Blocks in Polling mode */
1478 if (NumberOfBlocks > 1U)
1479 {
1480 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1481
1482 /* Write Multi Block command */
1483 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1484 }
1485 else
1486 {
1487 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1488
1489 /* Write Single Block command */
1490 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1491 }
1492 if (errorstate != HAL_MMC_ERROR_NONE)
1493 {
1494 /* Clear all the static flags */
1495 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1496 hmmc->ErrorCode |= errorstate;
1497 hmmc->State = HAL_MMC_STATE_READY;
1498 return HAL_ERROR;
1499 }
1500
1501 /* Enable transfer interrupts */
1502 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1503
1504 return HAL_OK;
1505 }
1506 else
1507 {
1508 return HAL_BUSY;
1509 }
1510}
1511
1512/**
1513 * @brief Erases the specified memory area of the given MMC card.
1514 * @note This API should be followed by a check on the card state through
1515 * HAL_MMC_GetCardState().
1516 * @param hmmc: Pointer to MMC handle
1517 * @param BlockStartAdd: Start Block address
1518 * @param BlockEndAdd: End Block address
1519 * @retval HAL status
1520 */
1521HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1522{
1523 uint32_t errorstate;
1524 uint32_t start_add = BlockStartAdd;
1525 uint32_t end_add = BlockEndAdd;
1526
1527 if (hmmc->State == HAL_MMC_STATE_READY)
1528 {
1529 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1530
1531 if (end_add < start_add)
1532 {
1533 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1534 return HAL_ERROR;
1535 }
1536
1537 if (end_add > (hmmc->MmcCard.LogBlockNbr))
1538 {
1539 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1540 return HAL_ERROR;
1541 }
1542
1543 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1544 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS)
1545 & 0x000000FFU) != 0x0U)
1546 {
1547 if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U))
1548 {
1549 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1550 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1551 return HAL_ERROR;
1552 }
1553 }
1554
1555 hmmc->State = HAL_MMC_STATE_BUSY;
1556
1557 /* Check if the card command class supports erase command */
1558 if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
1559 {
1560 /* Clear all the static flags */
1561 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1562 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1563 hmmc->State = HAL_MMC_STATE_READY;
1564 return HAL_ERROR;
1565 }
1566
1567 if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1568 {
1569 /* Clear all the static flags */
1570 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1571 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1572 hmmc->State = HAL_MMC_STATE_READY;
1573 return HAL_ERROR;
1574 }
1575
1576 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1577 {
1578 start_add *= MMC_BLOCKSIZE;
1579 end_add *= MMC_BLOCKSIZE;
1580 }
1581
1582 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
1583 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
1584 if (errorstate != HAL_MMC_ERROR_NONE)
1585 {
1586 /* Clear all the static flags */
1587 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1588 hmmc->ErrorCode |= errorstate;
1589 hmmc->State = HAL_MMC_STATE_READY;
1590 return HAL_ERROR;
1591 }
1592
1593 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
1594 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
1595 if (errorstate != HAL_MMC_ERROR_NONE)
1596 {
1597 /* Clear all the static flags */
1598 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1599 hmmc->ErrorCode |= errorstate;
1600 hmmc->State = HAL_MMC_STATE_READY;
1601 return HAL_ERROR;
1602 }
1603
1604 /* Send CMD38 ERASE */
1605 errorstate = SDMMC_CmdErase(hmmc->Instance, 0UL);
1606 if (errorstate != HAL_MMC_ERROR_NONE)
1607 {
1608 /* Clear all the static flags */
1609 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1610 hmmc->ErrorCode |= errorstate;
1611 hmmc->State = HAL_MMC_STATE_READY;
1612 return HAL_ERROR;
1613 }
1614
1615 hmmc->State = HAL_MMC_STATE_READY;
1616
1617 return HAL_OK;
1618 }
1619 else
1620 {
1621 return HAL_BUSY;
1622 }
1623}
1624
1625/**
1626 * @brief This function handles MMC card interrupt request.
1627 * @param hmmc: Pointer to MMC handle
1628 * @retval None
1629 */
1630void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1631{
1632 uint32_t errorstate;
1633 uint32_t context = hmmc->Context;
1634
1635 /* Check for SDMMC interrupt flags */
1636 if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1637 {
1638 MMC_Read_IT(hmmc);
1639 }
1640
1641 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET)
1642 {
1643 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
1644
1645 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
1646 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR | SDMMC_IT_TXFIFOHE | \
1647 SDMMC_IT_RXFIFOHF);
1648
1649 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1650 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
1651
1652 if ((context & MMC_CONTEXT_DMA) != 0U)
1653 {
1654 hmmc->Instance->DLEN = 0;
1655 hmmc->Instance->DCTRL = 0;
1656 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA ;
1657
1658 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1659 if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1660 {
1661 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1662 if (errorstate != HAL_MMC_ERROR_NONE)
1663 {
1664 hmmc->ErrorCode |= errorstate;
1665#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1666 hmmc->ErrorCallback(hmmc);
1667#else
1669#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1670 }
1671 }
1672
1673 /* Clear all the static flags */
1674 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1675
1676 hmmc->State = HAL_MMC_STATE_READY;
1677 if (((context & MMC_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1678 {
1679#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1680 hmmc->TxCpltCallback(hmmc);
1681#else
1683#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1684 }
1685 if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1686 {
1687#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1688 hmmc->RxCpltCallback(hmmc);
1689#else
1691#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1692 }
1693 }
1694 else if ((context & MMC_CONTEXT_IT) != 0U)
1695 {
1696 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1697 if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1698 {
1699 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1700 if (errorstate != HAL_MMC_ERROR_NONE)
1701 {
1702 hmmc->ErrorCode |= errorstate;
1703#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1704 hmmc->ErrorCallback(hmmc);
1705#else
1707#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1708 }
1709 }
1710
1711 /* Clear all the static flags */
1712 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1713
1714 hmmc->State = HAL_MMC_STATE_READY;
1715 if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1716 {
1717#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1718 hmmc->RxCpltCallback(hmmc);
1719#else
1721#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1722 }
1723 else
1724 {
1725#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1726 hmmc->TxCpltCallback(hmmc);
1727#else
1729#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1730 }
1731 }
1732 else
1733 {
1734 /* Nothing to do */
1735 }
1736 }
1737
1738 else if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1739 {
1740 MMC_Write_IT(hmmc);
1741 }
1742
1743 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL |
1744 SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET)
1745 {
1746 /* Set Error code */
1747 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET)
1748 {
1749 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1750 }
1751 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET)
1752 {
1753 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1754 }
1755 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET)
1756 {
1757 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1758 }
1759 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET)
1760 {
1761 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1762 }
1763
1764 /* Clear All flags */
1765 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1766
1767 /* Disable all interrupts */
1768 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
1769 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
1770
1771 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
1772 hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST;
1773 hmmc->Instance->CMD |= SDMMC_CMD_CMDSTOP;
1774 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1775 hmmc->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP);
1776 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DABORT);
1777
1778 if ((context & MMC_CONTEXT_IT) != 0U)
1779 {
1780 /* Set the MMC state to ready to be able to start again the process */
1781 hmmc->State = HAL_MMC_STATE_READY;
1782#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1783 hmmc->ErrorCallback(hmmc);
1784#else
1786#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1787 }
1788 else if ((context & MMC_CONTEXT_DMA) != 0U)
1789 {
1790 if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
1791 {
1792 /* Disable Internal DMA */
1793 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1794 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
1795
1796 /* Set the MMC state to ready to be able to start again the process */
1797 hmmc->State = HAL_MMC_STATE_READY;
1798#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1799 hmmc->ErrorCallback(hmmc);
1800#else
1802#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1803 }
1804 }
1805 else
1806 {
1807 /* Nothing to do */
1808 }
1809 }
1810
1811 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_IDMABTC) != RESET)
1812 {
1813 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_IT_IDMABTC);
1814 if (READ_BIT(hmmc->Instance->IDMACTRL, SDMMC_IDMA_IDMABACT) == 0U)
1815 {
1816 /* Current buffer is buffer0, Transfer complete for buffer1 */
1817 if ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1818 {
1819#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1820 hmmc->Write_DMADblBuf1CpltCallback(hmmc);
1821#else
1822 HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(hmmc);
1823#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1824 }
1825 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1826 {
1827#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1828 hmmc->Read_DMADblBuf1CpltCallback(hmmc);
1829#else
1830 HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(hmmc);
1831#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1832 }
1833 }
1834 else /* MMC_DMA_BUFFER1 */
1835 {
1836 /* Current buffer is buffer1, Transfer complete for buffer0 */
1837 if ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1838 {
1839#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1840 hmmc->Write_DMADblBuf0CpltCallback(hmmc);
1841#else
1842 HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(hmmc);
1843#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1844 }
1845 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1846 {
1847#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1848 hmmc->Read_DMADblBuf0CpltCallback(hmmc);
1849#else
1850 HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(hmmc);
1851#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1852 }
1853 }
1854 }
1855
1856 else
1857 {
1858 /* Nothing to do */
1859 }
1860}
1861
1862/**
1863 * @brief return the MMC state
1864 * @param hmmc: Pointer to mmc handle
1865 * @retval HAL state
1866 */
1867HAL_MMC_StateTypeDef HAL_MMC_GetState(const MMC_HandleTypeDef *hmmc)
1868{
1869 return hmmc->State;
1870}
1871
1872/**
1873 * @brief Return the MMC error code
1874 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1875 * the configuration information.
1876 * @retval MMC Error Code
1877 */
1878uint32_t HAL_MMC_GetError(const MMC_HandleTypeDef *hmmc)
1879{
1880 return hmmc->ErrorCode;
1881}
1882
1883/**
1884 * @brief Tx Transfer completed callbacks
1885 * @param hmmc: Pointer to MMC handle
1886 * @retval None
1887 */
1888__weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1889{
1890 /* Prevent unused argument(s) compilation warning */
1891 UNUSED(hmmc);
1892
1893 /* NOTE : This function should not be modified, when the callback is needed,
1894 the HAL_MMC_TxCpltCallback can be implemented in the user file
1895 */
1896}
1897
1898/**
1899 * @brief Rx Transfer completed callbacks
1900 * @param hmmc: Pointer MMC handle
1901 * @retval None
1902 */
1903__weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1904{
1905 /* Prevent unused argument(s) compilation warning */
1906 UNUSED(hmmc);
1907
1908 /* NOTE : This function should not be modified, when the callback is needed,
1909 the HAL_MMC_RxCpltCallback can be implemented in the user file
1910 */
1911}
1912
1913/**
1914 * @brief MMC error callbacks
1915 * @param hmmc: Pointer MMC handle
1916 * @retval None
1917 */
1918__weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1919{
1920 /* Prevent unused argument(s) compilation warning */
1921 UNUSED(hmmc);
1922
1923 /* NOTE : This function should not be modified, when the callback is needed,
1924 the HAL_MMC_ErrorCallback can be implemented in the user file
1925 */
1926}
1927
1928/**
1929 * @brief MMC Abort callbacks
1930 * @param hmmc: Pointer MMC handle
1931 * @retval None
1932 */
1933__weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1934{
1935 /* Prevent unused argument(s) compilation warning */
1936 UNUSED(hmmc);
1937
1938 /* NOTE : This function should not be modified, when the callback is needed,
1939 the HAL_MMC_AbortCallback can be implemented in the user file
1940 */
1941}
1942
1943#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1944/**
1945 * @brief Register a User MMC Callback
1946 * To be used instead of the weak (overridden) predefined callback
1947 * @note The HAL_MMC_RegisterCallback() may be called before HAL_MMC_Init() in
1948 * HAL_MMC_STATE_RESET to register callbacks for HAL_MMC_MSP_INIT_CB_ID
1949 * and HAL_MMC_MSP_DEINIT_CB_ID.
1950 * @param hmmc : MMC handle
1951 * @param CallbackId : ID of the callback to be registered
1952 * This parameter can be one of the following values:
1953 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1954 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1955 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1956 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1957 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Rx Double buffer 0 Callback ID
1958 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Rx Double buffer 1 Callback ID
1959 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1960 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1961 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1962 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1963 * @param pCallback : pointer to the Callback function
1964 * @retval status
1965 */
1966HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId,
1967 pMMC_CallbackTypeDef pCallback)
1968{
1970
1971 if (pCallback == NULL)
1972 {
1973 /* Update the error code */
1974 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1975 return HAL_ERROR;
1976 }
1977
1978 if (hmmc->State == HAL_MMC_STATE_READY)
1979 {
1980 switch (CallbackId)
1981 {
1982 case HAL_MMC_TX_CPLT_CB_ID :
1983 hmmc->TxCpltCallback = pCallback;
1984 break;
1985 case HAL_MMC_RX_CPLT_CB_ID :
1986 hmmc->RxCpltCallback = pCallback;
1987 break;
1988 case HAL_MMC_ERROR_CB_ID :
1989 hmmc->ErrorCallback = pCallback;
1990 break;
1991 case HAL_MMC_ABORT_CB_ID :
1992 hmmc->AbortCpltCallback = pCallback;
1993 break;
1994 case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
1995 hmmc->Read_DMADblBuf0CpltCallback = pCallback;
1996 break;
1997 case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
1998 hmmc->Read_DMADblBuf1CpltCallback = pCallback;
1999 break;
2000 case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
2001 hmmc->Write_DMADblBuf0CpltCallback = pCallback;
2002 break;
2003 case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
2004 hmmc->Write_DMADblBuf1CpltCallback = pCallback;
2005 break;
2006 case HAL_MMC_MSP_INIT_CB_ID :
2007 hmmc->MspInitCallback = pCallback;
2008 break;
2009 case HAL_MMC_MSP_DEINIT_CB_ID :
2010 hmmc->MspDeInitCallback = pCallback;
2011 break;
2012 default :
2013 /* Update the error code */
2014 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2015 /* update return status */
2016 status = HAL_ERROR;
2017 break;
2018 }
2019 }
2020 else if (hmmc->State == HAL_MMC_STATE_RESET)
2021 {
2022 switch (CallbackId)
2023 {
2024 case HAL_MMC_MSP_INIT_CB_ID :
2025 hmmc->MspInitCallback = pCallback;
2026 break;
2027 case HAL_MMC_MSP_DEINIT_CB_ID :
2028 hmmc->MspDeInitCallback = pCallback;
2029 break;
2030 default :
2031 /* Update the error code */
2032 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2033 /* update return status */
2034 status = HAL_ERROR;
2035 break;
2036 }
2037 }
2038 else
2039 {
2040 /* Update the error code */
2041 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2042 /* update return status */
2043 status = HAL_ERROR;
2044 }
2045
2046 return status;
2047}
2048
2049/**
2050 * @brief Unregister a User MMC Callback
2051 * MMC Callback is redirected to the weak (overridden) predefined callback
2052 * @note The HAL_MMC_UnRegisterCallback() may be called before HAL_MMC_Init() in
2053 * HAL_MMC_STATE_RESET to register callbacks for HAL_MMC_MSP_INIT_CB_ID
2054 * and HAL_MMC_MSP_DEINIT_CB_ID.
2055 * @param hmmc : MMC handle
2056 * @param CallbackId : ID of the callback to be unregistered
2057 * This parameter can be one of the following values:
2058 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
2059 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
2060 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
2061 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
2062 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Rx Double buffer 0 Callback ID
2063 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Rx Double buffer 1 Callback ID
2064 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
2065 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
2066 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
2067 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
2068 * @retval status
2069 */
2070HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
2071{
2073
2074 if (hmmc->State == HAL_MMC_STATE_READY)
2075 {
2076 switch (CallbackId)
2077 {
2078 case HAL_MMC_TX_CPLT_CB_ID :
2079 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
2080 break;
2081 case HAL_MMC_RX_CPLT_CB_ID :
2082 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
2083 break;
2084 case HAL_MMC_ERROR_CB_ID :
2085 hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
2086 break;
2087 case HAL_MMC_ABORT_CB_ID :
2088 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
2089 break;
2090 case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
2091 hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuf0CpltCallback;
2092 break;
2093 case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
2094 hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuf1CpltCallback;
2095 break;
2096 case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
2097 hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuf0CpltCallback;
2098 break;
2099 case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
2100 hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuf1CpltCallback;
2101 break;
2102 case HAL_MMC_MSP_INIT_CB_ID :
2103 hmmc->MspInitCallback = HAL_MMC_MspInit;
2104 break;
2105 case HAL_MMC_MSP_DEINIT_CB_ID :
2106 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2107 break;
2108 default :
2109 /* Update the error code */
2110 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2111 /* update return status */
2112 status = HAL_ERROR;
2113 break;
2114 }
2115 }
2116 else if (hmmc->State == HAL_MMC_STATE_RESET)
2117 {
2118 switch (CallbackId)
2119 {
2120 case HAL_MMC_MSP_INIT_CB_ID :
2121 hmmc->MspInitCallback = HAL_MMC_MspInit;
2122 break;
2123 case HAL_MMC_MSP_DEINIT_CB_ID :
2124 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2125 break;
2126 default :
2127 /* Update the error code */
2128 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2129 /* update return status */
2130 status = HAL_ERROR;
2131 break;
2132 }
2133 }
2134 else
2135 {
2136 /* Update the error code */
2137 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2138 /* update return status */
2139 status = HAL_ERROR;
2140 }
2141
2142 return status;
2143}
2144#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
2145
2146/**
2147 * @}
2148 */
2149
2150/** @addtogroup MMC_Exported_Functions_Group3
2151 * @brief management functions
2152 *
2153@verbatim
2154 ==============================================================================
2155 ##### Peripheral Control functions #####
2156 ==============================================================================
2157 [..]
2158 This subsection provides a set of functions allowing to control the MMC card
2159 operations and get the related information
2160
2161@endverbatim
2162 * @{
2163 */
2164
2165/**
2166 * @brief Returns information the information of the card which are stored on
2167 * the CID register.
2168 * @param hmmc: Pointer to MMC handle
2169 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
2170 * contains all CID register parameters
2171 * @retval HAL status
2172 */
2173HAL_StatusTypeDef HAL_MMC_GetCardCID(const MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
2174{
2175 pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
2176
2177 pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
2178
2179 pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
2180
2181 pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
2182
2183 pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
2184
2185 pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
2186
2187 pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
2188
2189 pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
2190
2191 pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
2192
2193 pCID->Reserved2 = 1U;
2194
2195 return HAL_OK;
2196}
2197
2198/**
2199 * @brief Returns information the information of the card which are stored on
2200 * the CSD register.
2201 * @param hmmc: Pointer to MMC handle
2202 * @param pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
2203 * contains all CSD register parameters
2204 * @retval HAL status
2205 */
2206HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
2207{
2208 uint32_t block_nbr = 0;
2209
2210 pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
2211
2212 pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
2213
2214 pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
2215
2216 pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
2217
2218 pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2219
2220 pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2221
2222 pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2223
2224 pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2225
2226 pCSD->PartBlockRead = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2227
2228 pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2229
2230 pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2231
2232 pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2233
2234 pCSD->Reserved2 = 0U; /*!< Reserved */
2235
2236 if (MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2237 {
2238 return HAL_ERROR;
2239 }
2240
2241 if (hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2242 {
2243 pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2244
2245 pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2246
2247 pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2248
2249 pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2250
2251 pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2252
2253 pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2254
2255 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
2256 hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2257 hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2258
2259 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / MMC_BLOCKSIZE);
2260 hmmc->MmcCard.LogBlockSize = MMC_BLOCKSIZE;
2261 }
2262 else if (hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2263 {
2264 hmmc->MmcCard.BlockNbr = block_nbr;
2265 hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2266 hmmc->MmcCard.BlockSize = MMC_BLOCKSIZE;
2267 hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2268 }
2269 else
2270 {
2271 /* Clear all the static flags */
2272 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2273 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2274 hmmc->State = HAL_MMC_STATE_READY;
2275 return HAL_ERROR;
2276 }
2277
2278 pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2279
2280 pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2281
2282 pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2283
2284 pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2285
2286 pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2287
2288 pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2289
2290 pCSD->MaxWrBlockLen = (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2291
2292 pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2293
2294 pCSD->Reserved3 = 0;
2295
2296 pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2297
2298 pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2299
2300 pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2301
2302 pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2303
2304 pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2305
2306 pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2307
2308 pCSD->ECC = (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2309
2310 pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2311
2312 pCSD->Reserved4 = 1;
2313
2314 return HAL_OK;
2315}
2316
2317/**
2318 * @brief Gets the MMC card info.
2319 * @param hmmc: Pointer to MMC handle
2320 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2321 * will contain the MMC card status information
2322 * @retval HAL status
2323 */
2324HAL_StatusTypeDef HAL_MMC_GetCardInfo(const MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2325{
2326 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
2327 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
2328 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2329 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
2330 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
2331 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2332 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2333
2334 return HAL_OK;
2335}
2336
2337/**
2338 * @brief Returns information the information of the card which are stored on
2339 * the Extended CSD register.
2340 * @param hmmc Pointer to MMC handle
2341 * @param pExtCSD Pointer to a memory area (512 bytes) that contains all
2342 * Extended CSD register parameters
2343 * @param Timeout Specify timeout value
2344 * @retval HAL status
2345 */
2346HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
2347{
2348 SDMMC_DataInitTypeDef config;
2349 uint32_t errorstate;
2350 uint32_t tickstart = HAL_GetTick();
2351 uint32_t count;
2352 uint32_t *tmp_buf;
2353
2354 if (NULL == pExtCSD)
2355 {
2356 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2357 return HAL_ERROR;
2358 }
2359
2360 if (hmmc->State == HAL_MMC_STATE_READY)
2361 {
2362 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2363
2364 hmmc->State = HAL_MMC_STATE_BUSY;
2365
2366 /* Initialize data control register */
2367 hmmc->Instance->DCTRL = 0;
2368
2369 /* Initiaize the destination pointer */
2370 tmp_buf = pExtCSD;
2371
2372 /* Configure the MMC DPSM (Data Path State Machine) */
2373 config.DataTimeOut = SDMMC_DATATIMEOUT;
2374 config.DataLength = MMC_BLOCKSIZE;
2375 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2376 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
2377 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
2378 config.DPSM = SDMMC_DPSM_DISABLE;
2379 (void)SDMMC_ConfigData(hmmc->Instance, &config);
2380 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
2381
2382 /* Send ExtCSD Read command to Card */
2383 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2384 if (errorstate != HAL_MMC_ERROR_NONE)
2385 {
2386 /* Clear all the static flags */
2387 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2388 hmmc->ErrorCode |= errorstate;
2389 hmmc->State = HAL_MMC_STATE_READY;
2390 return HAL_ERROR;
2391 }
2392
2393 /* Poll on SDMMC flags */
2394 while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR |
2395 SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2396 {
2397 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2398 {
2399 /* Read data from SDMMC Rx FIFO */
2400 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
2401 {
2402 *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance);
2403 tmp_buf++;
2404 }
2405 }
2406
2407 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
2408 {
2409 /* Clear all the static flags */
2410 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2411 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2412 hmmc->State = HAL_MMC_STATE_READY;
2413 return HAL_TIMEOUT;
2414 }
2415 }
2416
2417 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
2418
2419 /* Get error state */
2420 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
2421 {
2422 /* Clear all the static flags */
2423 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2424 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
2425 hmmc->State = HAL_MMC_STATE_READY;
2426 return HAL_ERROR;
2427 }
2428 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
2429 {
2430 /* Clear all the static flags */
2431 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2432 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
2433 hmmc->State = HAL_MMC_STATE_READY;
2434 return HAL_ERROR;
2435 }
2436 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
2437 {
2438 /* Clear all the static flags */
2439 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2440 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
2441 hmmc->State = HAL_MMC_STATE_READY;
2442 return HAL_ERROR;
2443 }
2444 else
2445 {
2446 /* Nothing to do */
2447 }
2448
2449 /* Clear all the static flags */
2450 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2451 hmmc->State = HAL_MMC_STATE_READY;
2452 }
2453
2454 return HAL_OK;
2455}
2456
2457/**
2458 * @brief Enables wide bus operation for the requested card if supported by
2459 * card.
2460 * @param hmmc: Pointer to MMC handle
2461 * @param WideMode: Specifies the MMC card wide bus mode
2462 * This parameter can be one of the following values:
2463 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2464 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2465 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2466 * @retval HAL status
2467 */
2468HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2469{
2470 uint32_t count;
2471 SDMMC_InitTypeDef Init;
2472 uint32_t errorstate;
2473 uint32_t response = 0U;
2474
2475 /* Check the parameters */
2476 assert_param(IS_SDMMC_BUS_WIDE(WideMode));
2477
2478 /* Change State */
2479 hmmc->State = HAL_MMC_STATE_BUSY;
2480
2481 /* Check and update the power class if needed */
2482 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2483 {
2484 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2485 {
2486 errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DDR);
2487 }
2488 else
2489 {
2490 errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_HIGH);
2491 }
2492 }
2493 else
2494 {
2495 errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DEFAULT);
2496 }
2497
2498 if (errorstate == HAL_MMC_ERROR_NONE)
2499 {
2500 if (WideMode == SDMMC_BUS_WIDE_8B)
2501 {
2502 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2503 }
2504 else if (WideMode == SDMMC_BUS_WIDE_4B)
2505 {
2506 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2507 }
2508 else if (WideMode == SDMMC_BUS_WIDE_1B)
2509 {
2510 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2511 }
2512 else
2513 {
2514 /* WideMode is not a valid argument*/
2515 errorstate = HAL_MMC_ERROR_PARAM;
2516 }
2517
2518 /* Check for switch error and violation of the trial number of sending CMD 13 */
2519 if (errorstate == HAL_MMC_ERROR_NONE)
2520 {
2521 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2522 count = SDMMC_MAX_TRIAL;
2523 do
2524 {
2525 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2526 if (errorstate != HAL_MMC_ERROR_NONE)
2527 {
2528 break;
2529 }
2530
2531 /* Get command response */
2532 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2533 count--;
2534 } while (((response & 0x100U) == 0U) && (count != 0U));
2535
2536 /* Check the status after the switch command execution */
2537 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2538 {
2539 /* Check the bit SWITCH_ERROR of the device status */
2540 if ((response & 0x80U) != 0U)
2541 {
2542 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2543 }
2544 else
2545 {
2546 /* Configure the SDMMC peripheral */
2547 Init = hmmc->Init;
2548 Init.BusWide = WideMode;
2549 (void)SDMMC_Init(hmmc->Instance, Init);
2550 }
2551 }
2552 else if (count == 0U)
2553 {
2554 errorstate = SDMMC_ERROR_TIMEOUT;
2555 }
2556 else
2557 {
2558 /* Nothing to do */
2559 }
2560 }
2561 }
2562
2563 /* Change State */
2564 hmmc->State = HAL_MMC_STATE_READY;
2565
2566 if (errorstate != HAL_MMC_ERROR_NONE)
2567 {
2568 /* Clear all the static flags */
2569 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2570 hmmc->ErrorCode |= errorstate;
2571 return HAL_ERROR;
2572 }
2573
2574 return HAL_OK;
2575}
2576
2577/**
2578 * @brief Configure the speed bus mode
2579 * @param hmmc: Pointer to the MMC handle
2580 * @param SpeedMode: Specifies the MMC card speed bus mode
2581 * This parameter can be one of the following values:
2582 * @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card
2583 * @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz)
2584 * @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz)
2585 * @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz)
2586 * @retval HAL status
2587 */
2588
2589HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode)
2590{
2591 uint32_t tickstart;
2593 uint32_t device_type;
2594 uint32_t errorstate;
2595
2596 /* Check the parameters */
2597 assert_param(IS_SDMMC_SPEED_MODE(SpeedMode));
2598
2599 /* Change State */
2600 hmmc->State = HAL_MMC_STATE_BUSY;
2601
2602 /* Field DEVICE_TYPE [196 = 49*4] of Extended CSD register */
2603 device_type = (hmmc->Ext_CSD[49] & 0x000000FFU);
2604
2605 switch (SpeedMode)
2606 {
2607 case SDMMC_SPEED_MODE_AUTO:
2608 {
2609 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2610 {
2611 /* High Speed DDR mode allowed */
2612 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2613 if (errorstate != HAL_MMC_ERROR_NONE)
2614 {
2615 hmmc->ErrorCode |= errorstate;
2616 }
2617 else
2618 {
2619 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2620 {
2621 /* DDR mode not supported with CLKDIV = 0 */
2622 errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2623 if (errorstate != HAL_MMC_ERROR_NONE)
2624 {
2625 hmmc->ErrorCode |= errorstate;
2626 }
2627 }
2628 }
2629 }
2630 else if ((device_type & 0x02U) != 0U)
2631 {
2632 /* High Speed mode allowed */
2633 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2634 if (errorstate != HAL_MMC_ERROR_NONE)
2635 {
2636 hmmc->ErrorCode |= errorstate;
2637 }
2638 }
2639 else
2640 {
2641 /* Nothing to do : keep current speed */
2642 }
2643 break;
2644 }
2645 case SDMMC_SPEED_MODE_DDR:
2646 {
2647 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2648 {
2649 /* High Speed DDR mode allowed */
2650 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2651 if (errorstate != HAL_MMC_ERROR_NONE)
2652 {
2653 hmmc->ErrorCode |= errorstate;
2654 }
2655 else
2656 {
2657 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2658 {
2659 /* DDR mode not supported with CLKDIV = 0 */
2660 errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2661 if (errorstate != HAL_MMC_ERROR_NONE)
2662 {
2663 hmmc->ErrorCode |= errorstate;
2664 }
2665 }
2666 }
2667 }
2668 else
2669 {
2670 /* High Speed DDR mode not allowed */
2671 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2672 status = HAL_ERROR;
2673 }
2674 break;
2675 }
2676 case SDMMC_SPEED_MODE_HIGH:
2677 {
2678 if ((device_type & 0x02U) != 0U)
2679 {
2680 /* High Speed mode allowed */
2681 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2682 if (errorstate != HAL_MMC_ERROR_NONE)
2683 {
2684 hmmc->ErrorCode |= errorstate;
2685 }
2686 }
2687 else
2688 {
2689 /* High Speed mode not allowed */
2690 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2691 status = HAL_ERROR;
2692 }
2693 break;
2694 }
2695 case SDMMC_SPEED_MODE_DEFAULT:
2696 {
2697 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2698 {
2699 /* High Speed DDR mode activated */
2700 errorstate = MMC_DDR_Mode(hmmc, DISABLE);
2701 if (errorstate != HAL_MMC_ERROR_NONE)
2702 {
2703 hmmc->ErrorCode |= errorstate;
2704 }
2705 }
2706 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2707 {
2708 /* High Speed mode activated */
2709 errorstate = MMC_HighSpeed(hmmc, DISABLE);
2710 if (errorstate != HAL_MMC_ERROR_NONE)
2711 {
2712 hmmc->ErrorCode |= errorstate;
2713 }
2714 }
2715 break;
2716 }
2717 default:
2718 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2719 status = HAL_ERROR;
2720 break;
2721 }
2722
2723 /* Verify that MMC card is ready to use after Speed mode switch*/
2724 tickstart = HAL_GetTick();
2725 while ((HAL_MMC_GetCardState(hmmc) != HAL_MMC_CARD_TRANSFER))
2726 {
2727 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
2728 {
2729 hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2730 hmmc->State = HAL_MMC_STATE_READY;
2731 return HAL_TIMEOUT;
2732 }
2733 }
2734
2735 /* Change State */
2736 hmmc->State = HAL_MMC_STATE_READY;
2737 return status;
2738}
2739
2740/**
2741 * @brief Gets the current mmc card data state.
2742 * @param hmmc: pointer to MMC handle
2743 * @retval Card state
2744 */
2745HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2746{
2747 uint32_t cardstate;
2748 uint32_t errorstate;
2749 uint32_t resp1 = 0U;
2750
2751 errorstate = MMC_SendStatus(hmmc, &resp1);
2752 if (errorstate != HAL_MMC_ERROR_NONE)
2753 {
2754 hmmc->ErrorCode |= errorstate;
2755 }
2756
2757 cardstate = ((resp1 >> 9U) & 0x0FU);
2758
2759 return (HAL_MMC_CardStateTypeDef)cardstate;
2760}
2761
2762/**
2763 * @brief Abort the current transfer and disable the MMC.
2764 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2765 * the configuration information for MMC module.
2766 * @retval HAL status
2767 */
2768HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2769{
2770 uint32_t error_code;
2771 uint32_t tickstart;
2772
2773 if (hmmc->State == HAL_MMC_STATE_BUSY)
2774 {
2775 /* DIsable All interrupts */
2776 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
2777 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
2778 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
2779
2780 /*we will send the CMD12 in all cases in order to stop the data transfers*/
2781 /*In case the data transfer just finished, the external memory will not respond
2782 and will return HAL_MMC_ERROR_CMD_RSP_TIMEOUT*/
2783 /*In case the data transfer aborted , the external memory will respond and will return HAL_MMC_ERROR_NONE*/
2784 /*Other scenario will return HAL_ERROR*/
2785
2786 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2787 error_code = hmmc->ErrorCode;
2788 if ((error_code != HAL_MMC_ERROR_NONE) && (error_code != HAL_MMC_ERROR_CMD_RSP_TIMEOUT))
2789 {
2790 return HAL_ERROR;
2791 }
2792
2793 tickstart = HAL_GetTick();
2794 if ((hmmc->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_CARD)
2795 {
2796 if (hmmc->ErrorCode == HAL_MMC_ERROR_NONE)
2797 {
2798 while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DABORT | SDMMC_FLAG_BUSYD0END))
2799 {
2800 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
2801 {
2802 hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2803 hmmc->State = HAL_MMC_STATE_READY;
2804 return HAL_TIMEOUT;
2805 }
2806 }
2807 }
2808
2809 if (hmmc->ErrorCode == HAL_MMC_ERROR_CMD_RSP_TIMEOUT)
2810 {
2811 while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND))
2812 {
2813 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
2814 {
2815 hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2816 hmmc->State = HAL_MMC_STATE_READY;
2817 return HAL_TIMEOUT;
2818 }
2819 }
2820 }
2821 }
2822 else if ((hmmc->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_SDMMC)
2823 {
2824 while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DABORT | SDMMC_FLAG_DATAEND))
2825 {
2826 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
2827 {
2828 hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2829 hmmc->State = HAL_MMC_STATE_READY;
2830 return HAL_TIMEOUT;
2831 }
2832 }
2833 }
2834 else
2835 {
2836 /* Nothing to do*/
2837 }
2838
2839 /*The reason of all these while conditions previously is that we need to wait the SDMMC and clear
2840 the appropriate flags that will be set depending of the abort/non abort of the memory */
2841 /*Not waiting the SDMMC flags will cause the next SDMMC_DISABLE_IDMA to not get cleared and will result
2842 in next SDMMC read/write operation to fail */
2843
2844 /*SDMMC ready for clear data flags*/
2845 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
2846 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2847 /* If IDMA Context, disable Internal DMA */
2848 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2849
2850 hmmc->State = HAL_MMC_STATE_READY;
2851
2852 /* Initialize the MMC operation */
2853 hmmc->Context = MMC_CONTEXT_NONE;
2854 }
2855 return HAL_OK;
2856}
2857/**
2858 * @brief Abort the current transfer and disable the MMC (IT mode).
2859 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2860 * the configuration information for MMC module.
2861 * @retval HAL status
2862 */
2863HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2864{
2865 HAL_MMC_CardStateTypeDef CardState;
2866
2867 /* DIsable All interrupts */
2868 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
2869 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
2870
2871 /* If IDMA Context, disable Internal DMA */
2872 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2873
2874 /* Clear All flags */
2875 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2876
2877 CardState = HAL_MMC_GetCardState(hmmc);
2878 hmmc->State = HAL_MMC_STATE_READY;
2879
2880 if ((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2881 {
2882 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2883 }
2884 if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2885 {
2886 return HAL_ERROR;
2887 }
2888 else
2889 {
2890#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2891 hmmc->AbortCpltCallback(hmmc);
2892#else
2893 HAL_MMC_AbortCallback(hmmc);
2894#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
2895 }
2896
2897 return HAL_OK;
2898}
2899
2900/**
2901 * @brief Perform specific commands sequence for the different type of erase.
2902 * @note This API should be followed by a check on the card state through
2903 * HAL_MMC_GetCardState().
2904 * @param hmmc Pointer to MMC handle
2905 * @param EraseType Specifies the type of erase to be performed
2906 * This parameter can be one of the following values:
2907 * @arg HAL_MMC_TRIM Erase the write blocks identified by CMD35 & 36
2908 * @arg HAL_MMC_ERASE Erase the erase groups identified by CMD35 & 36
2909 * @arg HAL_MMC_DISCARD Discard the write blocks identified by CMD35 & 36
2910 * @arg HAL_MMC_SECURE_ERASE Perform a secure purge according SRT on the erase groups identified
2911 * by CMD35 & 36
2912 * @arg HAL_MMC_SECURE_TRIM_STEP1 Mark the write blocks identified by CMD35 & 36 for secure erase
2913 * @arg HAL_MMC_SECURE_TRIM_STEP2 Perform a secure purge according SRT on the write blocks
2914 * previously identified
2915 * @param BlockStartAdd Start Block address
2916 * @param BlockEndAdd End Block address
2917 * @retval HAL status
2918 */
2919HAL_StatusTypeDef HAL_MMC_EraseSequence(MMC_HandleTypeDef *hmmc, uint32_t EraseType,
2920 uint32_t BlockStartAdd, uint32_t BlockEndAdd)
2921{
2922 uint32_t errorstate;
2923 uint32_t start_add = BlockStartAdd;
2924 uint32_t end_add = BlockEndAdd;
2925 uint32_t tickstart = HAL_GetTick();
2926
2927 /* Check the erase type value is correct */
2928 assert_param(IS_MMC_ERASE_TYPE(EraseType));
2929
2930 /* Check the coherence between start and end address */
2931 if (end_add < start_add)
2932 {
2933 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2934 return HAL_ERROR;
2935 }
2936
2937 /* Check that the end address is not out of range of device memory */
2938 if (end_add > (hmmc->MmcCard.LogBlockNbr))
2939 {
2940 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
2941 return HAL_ERROR;
2942 }
2943
2944 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
2945 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
2946 {
2947 if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U))
2948 {
2949 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
2950 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
2951 return HAL_ERROR;
2952 }
2953 }
2954
2955 /* Check if the card command class supports erase command */
2956 if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
2957 {
2958 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2959 return HAL_ERROR;
2960 }
2961
2962 /* Check the state of the driver */
2963 if (hmmc->State == HAL_MMC_STATE_READY)
2964 {
2965 /* Change State */
2966 hmmc->State = HAL_MMC_STATE_BUSY;
2967
2968 /* Check that the card is not locked */
2969 if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
2970 {
2971 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
2972 hmmc->State = HAL_MMC_STATE_READY;
2973 return HAL_ERROR;
2974 }
2975
2976 /* In case of low capacity card, the address is not block number but bytes */
2977 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
2978 {
2979 start_add *= MMC_BLOCKSIZE;
2980 end_add *= MMC_BLOCKSIZE;
2981 }
2982
2983 /* Send CMD35 MMC_ERASE_GRP_START with start address as argument */
2984 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
2985 if (errorstate == HAL_MMC_ERROR_NONE)
2986 {
2987 /* Send CMD36 MMC_ERASE_GRP_END with end address as argument */
2988 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
2989 if (errorstate == HAL_MMC_ERROR_NONE)
2990 {
2991 /* Send CMD38 ERASE with erase type as argument */
2992 errorstate = SDMMC_CmdErase(hmmc->Instance, EraseType);
2993 if (errorstate == HAL_MMC_ERROR_NONE)
2994 {
2995 if ((EraseType == HAL_MMC_SECURE_ERASE) || (EraseType == HAL_MMC_SECURE_TRIM_STEP2))
2996 {
2997 /* Wait that the device is ready by checking the D0 line */
2998 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
2999 {
3000 if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
3001 {
3002 errorstate = HAL_MMC_ERROR_TIMEOUT;
3003 }
3004 }
3005
3006 /* Clear the flag corresponding to end D0 bus line */
3007 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3008 }
3009 }
3010 }
3011 }
3012
3013 /* Change State */
3014 hmmc->State = HAL_MMC_STATE_READY;
3015
3016 /* Manage errors */
3017 if (errorstate != HAL_MMC_ERROR_NONE)
3018 {
3019 /* Clear all the static flags */
3020 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3021 hmmc->ErrorCode |= errorstate;
3022
3023 if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3024 {
3025 return HAL_ERROR;
3026 }
3027 else
3028 {
3029 return HAL_TIMEOUT;
3030 }
3031 }
3032 else
3033 {
3034 return HAL_OK;
3035 }
3036 }
3037 else
3038 {
3039 return HAL_BUSY;
3040 }
3041}
3042
3043/**
3044 * @brief Perform sanitize operation on the device.
3045 * @note This API should be followed by a check on the card state through
3046 * HAL_MMC_GetCardState().
3047 * @param hmmc Pointer to MMC handle
3048 * @retval HAL status
3049 */
3050HAL_StatusTypeDef HAL_MMC_Sanitize(MMC_HandleTypeDef *hmmc)
3051{
3052 uint32_t errorstate;
3053 uint32_t response = 0U;
3054 uint32_t count;
3055 uint32_t tickstart = HAL_GetTick();
3056
3057 /* Check the state of the driver */
3058 if (hmmc->State == HAL_MMC_STATE_READY)
3059 {
3060 /* Change State */
3061 hmmc->State = HAL_MMC_STATE_BUSY;
3062
3063 /* Index : 165 - Value : 0x01 */
3064 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03A50100U);
3065 if (errorstate == HAL_MMC_ERROR_NONE)
3066 {
3067 /* Wait that the device is ready by checking the D0 line */
3068 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3069 {
3070 if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
3071 {
3072 errorstate = HAL_MMC_ERROR_TIMEOUT;
3073 }
3074 }
3075
3076 /* Clear the flag corresponding to end D0 bus line */
3077 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3078
3079 if (errorstate == HAL_MMC_ERROR_NONE)
3080 {
3081 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3082 count = SDMMC_MAX_TRIAL;
3083 do
3084 {
3085 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3086 if (errorstate != HAL_MMC_ERROR_NONE)
3087 {
3088 break;
3089 }
3090
3091 /* Get command response */
3092 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3093 count--;
3094 } while (((response & 0x100U) == 0U) && (count != 0U));
3095
3096 /* Check the status after the switch command execution */
3097 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3098 {
3099 /* Check the bit SWITCH_ERROR of the device status */
3100 if ((response & 0x80U) != 0U)
3101 {
3102 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3103 }
3104 }
3105 else if (count == 0U)
3106 {
3107 errorstate = SDMMC_ERROR_TIMEOUT;
3108 }
3109 else
3110 {
3111 /* Nothing to do */
3112 }
3113 }
3114 }
3115
3116 /* Change State */
3117 hmmc->State = HAL_MMC_STATE_READY;
3118
3119 /* Manage errors */
3120 if (errorstate != HAL_MMC_ERROR_NONE)
3121 {
3122 /* Clear all the static flags */
3123 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3124 hmmc->ErrorCode |= errorstate;
3125
3126 if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3127 {
3128 return HAL_ERROR;
3129 }
3130 else
3131 {
3132 return HAL_TIMEOUT;
3133 }
3134 }
3135 else
3136 {
3137 return HAL_OK;
3138 }
3139 }
3140 else
3141 {
3142 return HAL_BUSY;
3143 }
3144}
3145
3146/**
3147 * @brief Configure the Secure Removal Type (SRT) in the Extended CSD register.
3148 * @note This API should be followed by a check on the card state through
3149 * HAL_MMC_GetCardState().
3150 * @param hmmc Pointer to MMC handle
3151 * @param SRTMode Specifies the type of erase to be performed
3152 * This parameter can be one of the following values:
3153 * @arg HAL_MMC_SRT_ERASE Information removed by an erase
3154 * @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character
3155 * followed by an erase
3156 * @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character,
3157 * its complement then a random character
3158 * @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3159 * @retval HAL status
3160 */
3161HAL_StatusTypeDef HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t SRTMode)
3162{
3163 uint32_t srt;
3164 uint32_t errorstate;
3165 uint32_t response = 0U;
3166 uint32_t count;
3167
3168 /* Check the erase type value is correct */
3169 assert_param(IS_MMC_SRT_TYPE(SRTMode));
3170
3171 /* Check the state of the driver */
3172 if (hmmc->State == HAL_MMC_STATE_READY)
3173 {
3174 /* Get the supported values by the device */
3175 if (HAL_MMC_GetSupportedSecRemovalType(hmmc, &srt) == HAL_OK)
3176 {
3177 /* Change State */
3178 hmmc->State = HAL_MMC_STATE_BUSY;
3179
3180 /* Check the value passed as parameter is supported by the device */
3181 if ((SRTMode & srt) != 0U)
3182 {
3183 /* Index : 16 - Value : SRTMode */
3184 srt |= ((POSITION_VAL(SRTMode)) << 4U);
3185 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03100000U | (srt << 8U)));
3186 if (errorstate == HAL_MMC_ERROR_NONE)
3187 {
3188 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3189 count = SDMMC_MAX_TRIAL;
3190 do
3191 {
3192 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3193 if (errorstate != HAL_MMC_ERROR_NONE)
3194 {
3195 break;
3196 }
3197
3198 /* Get command response */
3199 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3200 count--;
3201 } while (((response & 0x100U) == 0U) && (count != 0U));
3202
3203 /* Check the status after the switch command execution */
3204 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3205 {
3206 /* Check the bit SWITCH_ERROR of the device status */
3207 if ((response & 0x80U) != 0U)
3208 {
3209 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3210 }
3211 }
3212 else if (count == 0U)
3213 {
3214 errorstate = SDMMC_ERROR_TIMEOUT;
3215 }
3216 else
3217 {
3218 /* Nothing to do */
3219 }
3220 }
3221 }
3222 else
3223 {
3224 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3225 }
3226
3227 /* Change State */
3228 hmmc->State = HAL_MMC_STATE_READY;
3229 }
3230 else
3231 {
3232 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3233 }
3234
3235 /* Manage errors */
3236 if (errorstate != HAL_MMC_ERROR_NONE)
3237 {
3238 /* Clear all the static flags */
3239 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3240 hmmc->ErrorCode |= errorstate;
3241 return HAL_ERROR;
3242 }
3243 else
3244 {
3245 return HAL_OK;
3246 }
3247 }
3248 else
3249 {
3250 return HAL_BUSY;
3251 }
3252}
3253
3254/**
3255 * @brief Gets the supported values of the the Secure Removal Type (SRT).
3256 * @param hmmc pointer to MMC handle
3257 * @param SupportedSRT pointer for supported SRT value
3258 * This parameter is a bit field of the following values:
3259 * @arg HAL_MMC_SRT_ERASE Information removed by an erase
3260 * @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed
3261 * by an erase
3262 * @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character,
3263 * its complement then a random character
3264 * @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3265 * @retval HAL status
3266 */
3267HAL_StatusTypeDef HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t *SupportedSRT)
3268{
3269 /* Check the state of the driver */
3270 if (hmmc->State == HAL_MMC_STATE_READY)
3271 {
3272 /* Change State */
3273 hmmc->State = HAL_MMC_STATE_BUSY;
3274
3275 /* Read field SECURE_REMOVAL_TYPE [16 = 4*4] of the Extended CSD register */
3276 *SupportedSRT = (hmmc->Ext_CSD[4] & 0x0000000FU); /* Bits [3:0] of field 16 */
3277
3278 /* Change State */
3279 hmmc->State = HAL_MMC_STATE_READY;
3280
3281 return HAL_OK;
3282 }
3283 else
3284 {
3285 return HAL_BUSY;
3286 }
3287}
3288
3289/**
3290 * @brief Switch the device from Standby State to Sleep State.
3291 * @param hmmc pointer to MMC handle
3292 * @retval HAL status
3293 */
3294HAL_StatusTypeDef HAL_MMC_SleepDevice(MMC_HandleTypeDef *hmmc)
3295{
3296 uint32_t errorstate,
3297 sleep_timeout,
3298 timeout,
3299 count,
3300 response = 0U ;
3301 uint32_t tickstart = HAL_GetTick();
3302
3303 /* Check the state of the driver */
3304 if (hmmc->State == HAL_MMC_STATE_READY)
3305 {
3306 /* Change State */
3307 hmmc->State = HAL_MMC_STATE_BUSY;
3308
3309 /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3310 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3311 if (errorstate == HAL_MMC_ERROR_NONE)
3312 {
3313 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3314 count = SDMMC_MAX_TRIAL;
3315 do
3316 {
3317 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3318 if (errorstate != HAL_MMC_ERROR_NONE)
3319 {
3320 break;
3321 }
3322
3323 /* Get command response */
3324 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3325 count--;
3326 } while (((response & 0x100U) == 0U) && (count != 0U));
3327
3328 /* Check the status after the switch command execution */
3329 if (count == 0U)
3330 {
3331 errorstate = SDMMC_ERROR_TIMEOUT;
3332 }
3333 else if (errorstate == HAL_MMC_ERROR_NONE)
3334 {
3335 /* Check the bit SWITCH_ERROR of the device status */
3336 if ((response & 0x80U) != 0U)
3337 {
3338 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3339 }
3340 else
3341 {
3342 /* Set the power-off notification to sleep notification : Ext_CSD[34] = 4 */
3343 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220400U));
3344 if (errorstate == HAL_MMC_ERROR_NONE)
3345 {
3346 /* Field SLEEP_NOTIFICATION_TIME [216] */
3347 sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX / 4)] >>
3348 MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS) & 0x000000FFU);
3349
3350 /* Sleep/Awake Timeout = 10us * 2^SLEEP_NOTIFICATION_TIME */
3351 /* In HAL, the tick interrupt occurs each ms */
3352 if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3353 {
3354 sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3355 }
3356 timeout = (((1UL << sleep_timeout) / 100U) + 1U);
3357
3358 /* Wait that the device is ready by checking the D0 line */
3359 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3360 {
3361 if ((HAL_GetTick() - tickstart) >= timeout)
3362 {
3363 errorstate = SDMMC_ERROR_TIMEOUT;
3364 }
3365 }
3366
3367 /* Clear the flag corresponding to end D0 bus line */
3368 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3369
3370 if (errorstate == HAL_MMC_ERROR_NONE)
3371 {
3372 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3373 count = SDMMC_MAX_TRIAL;
3374 do
3375 {
3376 errorstate = SDMMC_CmdSendStatus(hmmc->Instance,
3377 (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3378 if (errorstate != HAL_MMC_ERROR_NONE)
3379 {
3380 break;
3381 }
3382
3383 /* Get command response */
3384 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3385 count--;
3386 } while (((response & 0x100U) == 0U) && (count != 0U));
3387
3388 /* Check the status after the switch command execution */
3389 if (count == 0U)
3390 {
3391 errorstate = SDMMC_ERROR_TIMEOUT;
3392 }
3393 else if (errorstate == HAL_MMC_ERROR_NONE)
3394 {
3395 /* Check the bit SWITCH_ERROR of the device status */
3396 if ((response & 0x80U) != 0U)
3397 {
3398 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3399 }
3400 else
3401 {
3402 /* Switch the device in stand-by mode */
3403 (void)SDMMC_CmdSelDesel(hmmc->Instance, 0U);
3404
3405 /* Field S_A_TIEMOUT [217] */
3406 sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >>
3407 MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU);
3408
3409 /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */
3410 /* In HAL, the tick interrupt occurs each ms */
3411 if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3412 {
3413 sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3414 }
3415 timeout = (((1UL << sleep_timeout) / 10000U) + 1U);
3416
3417 if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3418 {
3419 /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and SLEEP as argument */
3420 errorstate = SDMMC_CmdSleepMmc(hmmc->Instance,
3421 ((hmmc->MmcCard.RelCardAdd << 16UL) | (0x1UL << 15UL)));
3422 if (errorstate == HAL_MMC_ERROR_NONE)
3423 {
3424 /* Wait that the device is ready by checking the D0 line */
3425 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3426 {
3427 if ((HAL_GetTick() - tickstart) >= timeout)
3428 {
3429 errorstate = SDMMC_ERROR_TIMEOUT;
3430 }
3431 }
3432
3433 /* Clear the flag corresponding to end D0 bus line */
3434 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3435 }
3436 }
3437 else
3438 {
3439 errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3440 }
3441 }
3442 }
3443 else
3444 {
3445 /* Nothing to do */
3446 }
3447 }
3448 }
3449 }
3450 }
3451 else
3452 {
3453 /* Nothing to do */
3454 }
3455 }
3456
3457 /* Change State */
3458 hmmc->State = HAL_MMC_STATE_READY;
3459
3460 /* Manage errors */
3461 if (errorstate != HAL_MMC_ERROR_NONE)
3462 {
3463 /* Clear all the static flags */
3464 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3465 hmmc->ErrorCode |= errorstate;
3466
3467 if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3468 {
3469 return HAL_ERROR;
3470 }
3471 else
3472 {
3473 return HAL_TIMEOUT;
3474 }
3475 }
3476 else
3477 {
3478 return HAL_OK;
3479 }
3480 }
3481 else
3482 {
3483 return HAL_BUSY;
3484 }
3485}
3486
3487/**
3488 * @brief Switch the device from Sleep State to Standby State.
3489 * @param hmmc pointer to MMC handle
3490 * @retval HAL status
3491 */
3492HAL_StatusTypeDef HAL_MMC_AwakeDevice(MMC_HandleTypeDef *hmmc)
3493{
3494 uint32_t errorstate;
3495 uint32_t sleep_timeout;
3496 uint32_t timeout;
3497 uint32_t count;
3498 uint32_t response = 0U;
3499 uint32_t tickstart = HAL_GetTick();
3500
3501 /* Check the state of the driver */
3502 if (hmmc->State == HAL_MMC_STATE_READY)
3503 {
3504 /* Change State */
3505 hmmc->State = HAL_MMC_STATE_BUSY;
3506
3507 /* Field S_A_TIEMOUT [217] */
3508 sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) &
3509 0x000000FFU);
3510
3511 /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */
3512 /* In HAL, the tick interrupt occurs each ms */
3513 if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3514 {
3515 sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3516 }
3517 timeout = (((1UL << sleep_timeout) / 10000U) + 1U);
3518
3519 /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and AWAKE as argument */
3520 errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3521 if (errorstate == HAL_MMC_ERROR_NONE)
3522 {
3523 /* Wait that the device is ready by checking the D0 line */
3524 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3525 {
3526 if ((HAL_GetTick() - tickstart) >= timeout)
3527 {
3528 errorstate = SDMMC_ERROR_TIMEOUT;
3529 }
3530 }
3531
3532 /* Clear the flag corresponding to end D0 bus line */
3533 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3534
3535 if (errorstate == HAL_MMC_ERROR_NONE)
3536 {
3537 if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3538 {
3539 /* Switch the device in transfer mode */
3540 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3541 if (errorstate == HAL_MMC_ERROR_NONE)
3542 {
3543 if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_TRANSFER)
3544 {
3545 /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3546 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3547 if (errorstate == HAL_MMC_ERROR_NONE)
3548 {
3549 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3550 count = SDMMC_MAX_TRIAL;
3551 do
3552 {
3553 errorstate = SDMMC_CmdSendStatus(hmmc->Instance,
3554 (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3555 if (errorstate != HAL_MMC_ERROR_NONE)
3556 {
3557 break;
3558 }
3559
3560 /* Get command response */
3561 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3562 count--;
3563 } while (((response & 0x100U) == 0U) && (count != 0U));
3564
3565 /* Check the status after the switch command execution */
3566 if (count == 0U)
3567 {
3568 errorstate = SDMMC_ERROR_TIMEOUT;
3569 }
3570 else if (errorstate == HAL_MMC_ERROR_NONE)
3571 {
3572 /* Check the bit SWITCH_ERROR of the device status */
3573 if ((response & 0x80U) != 0U)
3574 {
3575 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3576 }
3577 }
3578 else
3579 {
3580 /* NOthing to do */
3581 }
3582 }
3583 }
3584 else
3585 {
3586 errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3587 }
3588 }
3589 }
3590 else
3591 {
3592 errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3593 }
3594 }
3595 }
3596
3597 /* Change State */
3598 hmmc->State = HAL_MMC_STATE_READY;
3599
3600 /* Manage errors */
3601 if (errorstate != HAL_MMC_ERROR_NONE)
3602 {
3603 /* Clear all the static flags */
3604 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3605 hmmc->ErrorCode |= errorstate;
3606
3607 if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3608 {
3609 return HAL_ERROR;
3610 }
3611 else
3612 {
3613 return HAL_TIMEOUT;
3614 }
3615 }
3616 else
3617 {
3618 return HAL_OK;
3619 }
3620 }
3621 else
3622 {
3623 return HAL_BUSY;
3624 }
3625}
3626/**
3627 * @}
3628 */
3629
3630/**
3631 * @}
3632 */
3633
3634/* Private function ----------------------------------------------------------*/
3635/** @addtogroup MMC_Private_Functions
3636 * @{
3637 */
3638
3639/**
3640 * @brief Initializes the mmc card.
3641 * @param hmmc: Pointer to MMC handle
3642 * @retval MMC Card error state
3643 */
3644static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
3645{
3646 HAL_MMC_CardCSDTypeDef CSD;
3647 uint32_t errorstate;
3648 uint16_t mmc_rca = 2U;
3649 MMC_InitTypeDef Init;
3650
3651 /* Check the power State */
3652 if (SDMMC_GetPowerState(hmmc->Instance) == 0U)
3653 {
3654 /* Power off */
3655 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
3656 }
3657
3658 /* Send CMD2 ALL_SEND_CID */
3659 errorstate = SDMMC_CmdSendCID(hmmc->Instance);
3660 if (errorstate != HAL_MMC_ERROR_NONE)
3661 {
3662 return errorstate;
3663 }
3664 else
3665 {
3666 /* Get Card identification number data */
3667 hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3668 hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3669 hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3670 hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3671 }
3672
3673 /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
3674 /* MMC Card publishes its RCA. */
3675 errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
3676 if (errorstate != HAL_MMC_ERROR_NONE)
3677 {
3678 return errorstate;
3679 }
3680
3681 /* Get the MMC card RCA */
3682 hmmc->MmcCard.RelCardAdd = mmc_rca;
3683
3684 /* Send CMD9 SEND_CSD with argument as card's RCA */
3685 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3686 if (errorstate != HAL_MMC_ERROR_NONE)
3687 {
3688 return errorstate;
3689 }
3690 else
3691 {
3692 /* Get Card Specific Data */
3693 hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3694 hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3695 hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3696 hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3697 }
3698
3699 /* Get the Card Class */
3700 hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U);
3701
3702 /* Select the Card */
3703 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3704 if (errorstate != HAL_MMC_ERROR_NONE)
3705 {
3706 return errorstate;
3707 }
3708
3709 /* Get CSD parameters */
3710 if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
3711 {
3712 return hmmc->ErrorCode;
3713 }
3714
3715 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3716 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3717 if (errorstate != HAL_MMC_ERROR_NONE)
3718 {
3719 hmmc->ErrorCode |= errorstate;
3720 }
3721
3722 /* Get Extended CSD parameters */
3723 if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
3724 {
3725 return hmmc->ErrorCode;
3726 }
3727
3728 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3729 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3730 if (errorstate != HAL_MMC_ERROR_NONE)
3731 {
3732 hmmc->ErrorCode |= errorstate;
3733 }
3734
3735 /* Configure the SDMMC peripheral */
3736 Init = hmmc->Init;
3737 Init.BusWide = SDMMC_BUS_WIDE_1B;
3738 (void)SDMMC_Init(hmmc->Instance, Init);
3739
3740 /* All cards are initialized */
3741 return HAL_MMC_ERROR_NONE;
3742}
3743
3744/**
3745 * @brief Enquires cards about their operating voltage and configures clock
3746 * controls and stores MMC information that will be needed in future
3747 * in the MMC handle.
3748 * @param hmmc: Pointer to MMC handle
3749 * @retval error state
3750 */
3751static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
3752{
3753 __IO uint32_t count = 0U;
3754 uint32_t response = 0U;
3755 uint32_t validvoltage = 0U;
3756 uint32_t errorstate;
3757
3758 /* CMD0: GO_IDLE_STATE */
3759 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
3760 if (errorstate != HAL_MMC_ERROR_NONE)
3761 {
3762 return errorstate;
3763 }
3764
3765 while (validvoltage == 0U)
3766 {
3767 if (count++ == SDMMC_MAX_VOLT_TRIAL)
3768 {
3769 return HAL_MMC_ERROR_INVALID_VOLTRANGE;
3770 }
3771
3772 /* SEND CMD1 APP_CMD with voltage range as argument */
3773 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
3774 if (errorstate != HAL_MMC_ERROR_NONE)
3775 {
3776 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
3777 }
3778
3779 /* Get command response */
3780 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3781
3782 /* Get operating voltage*/
3783 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
3784 }
3785
3786 /* When power routine is finished and command returns valid voltage */
3787 if (((response & (0xFF000000U)) >> 24) == 0xC0U)
3788 {
3789 hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
3790 }
3791 else
3792 {
3793 hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
3794 }
3795
3796 return HAL_MMC_ERROR_NONE;
3797}
3798
3799/**
3800 * @brief Turns the SDMMC output signals off.
3801 * @param hmmc: Pointer to MMC handle
3802 * @retval None
3803 */
3804static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
3805{
3806 /* Set Power State to OFF */
3807 (void)SDMMC_PowerState_OFF(hmmc->Instance);
3808}
3809
3810/**
3811 * @brief Returns the current card's status.
3812 * @param hmmc: Pointer to MMC handle
3813 * @param pCardStatus: pointer to the buffer that will contain the MMC card
3814 * status (Card Status register)
3815 * @retval error state
3816 */
3817static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
3818{
3819 uint32_t errorstate;
3820
3821 if (pCardStatus == NULL)
3822 {
3823 return HAL_MMC_ERROR_PARAM;
3824 }
3825
3826 /* Send Status command */
3827 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3828 if (errorstate != HAL_MMC_ERROR_NONE)
3829 {
3830 return errorstate;
3831 }
3832
3833 /* Get MMC card status */
3834 *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3835
3836 return HAL_MMC_ERROR_NONE;
3837}
3838
3839/**
3840 * @brief Reads extended CSD register to get the sectors number of the device
3841 * @param hmmc: Pointer to MMC handle
3842 * @param pFieldData: Pointer to the read buffer
3843 * @param FieldIndex: Index of the field to be read
3844 * @param Timeout: Specify timeout value
3845 * @retval HAL status
3846 */
3847static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData,
3848 uint16_t FieldIndex, uint32_t Timeout)
3849{
3850 SDMMC_DataInitTypeDef config;
3851 uint32_t errorstate;
3852 uint32_t tickstart = HAL_GetTick();
3853 uint32_t count;
3854 uint32_t i = 0;
3855 uint32_t tmp_data;
3856
3857 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
3858
3859 /* Initialize data control register */
3860 hmmc->Instance->DCTRL = 0;
3861
3862 /* Configure the MMC DPSM (Data Path State Machine) */
3863 config.DataTimeOut = SDMMC_DATATIMEOUT;
3864 config.DataLength = MMC_BLOCKSIZE;
3865 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
3866 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
3867 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
3868 config.DPSM = SDMMC_DPSM_ENABLE;
3869 (void)SDMMC_ConfigData(hmmc->Instance, &config);
3870
3871 /* Set Block Size for Card */
3872 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
3873 if (errorstate != HAL_MMC_ERROR_NONE)
3874 {
3875 /* Clear all the static flags */
3876 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3877 hmmc->ErrorCode |= errorstate;
3878 hmmc->State = HAL_MMC_STATE_READY;
3879 return HAL_ERROR;
3880 }
3881
3882 /* Poll on SDMMC flags */
3883 while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT |
3884 SDMMC_FLAG_DATAEND))
3885 {
3886 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
3887 {
3888 /* Read data from SDMMC Rx FIFO */
3889 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
3890 {
3891 tmp_data = SDMMC_ReadFIFO(hmmc->Instance);
3892 /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */
3893 /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
3894 if ((i + count) == ((uint32_t)FieldIndex / 4U))
3895 {
3896 *pFieldData = tmp_data;
3897 }
3898 }
3899 i += 8U;
3900 }
3901
3902 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
3903 {
3904 /* Clear all the static flags */
3905 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3906 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
3907 hmmc->State = HAL_MMC_STATE_READY;
3908 return HAL_TIMEOUT;
3909 }
3910 }
3911
3912 /* Get error state */
3913 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
3914 {
3915 /* Clear all the static flags */
3916 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3917 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
3918 hmmc->State = HAL_MMC_STATE_READY;
3919 return HAL_ERROR;
3920 }
3921 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
3922 {
3923 /* Clear all the static flags */
3924 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3925 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
3926 hmmc->State = HAL_MMC_STATE_READY;
3927 return HAL_ERROR;
3928 }
3929 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
3930 {
3931 /* Clear all the static flags */
3932 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3933 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
3934 hmmc->State = HAL_MMC_STATE_READY;
3935 return HAL_ERROR;
3936 }
3937 else
3938 {
3939 /* Nothing to do */
3940 }
3941
3942 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3943 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
3944 if (errorstate != HAL_MMC_ERROR_NONE)
3945 {
3946 hmmc->ErrorCode |= errorstate;
3947 }
3948
3949 /* Clear all the static flags */
3950 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
3951
3952 hmmc->State = HAL_MMC_STATE_READY;
3953
3954 return HAL_OK;
3955}
3956
3957/**
3958 * @brief Wrap up reading in non-blocking mode.
3959 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
3960 * the configuration information.
3961 * @retval None
3962 */
3963static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
3964{
3965 uint32_t count;
3966 uint32_t data;
3967 uint8_t *tmp;
3968
3969 tmp = hmmc->pRxBuffPtr;
3970
3971 if (hmmc->RxXferSize >= SDMMC_FIFO_SIZE)
3972 {
3973 /* Read data from SDMMC Rx FIFO */
3974 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
3975 {
3976 data = SDMMC_ReadFIFO(hmmc->Instance);
3977 *tmp = (uint8_t)(data & 0xFFU);
3978 tmp++;
3979 *tmp = (uint8_t)((data >> 8U) & 0xFFU);
3980 tmp++;
3981 *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3982 tmp++;
3983 *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3984 tmp++;
3985 }
3986
3987 hmmc->pRxBuffPtr = tmp;
3988 hmmc->RxXferSize -= SDMMC_FIFO_SIZE;
3989 }
3990}
3991
3992/**
3993 * @brief Wrap up writing in non-blocking mode.
3994 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
3995 * the configuration information.
3996 * @retval None
3997 */
3998static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
3999{
4000 uint32_t count;
4001 uint32_t data;
4002 const uint8_t *tmp;
4003
4004 tmp = hmmc->pTxBuffPtr;
4005
4006 if (hmmc->TxXferSize >= SDMMC_FIFO_SIZE)
4007 {
4008 /* Write data to SDMMC Tx FIFO */
4009 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4010 {
4011 data = (uint32_t)(*tmp);
4012 tmp++;
4013 data |= ((uint32_t)(*tmp) << 8U);
4014 tmp++;
4015 data |= ((uint32_t)(*tmp) << 16U);
4016 tmp++;
4017 data |= ((uint32_t)(*tmp) << 24U);
4018 tmp++;
4019 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
4020 }
4021
4022 hmmc->pTxBuffPtr = tmp;
4023 hmmc->TxXferSize -= SDMMC_FIFO_SIZE;
4024 }
4025}
4026
4027/**
4028 * @brief Switches the MMC card to high speed mode.
4029 * @param hmmc: MMC handle
4030 * @param state: State of high speed mode
4031 * @retval MMC Card error state
4032 */
4033static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state)
4034{
4035 uint32_t errorstate = HAL_MMC_ERROR_NONE;
4036 uint32_t response = 0U;
4037 uint32_t count;
4038 uint32_t sdmmc_clk;
4039 SDMMC_InitTypeDef Init = {0U};
4040
4041 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) && (state == DISABLE))
4042 {
4043 errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_DEFAULT);
4044 if (errorstate == HAL_MMC_ERROR_NONE)
4045 {
4046 /* Index : 185 - Value : 0 */
4047 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90000U);
4048 }
4049 }
4050
4051 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) == 0U) && (state != DISABLE))
4052 {
4053 errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_HIGH);
4054 if (errorstate == HAL_MMC_ERROR_NONE)
4055 {
4056 /* Index : 185 - Value : 1 */
4057 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90100U);
4058 }
4059 }
4060
4061 if (errorstate == HAL_MMC_ERROR_NONE)
4062 {
4063 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4064 count = SDMMC_MAX_TRIAL;
4065 do
4066 {
4067 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4068 if (errorstate != HAL_MMC_ERROR_NONE)
4069 {
4070 break;
4071 }
4072
4073 /* Get command response */
4074 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4075 count--;
4076 } while (((response & 0x100U) == 0U) && (count != 0U));
4077
4078 /* Check the status after the switch command execution */
4079 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4080 {
4081 /* Check the bit SWITCH_ERROR of the device status */
4082 if ((response & 0x80U) != 0U)
4083 {
4084 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4085 }
4086 else
4087 {
4088 /* Configure high speed */
4089 Init.ClockEdge = hmmc->Init.ClockEdge;
4090 Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
4091 Init.BusWide = (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS);
4092 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
4093
4094 if (state == DISABLE)
4095 {
4096 Init.ClockDiv = hmmc->Init.ClockDiv;
4097 (void)SDMMC_Init(hmmc->Instance, Init);
4098
4099 CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
4100 }
4101 else
4102 {
4103 /* High Speed Clock should be less or equal to 52MHz*/
4105
4106 if (sdmmc_clk == 0U)
4107 {
4108 errorstate = SDMMC_ERROR_INVALID_PARAMETER;
4109 }
4110 else
4111 {
4112 if (sdmmc_clk <= MMC_HIGH_SPEED_FREQ)
4113 {
4114 Init.ClockDiv = 0;
4115 }
4116 else
4117 {
4118 Init.ClockDiv = (sdmmc_clk / (2U * MMC_HIGH_SPEED_FREQ)) + 1U;
4119 }
4120 (void)SDMMC_Init(hmmc->Instance, Init);
4121
4122 SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
4123 }
4124 }
4125 }
4126 }
4127 else if (count == 0U)
4128 {
4129 errorstate = SDMMC_ERROR_TIMEOUT;
4130 }
4131 else
4132 {
4133 /* Nothing to do */
4134 }
4135 }
4136
4137 return errorstate;
4138}
4139
4140/**
4141 * @brief Switches the MMC card to Double Data Rate (DDR) mode.
4142 * @param hmmc: MMC handle
4143 * @param state: State of DDR mode
4144 * @retval MMC Card error state
4145 */
4146static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state)
4147{
4148 uint32_t errorstate = HAL_MMC_ERROR_NONE;
4149 uint32_t response = 0U;
4150 uint32_t count;
4151
4152 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) && (state == DISABLE))
4153 {
4154 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4155 {
4156 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_HIGH);
4157 if (errorstate == HAL_MMC_ERROR_NONE)
4158 {
4159 /* Index : 183 - Value : 1 */
4160 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
4161 }
4162 }
4163 else
4164 {
4165 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_HIGH);
4166 if (errorstate == HAL_MMC_ERROR_NONE)
4167 {
4168 /* Index : 183 - Value : 2 */
4169 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
4170 }
4171 }
4172 }
4173
4174 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U) && (state != DISABLE))
4175 {
4176 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4177 {
4178 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_DDR);
4179 if (errorstate == HAL_MMC_ERROR_NONE)
4180 {
4181 /* Index : 183 - Value : 5 */
4182 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70500U);
4183 }
4184 }
4185 else
4186 {
4187 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_DDR);
4188 if (errorstate == HAL_MMC_ERROR_NONE)
4189 {
4190 /* Index : 183 - Value : 6 */
4191 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70600U);
4192 }
4193 }
4194 }
4195
4196 if (errorstate == HAL_MMC_ERROR_NONE)
4197 {
4198 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4199 count = SDMMC_MAX_TRIAL;
4200 do
4201 {
4202 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4203 if (errorstate != HAL_MMC_ERROR_NONE)
4204 {
4205 break;
4206 }
4207
4208 /* Get command response */
4209 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4210 count--;
4211 } while (((response & 0x100U) == 0U) && (count != 0U));
4212
4213 /* Check the status after the switch command execution */
4214 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4215 {
4216 /* Check the bit SWITCH_ERROR of the device status */
4217 if ((response & 0x80U) != 0U)
4218 {
4219 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4220 }
4221 else
4222 {
4223 /* Configure DDR mode */
4224 if (state == DISABLE)
4225 {
4226 CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4227 }
4228 else
4229 {
4230 SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4231 }
4232 }
4233 }
4234 else if (count == 0U)
4235 {
4236 errorstate = SDMMC_ERROR_TIMEOUT;
4237 }
4238 else
4239 {
4240 /* Nothing to do */
4241 }
4242 }
4243
4244 return errorstate;
4245}
4246
4247/**
4248 * @brief Update the power class of the device.
4249 * @param hmmc MMC handle
4250 * @param Wide Wide of MMC bus
4251 * @param Speed Speed of the MMC bus
4252 * @retval MMC Card error state
4253 */
4254static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed)
4255{
4256 uint32_t count;
4257 uint32_t response = 0U;
4258 uint32_t errorstate = HAL_MMC_ERROR_NONE;
4259 uint32_t power_class;
4260 uint32_t supported_pwr_class;
4261
4262 if ((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B))
4263 {
4264 power_class = 0U; /* Default value after power-on or software reset */
4265
4266 /* Read the PowerClass field of the Extended CSD register */
4267 if (MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
4268 {
4269 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
4270 }
4271 else
4272 {
4273 power_class = ((power_class >> 24U) & 0x000000FFU);
4274 }
4275
4276 /* Get the supported PowerClass field of the Extended CSD register */
4277 if (Speed == SDMMC_SPEED_MODE_DDR)
4278 {
4279 /* Field PWR_CL_DDR_52_xxx [238 or 239] */
4280 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_DDR_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_DDR_52_POS) &
4281 0x000000FFU);
4282 }
4283 else if (Speed == SDMMC_SPEED_MODE_HIGH)
4284 {
4285 /* Field PWR_CL_52_xxx [200 or 202] */
4286 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_52_POS) &
4287 0x000000FFU);
4288 }
4289 else
4290 {
4291 /* Field PWR_CL_26_xxx [201 or 203] */
4292 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_26_POS) &
4293 0x000000FFU);
4294 }
4295
4296 if (errorstate == HAL_MMC_ERROR_NONE)
4297 {
4298 if (Wide == SDMMC_BUS_WIDE_8B)
4299 {
4300 /* Bit [7:4]: power class for 8-bits bus configuration - Bit [3:0]: power class for 4-bits bus configuration */
4301 supported_pwr_class = (supported_pwr_class >> 4U);
4302 }
4303
4304 if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
4305 {
4306 /* Need to change current power class */
4307 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
4308
4309 if (errorstate == HAL_MMC_ERROR_NONE)
4310 {
4311 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4312 count = SDMMC_MAX_TRIAL;
4313 do
4314 {
4315 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4316 if (errorstate != HAL_MMC_ERROR_NONE)
4317 {
4318 break;
4319 }
4320
4321 /* Get command response */
4322 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4323 count--;
4324 } while (((response & 0x100U) == 0U) && (count != 0U));
4325
4326 /* Check the status after the switch command execution */
4327 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4328 {
4329 /* Check the bit SWITCH_ERROR of the device status */
4330 if ((response & 0x80U) != 0U)
4331 {
4332 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4333 }
4334 }
4335 else if (count == 0U)
4336 {
4337 errorstate = SDMMC_ERROR_TIMEOUT;
4338 }
4339 else
4340 {
4341 /* Nothing to do */
4342 }
4343 }
4344 }
4345 }
4346 }
4347
4348 return errorstate;
4349}
4350
4351/**
4352 * @brief Used to select the partition.
4353 * @param hmmc: Pointer to MMC handle
4354 * @param Partition: Partition type
4355 * @retval HAL status
4356 */
4357HAL_StatusTypeDef HAL_MMC_SwitchPartition(MMC_HandleTypeDef *hmmc, HAL_MMC_PartitionTypeDef Partition)
4358{
4359 uint32_t errorstate;
4360 uint32_t response = 0U;
4361 uint32_t count;
4362 uint32_t tickstart = HAL_GetTick();
4363 uint32_t arg = Partition | 0x03B30000U;
4364
4365 /* Check the state of the driver */
4366 if (hmmc->State == HAL_MMC_STATE_READY)
4367 {
4368 /* Change State */
4369 hmmc->State = HAL_MMC_STATE_BUSY;
4370
4371 /* Index : 179 - Value : partition */
4372 errorstate = SDMMC_CmdSwitch(hmmc->Instance, arg);
4373 if (errorstate == HAL_MMC_ERROR_NONE)
4374 {
4375 /* Wait that the device is ready by checking the D0 line */
4376 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
4377 {
4378 if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
4379 {
4380 errorstate = HAL_MMC_ERROR_TIMEOUT;
4381 }
4382 }
4383
4384 /* Clear the flag corresponding to end D0 bus line */
4385 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
4386
4387 if (errorstate == HAL_MMC_ERROR_NONE)
4388 {
4389 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4390 count = SDMMC_MAX_TRIAL;
4391 do
4392 {
4393 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4394 if (errorstate != HAL_MMC_ERROR_NONE)
4395 {
4396 break;
4397 }
4398
4399 /* Get command response */
4400 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4401 count--;
4402 } while (((response & 0x100U) == 0U) && (count != 0U));
4403
4404 /* Check the status after the switch command execution */
4405 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4406 {
4407 /* Check the bit SWITCH_ERROR of the device status */
4408 if ((response & 0x80U) != 0U)
4409 {
4410 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
4411 }
4412 }
4413 else if (count == 0U)
4414 {
4415 errorstate = SDMMC_ERROR_TIMEOUT;
4416 }
4417 else
4418 {
4419 /* Nothing to do */
4420 }
4421 }
4422 }
4423
4424 /* Change State */
4425 hmmc->State = HAL_MMC_STATE_READY;
4426
4427 /* Manage errors */
4428 if (errorstate != HAL_MMC_ERROR_NONE)
4429 {
4430 /* Clear all the static flags */
4431 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4432 hmmc->ErrorCode |= errorstate;
4433
4434 if (errorstate != HAL_MMC_ERROR_TIMEOUT)
4435 {
4436 return HAL_ERROR;
4437 }
4438 else
4439 {
4440 return HAL_TIMEOUT;
4441 }
4442 }
4443 else
4444 {
4445 return HAL_OK;
4446 }
4447 }
4448 else
4449 {
4450 return HAL_BUSY;
4451 }
4452}
4453
4454/**
4455 * @brief Allows to program the authentication key within the RPMB partition
4456 * @param hmmc: Pointer to MMC handle
4457 * @param pKey: pointer to the authentication key (32 bytes)
4458 * @param Timeout: Specify timeout value
4459 * @retval HAL status
4460 */
4461HAL_StatusTypeDef HAL_MMC_RPMB_ProgramAuthenticationKey(MMC_HandleTypeDef *hmmc, const uint8_t *pKey, uint32_t Timeout)
4462{
4463 SDMMC_DataInitTypeDef config;
4464 uint32_t errorstate;
4465 uint32_t tickstart = HAL_GetTick();
4466 uint32_t count;
4467 uint32_t byte_count = 0;
4468 uint32_t data;
4469 uint32_t dataremaining;
4470 uint8_t tail_pack[12] = {0};
4471 uint8_t zero_pack[4] = {0};
4472 const uint8_t *rtempbuff;
4473 uint8_t *tempbuff;
4474
4475 tail_pack[11] = 0x01;
4476
4477 if (NULL == pKey)
4478 {
4479 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
4480 return HAL_ERROR;
4481 }
4482
4483 if (hmmc->State == HAL_MMC_STATE_READY)
4484 {
4485 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
4486
4487 hmmc->State = HAL_MMC_STATE_BUSY;
4488
4489 /* Initialize data control register */
4490 hmmc->Instance->DCTRL = 0U;
4491
4492 errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x80000001U);
4493 if (errorstate != HAL_MMC_ERROR_NONE)
4494 {
4495 /* Clear all the static flags */
4496 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4497 hmmc->ErrorCode |= errorstate;
4498 hmmc->State = HAL_MMC_STATE_READY;
4499 return HAL_ERROR;
4500 }
4501
4502 /* Configure the MMC DPSM (Data Path State Machine) */
4503 config.DataTimeOut = SDMMC_DATATIMEOUT;
4504 config.DataLength = MMC_BLOCKSIZE;
4505 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4506 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
4507 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
4508 config.DPSM = SDMMC_DPSM_DISABLE;
4509 (void)SDMMC_ConfigData(hmmc->Instance, &config);
4510 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4511
4512 /* Write Blocks in Polling mode */
4513 {
4514 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
4515
4516 /* Write Multi Block command */
4517 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
4518 }
4519
4520 if (errorstate != HAL_MMC_ERROR_NONE)
4521 {
4522 /* Clear all the static flags */
4523 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4524 hmmc->ErrorCode |= errorstate;
4525 hmmc->State = HAL_MMC_STATE_READY;
4526 return HAL_ERROR;
4527 }
4528
4529 /* Write block(s) in polling mode */
4530 rtempbuff = zero_pack;
4531 dataremaining = config.DataLength;
4532 while (!__HAL_MMC_GET_FLAG(hmmc,
4533 SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4534 {
4535 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
4536 {
4537 /* Write data to SDMMC Tx FIFO */
4538 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4539 {
4540 data = (uint32_t)(*rtempbuff);
4541 rtempbuff++;
4542 byte_count++;
4543 data |= ((uint32_t)(*rtempbuff) << 8U);
4544 rtempbuff++;
4545 byte_count++;
4546 data |= ((uint32_t)(*rtempbuff) << 16U);
4547 rtempbuff++;
4548 byte_count++;
4549 data |= ((uint32_t)(*rtempbuff) << 24U);
4550 rtempbuff++;
4551 byte_count++;
4552 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
4553 if (byte_count < MMC_RPMB_KEYMAC_POSITION)
4554 {
4555 rtempbuff = zero_pack;
4556 }
4557 else if (byte_count == MMC_RPMB_KEYMAC_POSITION)
4558 {
4559 rtempbuff = pKey;
4560 }
4561 else if ((byte_count < MMC_RPMB_WRITE_COUNTER_POSITION) && \
4562 (byte_count >= MMC_RPMB_DATA_POSITION))
4563 {
4564 rtempbuff = zero_pack;
4565 }
4566 else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4567 {
4568 rtempbuff = tail_pack;
4569 }
4570 else
4571 {
4572 /* Nothing to do */
4573 }
4574
4575 }
4576 dataremaining -= SDMMC_FIFO_SIZE;
4577 }
4578
4579 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
4580 {
4581 /* Clear all the static flags */
4582 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4583 hmmc->ErrorCode |= errorstate;
4584 hmmc->State = HAL_MMC_STATE_READY;
4585 return HAL_TIMEOUT;
4586 }
4587 }
4588 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4589
4590 /* Read Response Packet */
4591 errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x00000001);
4592 if (errorstate != HAL_MMC_ERROR_NONE)
4593 {
4594 /* Clear all the static flags */
4595 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4596 hmmc->ErrorCode |= errorstate;
4597 hmmc->State = HAL_MMC_STATE_READY;
4598 return HAL_ERROR;
4599 }
4600
4601 /* Configure the MMC DPSM (Data Path State Machine) */
4602 config.DataTimeOut = SDMMC_DATATIMEOUT;
4603 config.DataLength = MMC_BLOCKSIZE;
4604 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4605 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
4606 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
4607 config.DPSM = SDMMC_DPSM_DISABLE;
4608 (void)SDMMC_ConfigData(hmmc->Instance, &config);
4609 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4610
4611 /* Write Blocks in Polling mode */
4612 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
4613
4614 /* Write Multi Block command */
4615 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
4616
4617 if (errorstate != HAL_MMC_ERROR_NONE)
4618 {
4619 /* Clear all the static flags */
4620 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4621 hmmc->ErrorCode |= errorstate;
4622 hmmc->State = HAL_MMC_STATE_READY;
4623 return HAL_ERROR;
4624 }
4625
4626 /* Clear all the static flags */
4627 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4628 /* Poll on SDMMC flags */
4629 tempbuff = zero_pack;
4630 byte_count = 0;
4631
4632 dataremaining = config.DataLength;
4633 while (!__HAL_MMC_GET_FLAG(hmmc,
4634 SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4635 {
4636 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
4637 {
4638 /* Read data from SDMMC Rx FIFO */
4639 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4640 {
4641 data = SDMMC_ReadFIFO(hmmc->Instance);
4642 *tempbuff = (uint8_t)(data & 0xFFU);
4643 tempbuff++;
4644 byte_count++;
4645 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
4646 tempbuff++;
4647 byte_count++;
4648 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
4649 tempbuff++;
4650 byte_count++;
4651 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
4652 tempbuff++;
4653 byte_count++;
4654 if (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION)
4655 {
4656 tempbuff = zero_pack;
4657 }
4658 else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4659 {
4660 tempbuff = tail_pack;
4661 }
4662 else
4663 {
4664 /* Nothing to do */
4665 }
4666 }
4667 dataremaining -= SDMMC_FIFO_SIZE;
4668 }
4669
4670 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
4671 {
4672 /* Clear all the static flags */
4673 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4674 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
4675 hmmc->State = HAL_MMC_STATE_READY;
4676 return HAL_TIMEOUT;
4677 }
4678 }
4679 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4680
4681 /* Get error state */
4682 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
4683 {
4684 /* Clear all the static flags */
4685 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4686 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
4687 hmmc->State = HAL_MMC_STATE_READY;
4688 return HAL_ERROR;
4689 }
4690 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
4691 {
4692 /* Clear all the static flags */
4693 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4694 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
4695 hmmc->State = HAL_MMC_STATE_READY;
4696 return HAL_ERROR;
4697 }
4698 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
4699 {
4700 /* Clear all the static flags */
4701 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4702 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
4703 hmmc->State = HAL_MMC_STATE_READY;
4704 return HAL_ERROR;
4705 }
4706 else
4707 {
4708 /* Nothing to do */
4709 }
4710
4711 /* Clear all the static flags */
4712 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4713
4714 hmmc->State = HAL_MMC_STATE_READY;
4715
4716 /* Check result of operation */
4717 if ((tail_pack[9] != 0x00U) || (tail_pack[10] != 0x01U))
4718 {
4719 hmmc->RPMBErrorCode |= tail_pack[9];
4720 return HAL_ERROR;
4721 }
4722
4723 return HAL_OK;
4724 }
4725 else
4726 {
4727 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
4728 return HAL_ERROR;
4729 }
4730}
4731
4732/**
4733 * @brief Allows to get the value of write counter within the RPMB partition.
4734 * @param hmmc: Pointer to MMC handle
4735 * @param pNonce: pointer to the value of nonce (16 bytes)
4736 * @param Timeout: Specify timeout value
4737 * @retval write counter value.
4738 */
4739uint32_t HAL_MMC_RPMB_GetWriteCounter(MMC_HandleTypeDef *hmmc, uint8_t *pNonce, uint32_t Timeout)
4740{
4741 SDMMC_DataInitTypeDef config;
4742 uint32_t errorstate;
4743 uint32_t tickstart = HAL_GetTick();
4744 uint32_t count;
4745 uint32_t byte_count = 0;
4746 uint32_t data;
4747 uint32_t dataremaining;
4748 uint8_t tail_pack[12] = {0};
4749 uint8_t zero_pack[4] = {0};
4750 uint8_t echo_nonce[16] = {0};
4751 uint8_t *tempbuff = zero_pack;
4752
4753 tail_pack[11] = 0x02;
4754
4755 if (NULL == pNonce)
4756 {
4757 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
4758 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4759 return 0;
4760 }
4761
4762 if (hmmc->State == HAL_MMC_STATE_READY)
4763 {
4764 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
4765 hmmc->State = HAL_MMC_STATE_BUSY;
4766
4767 /* Initialize data control register */
4768 hmmc->Instance->DCTRL = 0U;
4769
4770 errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x00000001U);
4771 if (errorstate != HAL_MMC_ERROR_NONE)
4772 {
4773 /* Clear all the static flags */
4774 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4775 hmmc->ErrorCode |= errorstate;
4776 hmmc->State = HAL_MMC_STATE_READY;
4777 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4778 return 0;
4779 }
4780
4781 /* Send Request Packet */
4782
4783 /* Configure the MMC DPSM (Data Path State Machine) */
4784 config.DataTimeOut = SDMMC_DATATIMEOUT;
4785 config.DataLength = MMC_BLOCKSIZE;
4786 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4787 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
4788 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
4789 config.DPSM = SDMMC_DPSM_DISABLE;
4790 (void)SDMMC_ConfigData(hmmc->Instance, &config);
4791 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4792
4793 /* Write Blocks in Polling mode */
4794 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
4795
4796 /* Write Multi Block command */
4797 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
4798
4799 if (errorstate != HAL_MMC_ERROR_NONE)
4800 {
4801 /* Clear all the static flags */
4802 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4803 hmmc->ErrorCode |= errorstate;
4804 hmmc->State = HAL_MMC_STATE_READY;
4805 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4806 return 0;
4807 }
4808
4809 /* Write block(s) in polling mode */
4810 dataremaining = config.DataLength;
4811 while (!__HAL_MMC_GET_FLAG(hmmc,
4812 SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4813 {
4814 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
4815 {
4816
4817 /* Write data to SDMMC Tx FIFO */
4818 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4819 {
4820 data = (uint32_t)(*tempbuff);
4821 tempbuff++;
4822 byte_count++;
4823 data |= ((uint32_t)(*tempbuff) << 8U);
4824 tempbuff++;
4825 byte_count++;
4826 data |= ((uint32_t)(*tempbuff) << 16U);
4827 tempbuff++;
4828 byte_count++;
4829 data |= ((uint32_t)(*tempbuff) << 24U);
4830 tempbuff++;
4831 byte_count++;
4832 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
4833 if (byte_count < MMC_RPMB_NONCE_POSITION)
4834 {
4835 tempbuff = zero_pack;
4836 }
4837 else if (byte_count == MMC_RPMB_NONCE_POSITION)
4838 {
4839 tempbuff = (uint8_t *)pNonce;
4840 }
4841 else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4842 {
4843 tempbuff = tail_pack;
4844 }
4845 else
4846 {
4847 /* Nothing to do */
4848 }
4849
4850 }
4851 dataremaining -= SDMMC_FIFO_SIZE;
4852 }
4853
4854 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
4855 {
4856 /* Clear all the static flags */
4857 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4858 hmmc->ErrorCode |= errorstate;
4859 hmmc->State = HAL_MMC_STATE_READY;
4860 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4861 return 0;
4862 }
4863 }
4864 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4865
4866 /* Read Response Packt */
4867 errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x00000001U);
4868 if (errorstate != HAL_MMC_ERROR_NONE)
4869 {
4870 /* Clear all the static flags */
4871 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4872 hmmc->ErrorCode |= errorstate;
4873 hmmc->State = HAL_MMC_STATE_READY;
4874 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4875 return 0;
4876 }
4877
4878 /* Configure the MMC DPSM (Data Path State Machine) */
4879 config.DataTimeOut = SDMMC_DATATIMEOUT;
4880 config.DataLength = MMC_BLOCKSIZE;
4881 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4882 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
4883 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
4884 config.DPSM = SDMMC_DPSM_DISABLE;
4885 (void)SDMMC_ConfigData(hmmc->Instance, &config);
4886 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4887
4888 /* Write Blocks in Polling mode */
4889 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
4890
4891 /* Write Multi Block command */
4892 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
4893
4894 if (errorstate != HAL_MMC_ERROR_NONE)
4895 {
4896 /* Clear all the static flags */
4897 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4898 hmmc->ErrorCode |= errorstate;
4899 hmmc->State = HAL_MMC_STATE_READY;
4900 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4901 return 0;
4902 }
4903
4904 /* Clear all the static flags */
4905 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4906 /* Poll on SDMMC flags */
4907 tempbuff = zero_pack;
4908
4909 byte_count = 0;
4910 dataremaining = config.DataLength;
4911 while (!__HAL_MMC_GET_FLAG(hmmc,
4912 SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4913 {
4914 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
4915 {
4916 /* Read data from SDMMC Rx FIFO */
4917 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4918 {
4919 data = SDMMC_ReadFIFO(hmmc->Instance);
4920 *tempbuff = (uint8_t)(data & 0xFFU);
4921 tempbuff++;
4922 byte_count++;
4923 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
4924 tempbuff++;
4925 byte_count++;
4926 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
4927 tempbuff++;
4928 byte_count++;
4929 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
4930 tempbuff++;
4931 byte_count++;
4932 if (byte_count < MMC_RPMB_NONCE_POSITION)
4933 {
4934 tempbuff = zero_pack;
4935 }
4936 else if (byte_count == MMC_RPMB_NONCE_POSITION)
4937 {
4938 tempbuff = echo_nonce;
4939 }
4940 else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4941 {
4942 tempbuff = tail_pack;
4943 }
4944 else
4945 {
4946 /* Nothing to do */
4947 }
4948 }
4949 dataremaining -= SDMMC_FIFO_SIZE;
4950 }
4951
4952 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
4953 {
4954 /* Clear all the static flags */
4955 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4956 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
4957 hmmc->State = HAL_MMC_STATE_READY;
4958 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4959 return 0;
4960 }
4961 }
4962 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4963
4964 /* Get error state */
4965 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
4966 {
4967 /* Clear all the static flags */
4968 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4969 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
4970 hmmc->State = HAL_MMC_STATE_READY;
4971 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4972 return 0;
4973 }
4974 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
4975 {
4976 /* Clear all the static flags */
4977 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4978 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
4979 hmmc->State = HAL_MMC_STATE_READY;
4980 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4981 return 0;
4982 }
4983 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
4984 {
4985 /* Clear all the static flags */
4986 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4987 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
4988 hmmc->State = HAL_MMC_STATE_READY;
4989 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4990 return 0;
4991 }
4992 else
4993 {
4994 /* Nothing to do */
4995 }
4996
4997 /* Clear all the static flags */
4998 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4999
5000 hmmc->State = HAL_MMC_STATE_READY;
5001
5002 for (uint8_t i = 0; i < 16U; i++)
5003 {
5004 if (pNonce[i] != echo_nonce[i])
5005 {
5006 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
5007 return 0;
5008 }
5009 }
5010
5011 return ((uint32_t)tail_pack[3] | ((uint32_t)tail_pack[2] << 8) | ((uint32_t)tail_pack[1] << 16) | \
5012 ((uint32_t)tail_pack[0] << 24));
5013 }
5014 else
5015 {
5016 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5017 hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
5018 return 0;
5019 }
5020}
5021
5022/**
5023 * @brief Allows to write block(s) to a specified address in the RPMB partition. The Data
5024 * transfer is managed by polling mode.
5025 * @param hmmc: Pointer to MMC handle
5026 * @param pData: Pointer to the buffer that will contain the data to transmit
5027 * @param BlockAdd: Block Address where data will be written
5028 * @param NumberOfBlocks: Number of blocks to write
5029 * @param pMAC: Pointer to the authentication MAC buffer
5030 * @param Timeout: Specify timeout value
5031 * @retval HAL status
5032 */
5033HAL_StatusTypeDef HAL_MMC_RPMB_WriteBlocks(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint16_t BlockAdd,
5034 uint16_t NumberOfBlocks, const uint8_t *pMAC, uint32_t Timeout)
5035{
5036
5037 SDMMC_DataInitTypeDef config;
5038 uint32_t errorstate;
5039 uint32_t tickstart = HAL_GetTick();
5040 uint32_t count;
5041 uint32_t byte_count = 0;
5042 uint32_t data;
5043 uint32_t dataremaining;
5044 uint8_t tail_pack[12] = {0};
5045 uint8_t zero_pack[4] = {0};
5046 uint8_t echo_nonce[16] = {0};
5047 const uint8_t local_nonce[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x01, 0x02,
5048 0x03, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x08
5049 };
5050 const uint8_t *rtempbuff;
5051 uint8_t *tempbuff;
5052 uint32_t arg = 0x80000000U;
5053 uint32_t offset = 0;
5054
5055 if ((NumberOfBlocks != 0x1U) && (NumberOfBlocks != 0x2U) && (NumberOfBlocks != 0x20U))
5056 {
5057 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
5058 return HAL_ERROR;
5059 }
5060
5061 if ((NULL == pData) || (NULL == pMAC))
5062 {
5063 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
5064 return HAL_ERROR;
5065 }
5066
5067 tail_pack[11] = 0x02;
5068
5069 if (hmmc->State == HAL_MMC_STATE_READY)
5070 {
5071 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
5072 hmmc->State = HAL_MMC_STATE_BUSY;
5073
5074 /* Initialize data control register */
5075 hmmc->Instance->DCTRL = 0U;
5076
5077 errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x00000001U);
5078 if (errorstate != HAL_MMC_ERROR_NONE)
5079 {
5080 /* Clear all the static flags */
5081 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5082 hmmc->ErrorCode |= errorstate;
5083 hmmc->State = HAL_MMC_STATE_READY;
5084 return HAL_ERROR;
5085 }
5086
5087 /* Send Request Packet */
5088
5089 /* Configure the MMC DPSM (Data Path State Machine) */
5090 config.DataTimeOut = SDMMC_DATATIMEOUT;
5091 config.DataLength = MMC_BLOCKSIZE;
5092 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5093 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
5094 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
5095 config.DPSM = SDMMC_DPSM_DISABLE;
5096 (void)SDMMC_ConfigData(hmmc->Instance, &config);
5097 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5098
5099 /* Write Blocks in Polling mode */
5100 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
5101
5102 /* Write Multi Block command */
5103 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
5104
5105 if (errorstate != HAL_MMC_ERROR_NONE)
5106 {
5107 /* Clear all the static flags */
5108 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5109 hmmc->ErrorCode |= errorstate;
5110 hmmc->State = HAL_MMC_STATE_READY;
5111 return HAL_ERROR;
5112 }
5113
5114 /* Write block(s) in polling mode */
5115 rtempbuff = zero_pack;
5116 dataremaining = config.DataLength;
5117 while (!__HAL_MMC_GET_FLAG(hmmc,
5118 SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5119 {
5120 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
5121 {
5122
5123 /* Write data to SDMMC Tx FIFO */
5124 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5125 {
5126 data = (uint32_t)(*rtempbuff);
5127 rtempbuff++;
5128 byte_count++;
5129 data |= ((uint32_t)(*rtempbuff) << 8U);
5130 rtempbuff++;
5131 byte_count++;
5132 data |= ((uint32_t)(*rtempbuff) << 16U);
5133 rtempbuff++;
5134 byte_count++;
5135 data |= ((uint32_t)(*rtempbuff) << 24U);
5136 rtempbuff++;
5137 byte_count++;
5138 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
5139 if (byte_count < MMC_RPMB_NONCE_POSITION)
5140 {
5141 rtempbuff = zero_pack;
5142 }
5143 else if (byte_count == MMC_RPMB_NONCE_POSITION)
5144 {
5145 rtempbuff = local_nonce;
5146 }
5147 else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5148 {
5149 rtempbuff = tail_pack;
5150 }
5151 else
5152 {
5153 /* Nothing to do */
5154 }
5155 }
5156 dataremaining -= SDMMC_FIFO_SIZE;
5157 }
5158
5159 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
5160 {
5161 /* Clear all the static flags */
5162 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5163 hmmc->ErrorCode |= errorstate;
5164 hmmc->State = HAL_MMC_STATE_READY;
5165 return HAL_TIMEOUT;
5166 }
5167 }
5168 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5169
5170 /* Read Response Packt */
5171 errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x00000001);
5172 if (errorstate != HAL_MMC_ERROR_NONE)
5173 {
5174 /* Clear all the static flags */
5175 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5176 hmmc->ErrorCode |= errorstate;
5177 hmmc->State = HAL_MMC_STATE_READY;
5178 return HAL_ERROR;
5179 }
5180
5181 /* Configure the MMC DPSM (Data Path State Machine) */
5182 config.DataTimeOut = SDMMC_DATATIMEOUT;
5183 config.DataLength = MMC_BLOCKSIZE;
5184 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5185 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
5186 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
5187 config.DPSM = SDMMC_DPSM_DISABLE;
5188 (void)SDMMC_ConfigData(hmmc->Instance, &config);
5189 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5190
5191 /* Write Blocks in Polling mode */
5192 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
5193
5194 /* Write Multi Block command */
5195 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
5196
5197 if (errorstate != HAL_MMC_ERROR_NONE)
5198 {
5199 /* Clear all the static flags */
5200 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5201 hmmc->ErrorCode |= errorstate;
5202 hmmc->State = HAL_MMC_STATE_READY;
5203 return HAL_ERROR;
5204 }
5205
5206 /* Clear all the static flags */
5207 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5208 /* Poll on SDMMC flags */
5209 tempbuff = zero_pack;
5210
5211 byte_count = 0;
5212 dataremaining = config.DataLength;
5213 while (!__HAL_MMC_GET_FLAG(hmmc,
5214 SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5215 {
5216 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
5217 {
5218 /* Read data from SDMMC Rx FIFO */
5219 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5220 {
5221 data = SDMMC_ReadFIFO(hmmc->Instance);
5222 *tempbuff = (uint8_t)(data & 0xFFU);
5223 tempbuff++;
5224 byte_count++;
5225 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
5226 tempbuff++;
5227 byte_count++;
5228 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
5229 tempbuff++;
5230 byte_count++;
5231 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
5232 tempbuff++;
5233 byte_count++;
5234 if (byte_count < MMC_RPMB_NONCE_POSITION)
5235 {
5236 tempbuff = zero_pack;
5237 }
5238 else if (byte_count == MMC_RPMB_NONCE_POSITION)
5239 {
5240 tempbuff = echo_nonce;
5241 }
5242 else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5243 {
5244 tempbuff = tail_pack;
5245 }
5246 else
5247 {
5248 /* Nothing to do */
5249 }
5250 }
5251 dataremaining -= SDMMC_FIFO_SIZE;
5252 }
5253
5254 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
5255 {
5256 /* Clear all the static flags */
5257 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5258 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
5259 hmmc->State = HAL_MMC_STATE_READY;
5260 return HAL_TIMEOUT;
5261 }
5262 }
5263 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5264
5265 /* Get error state */
5266 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
5267 {
5268 /* Clear all the static flags */
5269 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5270 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
5271 hmmc->State = HAL_MMC_STATE_READY;
5272 return HAL_ERROR;
5273 }
5274 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
5275 {
5276 /* Clear all the static flags */
5277 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5278 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
5279 hmmc->State = HAL_MMC_STATE_READY;
5280 return HAL_ERROR;
5281 }
5282 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
5283 {
5284 /* Clear all the static flags */
5285 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5286 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
5287 hmmc->State = HAL_MMC_STATE_READY;
5288 return HAL_ERROR;
5289 }
5290 else
5291 {
5292 /* Nothing to do */
5293 }
5294
5295 /* Clear all the static flags */
5296 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5297
5298 hmmc->State = HAL_MMC_STATE_READY;
5299
5300 for (uint8_t i = 0; i < 16U; i++)
5301 {
5302 if (local_nonce[i] != echo_nonce[i])
5303 {
5304 return HAL_ERROR;
5305 }
5306 }
5307 }
5308 else
5309 {
5310 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5311 return HAL_ERROR;
5312 }
5313 tail_pack[11] = 0x03;
5314 tail_pack[10] = 0x00;
5315 tail_pack[7] = (uint8_t)(NumberOfBlocks) & 0xFFU;
5316 tail_pack[6] = (uint8_t)(NumberOfBlocks >> 8) & 0xFFU;
5317 tail_pack[5] = (uint8_t)(BlockAdd) & 0xFFU;
5318 tail_pack[4] = (uint8_t)(BlockAdd >> 8) & 0xFFU;
5319
5320 rtempbuff = zero_pack;
5321 byte_count = 0;
5322 arg |= NumberOfBlocks;
5323
5324 if (hmmc->State == HAL_MMC_STATE_READY)
5325 {
5326 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
5327
5328
5329 hmmc->State = HAL_MMC_STATE_BUSY;
5330
5331 /* Initialize data control register */
5332 hmmc->Instance->DCTRL = 0U;
5333
5334 errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
5335 if (errorstate != HAL_MMC_ERROR_NONE)
5336 {
5337 /* Clear all the static flags */
5338 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5339 hmmc->ErrorCode |= errorstate;
5340 hmmc->State = HAL_MMC_STATE_READY;
5341 return HAL_ERROR;
5342 }
5343
5344 /* Send Request Packet */
5345 /* Configure the MMC DPSM (Data Path State Machine) */
5346 config.DataTimeOut = SDMMC_DATATIMEOUT;
5347 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
5348 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5349 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
5350 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
5351 config.DPSM = SDMMC_DPSM_DISABLE;
5352 (void)SDMMC_ConfigData(hmmc->Instance, &config);
5353 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5354
5355 /* Write Blocks in Polling mode */
5356
5357 {
5358 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
5359
5360 /* Write Multi Block command */
5361 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
5362 }
5363
5364 if (errorstate != HAL_MMC_ERROR_NONE)
5365 {
5366 /* Clear all the static flags */
5367 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5368 hmmc->ErrorCode |= errorstate;
5369 hmmc->State = HAL_MMC_STATE_READY;
5370 return HAL_ERROR;
5371 }
5372
5373
5374 /* Write block(s) in polling mode */
5375 dataremaining = config.DataLength;
5376 while (!__HAL_MMC_GET_FLAG(hmmc,
5377 SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5378 {
5379 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
5380 {
5381
5382 /* Write data to SDMMC Tx FIFO */
5383 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5384 {
5385 data = (uint32_t)(*rtempbuff);
5386 rtempbuff++;
5387 byte_count++;
5388 data |= ((uint32_t)(*rtempbuff) << 8U);
5389 rtempbuff++;
5390 byte_count++;
5391 data |= ((uint32_t)(*rtempbuff) << 16U);
5392 rtempbuff++;
5393 byte_count++;
5394 data |= ((uint32_t)(*rtempbuff) << 24U);
5395 rtempbuff++;
5396 byte_count++;
5397 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
5398 if (byte_count == MMC_RPMB_KEYMAC_POSITION)
5399 {
5400 rtempbuff = pMAC;
5401 }
5402 if (byte_count == MMC_RPMB_DATA_POSITION)
5403 {
5404 rtempbuff = &pData[offset];
5405 }
5406 if ((byte_count >= MMC_RPMB_NONCE_POSITION) && \
5407 (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION))
5408 {
5409 rtempbuff = zero_pack;
5410 }
5411 if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5412 {
5413 rtempbuff = tail_pack;
5414 }
5415 else if (byte_count == MMC_BLOCKSIZE)
5416 {
5417 offset += (uint32_t)256U;
5418 byte_count = 0;
5419 }
5420 else
5421 {
5422 /* Nothing to do */
5423 }
5424 }
5425 dataremaining -= SDMMC_FIFO_SIZE;
5426 }
5427
5428 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
5429 {
5430 /* Clear all the static flags */
5431 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5432 hmmc->ErrorCode |= errorstate;
5433 hmmc->State = HAL_MMC_STATE_READY;
5434 return HAL_TIMEOUT;
5435 }
5436 }
5437 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5438
5439 /* Response Packet */
5440
5441 errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
5442 if (errorstate != HAL_MMC_ERROR_NONE)
5443 {
5444 /* Clear all the static flags */
5445 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5446 hmmc->ErrorCode |= errorstate;
5447 hmmc->State = HAL_MMC_STATE_READY;
5448 return HAL_ERROR;
5449 }
5450
5451 /* Configure the MMC DPSM (Data Path State Machine) */
5452 config.DataTimeOut = SDMMC_DATATIMEOUT;
5453 config.DataLength = MMC_BLOCKSIZE;
5454 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5455 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
5456 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
5457 config.DPSM = SDMMC_DPSM_DISABLE;
5458 (void)SDMMC_ConfigData(hmmc->Instance, &config);
5459 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5460
5461 /* Write Blocks in Polling mode */
5462
5463 {
5464 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
5465
5466 /* Write Multi Block command */
5467 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
5468 }
5469
5470 if (errorstate != HAL_MMC_ERROR_NONE)
5471 {
5472 /* Clear all the static flags */
5473 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5474 hmmc->ErrorCode |= errorstate;
5475 hmmc->State = HAL_MMC_STATE_READY;
5476 return HAL_ERROR;
5477 }
5478
5479
5480 /* Clear all the static flags */
5481 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5482 /* Poll on SDMMC flags */
5483 tempbuff = zero_pack;
5484 byte_count = 0;
5485 dataremaining = config.DataLength;
5486 while (!__HAL_MMC_GET_FLAG(hmmc,
5487 SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5488 {
5489 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
5490 {
5491 /* Read data from SDMMC Rx FIFO */
5492 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5493 {
5494 data = SDMMC_ReadFIFO(hmmc->Instance);
5495 *tempbuff = (uint8_t)(data & 0xFFU);
5496 tempbuff++;
5497 byte_count++;
5498 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
5499 tempbuff++;
5500 byte_count++;
5501 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
5502 tempbuff++;
5503 byte_count++;
5504 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
5505 tempbuff++;
5506 byte_count++;
5507 if (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION)
5508 {
5509 tempbuff = zero_pack;
5510 }
5511 else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5512 {
5513 tempbuff = tail_pack;
5514 }
5515 else
5516 {
5517 /* Nothing to do */
5518 }
5519 }
5520 dataremaining -= SDMMC_FIFO_SIZE;
5521 }
5522
5523 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
5524 {
5525 /* Clear all the static flags */
5526 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5527 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
5528 hmmc->State = HAL_MMC_STATE_READY;
5529 return HAL_TIMEOUT;
5530 }
5531 }
5532 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5533
5534 /* Get error state */
5535 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
5536 {
5537 /* Clear all the static flags */
5538 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5539 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
5540 hmmc->State = HAL_MMC_STATE_READY;
5541 return HAL_ERROR;
5542 }
5543 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
5544 {
5545 /* Clear all the static flags */
5546 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5547 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
5548 hmmc->State = HAL_MMC_STATE_READY;
5549 return HAL_ERROR;
5550 }
5551 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
5552 {
5553 /* Clear all the static flags */
5554 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5555 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
5556 hmmc->State = HAL_MMC_STATE_READY;
5557 return HAL_ERROR;
5558 }
5559 else
5560 {
5561 /* Nothing to do */
5562 }
5563
5564 /* Clear all the static flags */
5565 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5566
5567 hmmc->State = HAL_MMC_STATE_READY;
5568
5569 /* Check result of operation */
5570 if (((tail_pack[9] & (uint8_t)0xFEU) != 0x00U) || (tail_pack[10] != 0x03U))
5571 {
5572 hmmc->RPMBErrorCode |= tail_pack[9];
5573 return HAL_ERROR;
5574 }
5575
5576 return HAL_OK;
5577 }
5578 else
5579 {
5580 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5581 return HAL_ERROR;
5582 }
5583}
5584
5585/**
5586 * @brief Allows to read block(s) to a specified address in the RPMB partition. The Data
5587 * transfer is managed by polling mode.
5588 * @param hmmc: Pointer to MMC handle
5589 * @param pData: Pointer to the buffer that will contain the data to transmit
5590 * @param BlockAdd: Block Address where data will be written
5591 * @param NumberOfBlocks: Number of blocks to write
5592 * @param pNonce: Pointer to the buffer that will contain the nonce to transmit
5593 * @param pMAC: Pointer to the authentication MAC buffer
5594 * @param Timeout: Specify timeout value
5595 * @retval HAL status
5596 */
5597HAL_StatusTypeDef HAL_MMC_RPMB_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint16_t BlockAdd,
5598 uint16_t NumberOfBlocks, const uint8_t *pNonce, uint8_t *pMAC,
5599 uint32_t Timeout)
5600{
5601 SDMMC_DataInitTypeDef config;
5602 uint32_t errorstate;
5603 uint32_t tickstart = HAL_GetTick();
5604 uint32_t count;
5605 uint32_t byte_count = 0;
5606 uint32_t data;
5607 uint8_t tail_pack[12] = {0};
5608 uint8_t zero_pack[4] = {0};
5609 uint8_t echo_nonce[16] = {0};
5610 uint32_t dataremaining;
5611 const uint8_t *rtempbuff;
5612 uint8_t *tempbuff;
5613 uint32_t arg = 0;
5614 uint32_t offset = 0;
5615
5616 arg |= NumberOfBlocks;
5617
5618 tail_pack[11] = 0x04;
5619 tail_pack[10] = 0x00;
5620 tail_pack[7] = 0x00;
5621 tail_pack[6] = 0x00;
5622 tail_pack[5] = (uint8_t)(BlockAdd) & 0xFFU;
5623 tail_pack[4] = (uint8_t)(BlockAdd >> 8) & 0xFFU;
5624 tail_pack[3] = 0x00;
5625 tail_pack[2] = 0x00;
5626 tail_pack[1] = 0x00;
5627 tail_pack[0] = 0x00;
5628
5629 if (hmmc->State == HAL_MMC_STATE_READY)
5630 {
5631 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
5632 hmmc->State = HAL_MMC_STATE_BUSY;
5633
5634 /* Initialize data control register */
5635 hmmc->Instance->DCTRL = 0U;
5636
5637 errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 1);
5638 if (errorstate != HAL_MMC_ERROR_NONE)
5639 {
5640 /* Clear all the static flags */
5641 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5642 hmmc->ErrorCode |= errorstate;
5643 hmmc->State = HAL_MMC_STATE_READY;
5644 return HAL_ERROR;
5645 }
5646
5647 /* Send Request Packet */
5648
5649 /* Configure the MMC DPSM (Data Path State Machine) */
5650 config.DataTimeOut = SDMMC_DATATIMEOUT;
5651 config.DataLength = MMC_BLOCKSIZE;
5652 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5653 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
5654 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
5655 config.DPSM = SDMMC_DPSM_DISABLE;
5656 (void)SDMMC_ConfigData(hmmc->Instance, &config);
5657 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5658
5659 /* Write Blocks in Polling mode */
5660 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
5661
5662 /* Write Multi Block command */
5663 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
5664
5665 if (errorstate != HAL_MMC_ERROR_NONE)
5666 {
5667 /* Clear all the static flags */
5668 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5669 hmmc->ErrorCode |= errorstate;
5670 hmmc->State = HAL_MMC_STATE_READY;
5671 return HAL_ERROR;
5672 }
5673
5674 /* Write block(s) in polling mode */
5675 rtempbuff = zero_pack;
5676 dataremaining = config.DataLength;
5677 while (!__HAL_MMC_GET_FLAG(hmmc,
5678 SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5679 {
5680 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
5681 {
5682
5683 /* Write data to SDMMC Tx FIFO */
5684 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5685 {
5686 data = (uint32_t)(*rtempbuff);
5687 rtempbuff++;
5688 byte_count++;
5689 data |= ((uint32_t)(*rtempbuff) << 8U);
5690 rtempbuff++;
5691 byte_count++;
5692 data |= ((uint32_t)(*rtempbuff) << 16U);
5693 rtempbuff++;
5694 byte_count++;
5695 data |= ((uint32_t)(*rtempbuff) << 24U);
5696 rtempbuff++;
5697 byte_count++;
5698 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
5699 if (byte_count < MMC_RPMB_NONCE_POSITION)
5700 {
5701 rtempbuff = zero_pack;
5702 }
5703 else if (byte_count == MMC_RPMB_NONCE_POSITION)
5704 {
5705 rtempbuff = pNonce;
5706 }
5707 else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5708 {
5709 rtempbuff = tail_pack;
5710 }
5711 else
5712 {
5713 /* Nothing to do */
5714 }
5715 }
5716 dataremaining -= SDMMC_FIFO_SIZE;
5717 }
5718
5719 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
5720 {
5721 /* Clear all the static flags */
5722 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5723 hmmc->ErrorCode |= errorstate;
5724 hmmc->State = HAL_MMC_STATE_READY;
5725 return HAL_TIMEOUT;
5726 }
5727 }
5728 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5729
5730 /* Read Response Packet */
5731 errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
5732 if (errorstate != HAL_MMC_ERROR_NONE)
5733 {
5734 /* Clear all the static flags */
5735 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5736 hmmc->ErrorCode |= errorstate;
5737 hmmc->State = HAL_MMC_STATE_READY;
5738 return HAL_ERROR;
5739 }
5740
5741 /* Configure the MMC DPSM (Data Path State Machine) */
5742 config.DataTimeOut = SDMMC_DATATIMEOUT;
5743 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
5744 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5745 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
5746 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
5747 config.DPSM = SDMMC_DPSM_DISABLE;
5748 (void)SDMMC_ConfigData(hmmc->Instance, &config);
5749 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5750
5751 /* Write Blocks in Polling mode */
5752 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
5753
5754 /* Write Multi Block command */
5755 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
5756
5757 if (errorstate != HAL_MMC_ERROR_NONE)
5758 {
5759 /* Clear all the static flags */
5760 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5761 hmmc->ErrorCode |= errorstate;
5762 hmmc->State = HAL_MMC_STATE_READY;
5763 return HAL_ERROR;
5764 }
5765
5766 /* Clear all the static flags */
5767 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5768 /* Poll on SDMMC flags */
5769 tempbuff = zero_pack;
5770 byte_count = 0;
5771
5772 dataremaining = config.DataLength;
5773 while (!__HAL_MMC_GET_FLAG(hmmc,
5774 SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5775 {
5776 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
5777 {
5778 /* Read data from SDMMC Rx FIFO */
5779 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5780 {
5781 data = SDMMC_ReadFIFO(hmmc->Instance);
5782 *tempbuff = (uint8_t)(data & 0xFFU);
5783 tempbuff++;
5784 byte_count++;
5785 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
5786 tempbuff++;
5787 byte_count++;
5788 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
5789 tempbuff++;
5790 byte_count++;
5791 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
5792 tempbuff++;
5793 byte_count++;
5794 if (byte_count < MMC_RPMB_KEYMAC_POSITION)
5795 {
5796 tempbuff = zero_pack;
5797 }
5798 else if (byte_count == MMC_RPMB_KEYMAC_POSITION)
5799 {
5800 tempbuff = (uint8_t *)pMAC;
5801 }
5802 else if (byte_count == MMC_RPMB_DATA_POSITION)
5803 {
5804 tempbuff = &pData[offset];
5805 }
5806 else if (byte_count == MMC_RPMB_NONCE_POSITION)
5807 {
5808 tempbuff = echo_nonce;
5809 }
5810 else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5811 {
5812 tempbuff = tail_pack;
5813 }
5814 else if (byte_count == MMC_BLOCKSIZE)
5815 {
5816 byte_count = 0;
5817 offset += (uint32_t)256U;
5818 }
5819 else
5820 {
5821 /* Nothing to do */
5822 }
5823 }
5824 dataremaining -= SDMMC_FIFO_SIZE;
5825 }
5826
5827 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
5828 {
5829 /* Clear all the static flags */
5830 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5831 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
5832 hmmc->State = HAL_MMC_STATE_READY;
5833 return HAL_TIMEOUT;
5834 }
5835 }
5836 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5837
5838 /* Get error state */
5839 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
5840 {
5841 /* Clear all the static flags */
5842 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5843 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
5844 hmmc->State = HAL_MMC_STATE_READY;
5845 return HAL_ERROR;
5846 }
5847 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
5848 {
5849 /* Clear all the static flags */
5850 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5851 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
5852 hmmc->State = HAL_MMC_STATE_READY;
5853 return HAL_ERROR;
5854 }
5855 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
5856 {
5857 /* Clear all the static flags */
5858 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5859 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
5860 hmmc->State = HAL_MMC_STATE_READY;
5861 return HAL_ERROR;
5862 }
5863 else
5864 {
5865 /* Nothing to do */
5866 }
5867
5868 /* Clear all the static flags */
5869 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5870
5871 hmmc->State = HAL_MMC_STATE_READY;
5872
5873 for (uint8_t i = 0; i < 16U; i++)
5874 {
5875 if (pNonce[i] != echo_nonce[i])
5876 {
5877 return HAL_ERROR;
5878 }
5879 }
5880
5881 /* Check result of operation */
5882 if ((tail_pack[9] != 0x00U) || (tail_pack[10] != 0x04U))
5883 {
5884 hmmc->RPMBErrorCode |= tail_pack[9];
5885 return HAL_ERROR;
5886 }
5887
5888 return HAL_OK;
5889 }
5890 else
5891 {
5892 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5893 return HAL_ERROR;
5894 }
5895}
5896
5897
5898/**
5899 * @brief Read DMA Buffer 0 Transfer completed callbacks
5900 * @param hmmc: MMC handle
5901 * @retval None
5902 */
5903__weak void HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef *hmmc)
5904{
5905 /* Prevent unused argument(s) compilation warning */
5906 UNUSED(hmmc);
5907
5908 /* NOTE : This function should not be modified, when the callback is needed,
5909 the HAL_MMCEx_Read_DMADoubleBuf0CpltCallback can be implemented in the user file
5910 */
5911}
5912
5913/**
5914 * @brief Read DMA Buffer 1 Transfer completed callbacks
5915 * @param hmmc: MMC handle
5916 * @retval None
5917 */
5918__weak void HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef *hmmc)
5919{
5920 /* Prevent unused argument(s) compilation warning */
5921 UNUSED(hmmc);
5922
5923 /* NOTE : This function should not be modified, when the callback is needed,
5924 the HAL_MMCEx_Read_DMADoubleBuf1CpltCallback can be implemented in the user file
5925 */
5926}
5927
5928/**
5929 * @brief Write DMA Buffer 0 Transfer completed callbacks
5930 * @param hmmc: MMC handle
5931 * @retval None
5932 */
5933__weak void HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef *hmmc)
5934{
5935 /* Prevent unused argument(s) compilation warning */
5936 UNUSED(hmmc);
5937
5938 /* NOTE : This function should not be modified, when the callback is needed,
5939 the HAL_MMCEx_Write_DMADoubleBuf0CpltCallback can be implemented in the user file
5940 */
5941}
5942
5943/**
5944 * @brief Write DMA Buffer 1 Transfer completed callbacks
5945 * @param hmmc: MMC handle
5946 * @retval None
5947 */
5948__weak void HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef *hmmc)
5949{
5950 /* Prevent unused argument(s) compilation warning */
5951 UNUSED(hmmc);
5952
5953 /* NOTE : This function should not be modified, when the callback is needed,
5954 the HAL_MMCEx_Write_DMADoubleBuf1CpltCallback can be implemented in the user file
5955 */
5956}
5957
5958/**
5959 * @}
5960 */
5961
5962#endif /* HAL_MMC_MODULE_ENABLED */
5963#endif /* SDMMC1 || SDMMC2 */
5964
5965/**
5966 * @}
5967 */
5968
5969/**
5970 * @}
5971 */
#define __IO
Defines 'read / write' permissions.
void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
Definition emmc_stm32.c:215
void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
Definition emmc_stm32.c:226
void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
Definition emmc_stm32.c:222
static ActuatorControllerState state
Definition main.cpp:57
#define HAL_DMA_ERROR_NONE
No error.
#define CLEAR_BIT(REG, BIT)
Definition stm32h7xx.h:209
#define SET_BIT(REG, BIT)
Definition stm32h7xx.h:207
#define POSITION_VAL(VAL)
Definition stm32h7xx.h:221
#define READ_BIT(REG, BIT)
Definition stm32h7xx.h:211
#define IS_SDMMC_ALL_INSTANCE(_INSTANCE_)
FunctionalState
Definition stm32h7xx.h:187
@ RESET
Definition stm32h7xx.h:182
@ ENABLE
Definition stm32h7xx.h:189
@ DISABLE
Definition stm32h7xx.h:188
void HAL_Delay(uint32_t Delay)
This function provides minimum delay (in milliseconds) based on variable incremented.
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
#define SDMMC_CLKCR_DDR
Data rate signaling selection.
#define SDMMC_CLKCR_WIDBUS
WIDBUS[1:0] bits (Wide bus mode enable bit).
#define SDMMC_CLKCR_BUSSPEED
Bus speed mode selection.
#define SDMMC_DCTRL_DTDIR
Data transfer direction selection.
#define SDMMC_CLKCR_WIDBUS_0
0x00004000
#define SDMMC_IDMA_IDMABACT
Uses buffer 1 when double buffer mode is selected.
#define SDMMC_CMD_CMDSTOP
CPSM Treats command as a Stop.
#define SDMMC_CLKCR_CLKDIV
Clock divide factor.
#define SDMMC_DCTRL_FIFORST
FIFO reset.
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint64_t PeriphClk)
#define RCC_PERIPHCLK_SDMMC
#define NULL
Definition usbd_def.h:44
static const idle_config_t config
Definition idle_task.c:17
size_type count(const key_type &key) const
Definition json.hpp:19264
This file contains all the functions prototypes for the HAL module driver.
#define assert_param(expr)
Uncomment the line below to expanse the "assert_param" macro in the HAL drivers code.
HAL_StatusTypeDef
HAL Status structures definition.
@ HAL_TIMEOUT
@ HAL_ERROR
@ HAL_OK
@ HAL_BUSY
#define UNUSED(x)
@ HAL_UNLOCKED
void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
MMC MSP Initialization This function configures the hardware resources used in this example.
void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
MMC MSP De-Initialization This function freeze the hardware resources used in this example.