Subversion Repositories AFRtranscoder

Rev

Details | Last modification | View Log | RSS feed

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