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