Subversion Repositories testOled

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