Subversion Repositories LedShow

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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