Subversion Repositories dashGPS

Rev

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