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_ll_sdmmc.c
4
  * @author  MCD Application Team
5
  * @brief   SDIO Low Layer HAL module driver.
6
  *    
7
  *          This file provides firmware functions to manage the following
8
  *          functionalities of the SDIO peripheral:
9
  *           + Initialization/de-initialization functions
10
  *           + I/O operation functions
11
  *           + Peripheral Control functions
12
  *           + Peripheral State functions
13
  *        
14
  @verbatim
15
  ==============================================================================
16
                       ##### SDMMC peripheral features #####
17
  ==============================================================================        
18
    [..] The SD/SDMMC MMC card host interface (SDMMC) provides an interface between the APB2
19
         peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDMMC cards and CE-ATA
20
         devices.
21
 
22
    [..] The SDMMC features include the following:
23
         (+) Full compliance with MultiMedia Card System Specification Version 4.2. Card support
24
             for three different databus modes: 1-bit (default), 4-bit and 8-bit
25
         (+) Full compatibility with previous versions of MultiMedia Cards (forward compatibility)
26
         (+) Full compliance with SD Memory Card Specifications Version 2.0
27
         (+) Full compliance with SD I/O Card Specification Version 2.0: card support for two
28
             different data bus modes: 1-bit (default) and 4-bit
29
         (+) Full support of the CE-ATA features (full compliance with CE-ATA digital protocol
30
             Rev1.1)
31
         (+) Data transfer up to 48 MHz for the 8 bit mode
32
         (+) Data and command output enable signals to control external bidirectional drivers.
33
 
34
 
35
                           ##### How to use this driver #####
36
  ==============================================================================
37
    [..]
38
      This driver is a considered as a driver of service for external devices drivers
39
      that interfaces with the SDMMC peripheral.
40
      According to the device used (SD card/ MMC card / SDMMC card ...), a set of APIs
41
      is used in the device's driver to perform SDMMC operations and functionalities.
42
 
43
      This driver is almost transparent for the final user, it is only used to implement other
44
      functionalities of the external device.
45
 
46
    [..]
47
      (+) The SDIO peripheral uses two clock signals:
48
          (++) SDIO adapter clock (SDIOCLK = HCLK)
49
          (++) AHB bus clock (HCLK/2)
50
 
51
          -@@- PCLK2 and SDMMC_CK clock frequencies must respect the following condition:
52
               Frequency(PCLK2) >= (3 / 8 x Frequency(SDMMC_CK))
53
 
54
      (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDMMC
55
          peripheral.
56
 
57
      (+) Enable the Power ON State using the SDIO_PowerState_ON(SDIOx)
58
          function and disable it using the function SDIO_PowerState_OFF(SDIOx).
59
 
60
      (+) Enable/Disable the clock using the __SDIO_ENABLE()/__SDIO_DISABLE() macros.
61
 
62
      (+) Enable/Disable the peripheral interrupts using the macros __SDIO_ENABLE_IT(hsdio, IT)
63
          and __SDIO_DISABLE_IT(hsdio, IT) if you need to use interrupt mode.
64
 
65
      (+) When using the DMA mode
66
          (++) Configure the DMA in the MSP layer of the external device
67
          (++) Active the needed channel Request
68
          (++) Enable the DMA using __SDIO_DMA_ENABLE() macro or Disable it using the macro
69
               __SDIO_DMA_DISABLE().
70
 
71
      (+) To control the CPSM (Command Path State Machine) and send
72
          commands to the card use the SDIO_SendCommand(),
73
          SDIO_GetCommandResponse() and SDIO_GetResponse() functions. First, user has
74
          to fill the command structure (pointer to SDIO_CmdInitTypeDef) according
75
          to the selected command to be sent.
76
          The parameters that should be filled are:
77
           (++) Command Argument
78
           (++) Command Index
79
           (++) Command Response type
80
           (++) Command Wait
81
           (++) CPSM Status (Enable or Disable).
82
 
83
          -@@- To check if the command is well received, read the SDIO_CMDRESP
84
              register using the SDIO_GetCommandResponse().
85
              The SDMMC responses registers (SDIO_RESP1 to SDIO_RESP2), use the
86
              SDIO_GetResponse() function.
87
 
88
      (+) To control the DPSM (Data Path State Machine) and send/receive
89
           data to/from the card use the SDIO_ConfigData(), SDIO_GetDataCounter(),
90
          SDIO_ReadFIFO(), SDIO_WriteFIFO() and SDIO_GetFIFOCount() functions.
91
 
92
    *** Read Operations ***
93
    =======================
94
    [..]
95
      (#) First, user has to fill the data structure (pointer to
96
          SDIO_DataInitTypeDef) according to the selected data type to be received.
97
          The parameters that should be filled are:
98
           (++) Data TimeOut
99
           (++) Data Length
100
           (++) Data Block size
101
           (++) Data Transfer direction: should be from card (To SDMMC)
102
           (++) Data Transfer mode
103
           (++) DPSM Status (Enable or Disable)
104
 
105
      (#) Configure the SDMMC resources to receive the data from the card
106
          according to selected transfer mode (Refer to Step 8, 9 and 10).
107
 
108
      (#) Send the selected Read command (refer to step 11).
109
 
110
      (#) Use the SDIO flags/interrupts to check the transfer status.
111
 
112
    *** Write Operations ***
113
    ========================
114
    [..]
115
     (#) First, user has to fill the data structure (pointer to
116
         SDIO_DataInitTypeDef) according to the selected data type to be received.
117
         The parameters that should be filled are:
118
          (++) Data TimeOut
119
          (++) Data Length
120
          (++) Data Block size
121
          (++) Data Transfer direction:  should be to card (To CARD)
122
          (++) Data Transfer mode
123
          (++) DPSM Status (Enable or Disable)
124
 
125
     (#) Configure the SDMMC resources to send the data to the card according to
126
         selected transfer mode.
127
 
128
     (#) Send the selected Write command.
129
 
130
     (#) Use the SDIO flags/interrupts to check the transfer status.
131
 
132
    *** Command management operations ***
133
    =====================================
134
    [..]
135
     (#) The commands used for Read/Write//Erase operations are managed in
136
         separate functions.
137
         Each function allows to send the needed command with the related argument,
138
         then check the response.
139
         By the same approach, you could implement a command and check the response.
140
 
141
  @endverbatim
142
  ******************************************************************************
143
  * @attention
144
  *
145
  * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
146
  *
147
  * Redistribution and use in source and binary forms, with or without modification,
148
  * are permitted provided that the following conditions are met:
149
  *   1. Redistributions of source code must retain the above copyright notice,
150
  *      this list of conditions and the following disclaimer.
151
  *   2. Redistributions in binary form must reproduce the above copyright notice,
152
  *      this list of conditions and the following disclaimer in the documentation
153
  *      and/or other materials provided with the distribution.
154
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
155
  *      may be used to endorse or promote products derived from this software
156
  *      without specific prior written permission.
157
  *
158
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
159
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
160
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
161
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
162
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
163
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
164
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
165
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
166
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
167
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
168
  *
169
  ******************************************************************************
170
  */
171
 
172
/* Includes ------------------------------------------------------------------*/
173
#include "stm32f1xx_hal.h"
174
 
175
 
176
#if defined(STM32F103xE) || defined(STM32F103xG)
177
 
178
/** @addtogroup STM32F1xx_HAL_Driver
179
  * @{
180
  */
181
 
182
/** @defgroup SDMMC_LL SDMMC Low Layer
183
  * @brief Low layer module for SD
184
  * @{
185
  */
186
#if defined (HAL_SD_MODULE_ENABLED) || defined(HAL_MMC_MODULE_ENABLED)
187
 
188
/* Private typedef -----------------------------------------------------------*/
189
/* Private define ------------------------------------------------------------*/
190
/* Private macro -------------------------------------------------------------*/
191
/* Private variables ---------------------------------------------------------*/
192
/* Private function prototypes -----------------------------------------------*/
193
static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx);
194
static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout);
195
static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx);
196
static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx);
197
static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx);
198
static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA);
199
 
200
/* Exported functions --------------------------------------------------------*/
201
 
202
/** @defgroup SDMMC_LL_Exported_Functions SDMMC Low Layer Exported Functions
203
  * @{
204
  */
205
 
206
/** @defgroup HAL_SDMMC_LL_Group1 Initialization de-initialization functions
207
 *  @brief    Initialization and Configuration functions
208
 *
209
@verbatim    
210
 ===============================================================================
211
              ##### Initialization/de-initialization functions #####
212
 ===============================================================================
213
    [..]  This section provides functions allowing to:
214
 
215
@endverbatim
216
  * @{
217
  */
218
 
219
/**
220
  * @brief  Initializes the SDMMC according to the specified
221
  *         parameters in the SDMMC_InitTypeDef and create the associated handle.
222
  * @param  SDIOx: Pointer to SDMMC register base
223
  * @param  Init: SDMMC initialization structure  
224
  * @retval HAL status
225
  */
226
HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init)
227
{
228
  uint32_t tmpreg = 0U;
229
 
230
  /* Check the parameters */
231
  assert_param(IS_SDIO_ALL_INSTANCE(SDIOx));
232
  assert_param(IS_SDIO_CLOCK_EDGE(Init.ClockEdge));
233
  assert_param(IS_SDIO_CLOCK_BYPASS(Init.ClockBypass));
234
  assert_param(IS_SDIO_CLOCK_POWER_SAVE(Init.ClockPowerSave));
235
  assert_param(IS_SDIO_BUS_WIDE(Init.BusWide));
236
  assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl));
237
  assert_param(IS_SDIO_CLKDIV(Init.ClockDiv));
238
 
239
  /* Set SDMMC configuration parameters */
240
  tmpreg |= (Init.ClockEdge           |\
241
             Init.ClockBypass         |\
242
             Init.ClockPowerSave      |\
243
             Init.BusWide             |\
244
             Init.HardwareFlowControl |\
245
             Init.ClockDiv
246
             );
247
 
248
  /* Write to SDMMC CLKCR */
249
  MODIFY_REG(SDIOx->CLKCR, CLKCR_CLEAR_MASK, tmpreg);  
250
 
251
  return HAL_OK;
252
}
253
 
254
 
255
/**
256
  * @}
257
  */
258
 
259
/** @defgroup HAL_SDMMC_LL_Group2 IO operation functions
260
 *  @brief   Data transfers functions
261
 *
262
@verbatim  
263
 ===============================================================================
264
                      ##### I/O operation functions #####
265
 ===============================================================================  
266
    [..]
267
    This subsection provides a set of functions allowing to manage the SDMMC data
268
    transfers.
269
 
270
@endverbatim
271
  * @{
272
  */
273
 
274
/**
275
  * @brief  Read data (word) from Rx FIFO in blocking mode (polling)
276
  * @param  SDIOx: Pointer to SDMMC register base
277
  * @retval HAL status
278
  */
279
uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx)
280
{
281
  /* Read data from Rx FIFO */
282
  return (SDIOx->FIFO);
283
}
284
 
285
/**
286
  * @brief  Write data (word) to Tx FIFO in blocking mode (polling)
287
  * @param  SDIOx: Pointer to SDMMC register base
288
  * @param  pWriteData: pointer to data to write
289
  * @retval HAL status
290
  */
291
HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData)
292
{
293
  /* Write data to FIFO */
294
  SDIOx->FIFO = *pWriteData;
295
 
296
  return HAL_OK;
297
}
298
 
299
/**
300
  * @}
301
  */
302
 
303
/** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions
304
 *  @brief   management functions
305
 *
306
@verbatim  
307
 ===============================================================================
308
                      ##### Peripheral Control functions #####
309
 ===============================================================================  
310
    [..]
311
    This subsection provides a set of functions allowing to control the SDMMC data
312
    transfers.
313
 
314
@endverbatim
315
  * @{
316
  */
317
 
318
/**
319
  * @brief  Set SDMMC Power state to ON.
320
  * @param  SDIOx: Pointer to SDMMC register base
321
  * @retval HAL status
322
  */
323
HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx)
324
{  
325
  /* Set power state to ON */
326
  SDIOx->POWER = SDIO_POWER_PWRCTRL;
327
 
328
  return HAL_OK;
329
}
330
 
331
/**
332
  * @brief  Set SDMMC Power state to OFF.
333
  * @param  SDIOx: Pointer to SDMMC register base
334
  * @retval HAL status
335
  */
336
HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx)
337
{
338
  /* Set power state to OFF */
339
  SDIOx->POWER = 0x00000000U;
340
 
341
  return HAL_OK;
342
}
343
 
344
/**
345
  * @brief  Get SDMMC Power state.
346
  * @param  SDIOx: Pointer to SDMMC register base
347
  * @retval Power status of the controller. The returned value can be one of the
348
  *         following values:
349
  *            - 0x00: Power OFF
350
  *            - 0x02: Power UP
351
  *            - 0x03: Power ON
352
  */
353
uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx)  
354
{
355
  return (SDIOx->POWER & SDIO_POWER_PWRCTRL);
356
}
357
 
358
/**
359
  * @brief  Configure the SDMMC command path according to the specified parameters in
360
  *         SDIO_CmdInitTypeDef structure and send the command
361
  * @param  SDIOx: Pointer to SDMMC register base
362
  * @param  Command: pointer to a SDIO_CmdInitTypeDef structure that contains
363
  *         the configuration information for the SDMMC command
364
  * @retval HAL status
365
  */
366
HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command)
367
{
368
  uint32_t tmpreg = 0U;
369
 
370
  /* Check the parameters */
371
  assert_param(IS_SDIO_CMD_INDEX(Command->CmdIndex));
372
  assert_param(IS_SDIO_RESPONSE(Command->Response));
373
  assert_param(IS_SDIO_WAIT(Command->WaitForInterrupt));
374
  assert_param(IS_SDIO_CPSM(Command->CPSM));
375
 
376
  /* Set the SDMMC Argument value */
377
  SDIOx->ARG = Command->Argument;
378
 
379
  /* Set SDMMC command parameters */
380
  tmpreg |= (uint32_t)(Command->CmdIndex         |\
381
                       Command->Response         |\
382
                       Command->WaitForInterrupt |\
383
                       Command->CPSM);
384
 
385
  /* Write to SDMMC CMD register */
386
  MODIFY_REG(SDIOx->CMD, CMD_CLEAR_MASK, tmpreg);
387
 
388
  return HAL_OK;  
389
}
390
 
391
/**
392
  * @brief  Return the command index of last command for which response received
393
  * @param  SDIOx: Pointer to SDMMC register base
394
  * @retval Command index of the last command response received
395
  */
396
uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx)
397
{
398
  return (uint8_t)(SDIOx->RESPCMD);
399
}
400
 
401
 
402
/**
403
  * @brief  Return the response received from the card for the last command
404
  * @param  SDIOx: Pointer to SDMMC register base    
405
  * @param  Response: Specifies the SDMMC response register.
406
  *          This parameter can be one of the following values:
407
  *            @arg SDIO_RESP1: Response Register 1
408
  *            @arg SDIO_RESP2: Response Register 2
409
  *            @arg SDIO_RESP3: Response Register 3
410
  *            @arg SDIO_RESP4: Response Register 4  
411
  * @retval The Corresponding response register value
412
  */
413
uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response)
414
{
415
  __IO uint32_t tmp = 0U;
416
 
417
  /* Check the parameters */
418
  assert_param(IS_SDIO_RESP(Response));
419
 
420
  /* Get the response */
421
  tmp = (uint32_t)&(SDIOx->RESP1) + Response;
422
 
423
  return (*(__IO uint32_t *) tmp);
424
}  
425
 
426
/**
427
  * @brief  Configure the SDMMC data path according to the specified
428
  *         parameters in the SDIO_DataInitTypeDef.
429
  * @param  SDIOx: Pointer to SDMMC register base  
430
  * @param  Data : pointer to a SDIO_DataInitTypeDef structure
431
  *         that contains the configuration information for the SDMMC data.
432
  * @retval HAL status
433
  */
434
HAL_StatusTypeDef SDIO_ConfigData(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* Data)
435
{
436
  uint32_t tmpreg = 0U;
437
 
438
  /* Check the parameters */
439
  assert_param(IS_SDIO_DATA_LENGTH(Data->DataLength));
440
  assert_param(IS_SDIO_BLOCK_SIZE(Data->DataBlockSize));
441
  assert_param(IS_SDIO_TRANSFER_DIR(Data->TransferDir));
442
  assert_param(IS_SDIO_TRANSFER_MODE(Data->TransferMode));
443
  assert_param(IS_SDIO_DPSM(Data->DPSM));
444
 
445
  /* Set the SDMMC Data TimeOut value */
446
  SDIOx->DTIMER = Data->DataTimeOut;
447
 
448
  /* Set the SDMMC DataLength value */
449
  SDIOx->DLEN = Data->DataLength;
450
 
451
  /* Set the SDMMC data configuration parameters */
452
  tmpreg |= (uint32_t)(Data->DataBlockSize |\
453
                       Data->TransferDir   |\
454
                       Data->TransferMode  |\
455
                       Data->DPSM);
456
 
457
  /* Write to SDMMC DCTRL */
458
  MODIFY_REG(SDIOx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);
459
 
460
  return HAL_OK;
461
 
462
}
463
 
464
/**
465
  * @brief  Returns number of remaining data bytes to be transferred.
466
  * @param  SDIOx: Pointer to SDMMC register base
467
  * @retval Number of remaining data bytes to be transferred
468
  */
469
uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx)
470
{
471
  return (SDIOx->DCOUNT);
472
}
473
 
474
/**
475
  * @brief  Get the FIFO data
476
  * @param  SDIOx: Pointer to SDMMC register base
477
  * @retval Data received
478
  */
479
uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx)
480
{
481
  return (SDIOx->FIFO);
482
}
483
 
484
/**
485
  * @brief  Sets one of the two options of inserting read wait interval.
486
  * @param  SDIOx: Pointer to SDMMC register base  
487
  * @param  SDIO_ReadWaitMode: SDMMC Read Wait operation mode.
488
  *          This parameter can be:
489
  *            @arg SDIO_READ_WAIT_MODE_CLK: Read Wait control by stopping SDMMCCLK
490
  *            @arg SDIO_READ_WAIT_MODE_DATA2: Read Wait control using SDMMC_DATA2
491
  * @retval None
492
  */
493
HAL_StatusTypeDef SDIO_SetSDMMCReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode)
494
{
495
  /* Check the parameters */
496
  assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode));
497
 
498
  /* Set SDMMC read wait mode */
499
  MODIFY_REG(SDIOx->DCTRL, SDIO_DCTRL_RWMOD, SDIO_ReadWaitMode);
500
 
501
  return HAL_OK;  
502
}
503
 
504
/**
505
  * @}
506
  */
507
 
508
 
509
/** @defgroup HAL_SDMMC_LL_Group4 Command management functions
510
 *  @brief   Data transfers functions
511
 *
512
@verbatim  
513
 ===============================================================================
514
                   ##### Commands management functions #####
515
 ===============================================================================  
516
    [..]
517
    This subsection provides a set of functions allowing to manage the needed commands.
518
 
519
@endverbatim
520
  * @{
521
  */
522
 
523
/**
524
  * @brief  Send the Data Block Lenght command and check the response
525
  * @param  SDIOx: Pointer to SDMMC register base
526
  * @retval HAL status
527
  */
528
uint32_t SDMMC_CmdBlockLength(SDIO_TypeDef *SDIOx, uint32_t BlockSize)
529
{
530
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
531
  uint32_t errorstate = SDMMC_ERROR_NONE;
532
 
533
  /* Set Block Size for Card */
534
  sdmmc_cmdinit.Argument         = (uint32_t)BlockSize;
535
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SET_BLOCKLEN;
536
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
537
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
538
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
539
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
540
 
541
  /* Check for error conditions */
542
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SET_BLOCKLEN, SDIO_CMDTIMEOUT);
543
 
544
  return errorstate;
545
}
546
 
547
/**
548
  * @brief  Send the Read Single Block command and check the response
549
  * @param  SDIOx: Pointer to SDMMC register base
550
  * @retval HAL status
551
  */
552
uint32_t SDMMC_CmdReadSingleBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
553
{
554
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
555
  uint32_t errorstate = SDMMC_ERROR_NONE;
556
 
557
  /* Set Block Size for Card */
558
  sdmmc_cmdinit.Argument         = (uint32_t)ReadAdd;
559
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_READ_SINGLE_BLOCK;
560
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
561
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
562
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
563
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
564
 
565
  /* Check for error conditions */
566
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
567
 
568
  return errorstate;
569
}
570
 
571
/**
572
  * @brief  Send the Read Multi Block command and check the response
573
  * @param  SDIOx: Pointer to SDIO register base
574
  * @retval HAL status
575
  */
576
uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
577
{
578
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
579
  uint32_t errorstate = SDMMC_ERROR_NONE;
580
 
581
  /* Set Block Size for Card */
582
  sdmmc_cmdinit.Argument         = (uint32_t)ReadAdd;
583
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_READ_MULT_BLOCK;
584
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
585
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
586
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
587
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
588
 
589
  /* Check for error conditions */
590
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_MULT_BLOCK, SDIO_CMDTIMEOUT);
591
 
592
  return errorstate;
593
}
594
 
595
/**
596
  * @brief  Send the Write Single Block command and check the response
597
  * @param  SDIOx: Pointer to SDIO register base
598
  * @retval HAL status
599
  */
600
uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
601
{
602
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
603
  uint32_t errorstate = SDMMC_ERROR_NONE;
604
 
605
  /* Set Block Size for Card */
606
  sdmmc_cmdinit.Argument         = (uint32_t)WriteAdd;
607
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_WRITE_SINGLE_BLOCK;
608
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
609
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
610
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
611
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
612
 
613
  /* Check for error conditions */
614
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
615
 
616
  return errorstate;
617
}
618
 
619
/**
620
  * @brief  Send the Write Multi Block command and check the response
621
  * @param  SDIOx: Pointer to SDIO register base
622
  * @retval HAL status
623
  */
624
uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
625
{
626
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
627
  uint32_t errorstate = SDMMC_ERROR_NONE;
628
 
629
  /* Set Block Size for Card */
630
  sdmmc_cmdinit.Argument         = (uint32_t)WriteAdd;
631
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_WRITE_MULT_BLOCK;
632
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
633
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
634
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
635
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
636
 
637
  /* Check for error conditions */
638
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_MULT_BLOCK, SDIO_CMDTIMEOUT);
639
 
640
  return errorstate;
641
}
642
 
643
/**
644
  * @brief  Send the Start Address Erase command for SD and check the response
645
  * @param  SDIOx: Pointer to SDIO register base
646
  * @retval HAL status
647
  */
648
uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
649
{
650
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
651
  uint32_t errorstate = SDMMC_ERROR_NONE;
652
 
653
  /* Set Block Size for Card */
654
  sdmmc_cmdinit.Argument         = (uint32_t)StartAdd;
655
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_ERASE_GRP_START;
656
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
657
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
658
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
659
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
660
 
661
  /* Check for error conditions */
662
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
663
 
664
  return errorstate;
665
}
666
 
667
/**
668
  * @brief  Send the End Address Erase command for SD and check the response
669
  * @param  SDIOx: Pointer to SDIO register base
670
  * @retval HAL status
671
  */
672
uint32_t SDMMC_CmdSDEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
673
{
674
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
675
  uint32_t errorstate = SDMMC_ERROR_NONE;
676
 
677
  /* Set Block Size for Card */
678
  sdmmc_cmdinit.Argument         = (uint32_t)EndAdd;
679
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_ERASE_GRP_END;
680
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
681
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
682
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
683
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
684
 
685
  /* Check for error conditions */
686
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
687
 
688
  return errorstate;
689
}
690
 
691
/**
692
  * @brief  Send the Start Address Erase command and check the response
693
  * @param  SDIOx: Pointer to SDIO register base
694
  * @retval HAL status
695
  */
696
uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
697
{
698
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
699
  uint32_t errorstate = SDMMC_ERROR_NONE;
700
 
701
  /* Set Block Size for Card */
702
  sdmmc_cmdinit.Argument         = (uint32_t)StartAdd;
703
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ERASE_GRP_START;
704
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
705
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
706
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
707
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
708
 
709
  /* Check for error conditions */
710
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
711
 
712
  return errorstate;
713
}
714
 
715
/**
716
  * @brief  Send the End Address Erase command and check the response
717
  * @param  SDIOx: Pointer to SDIO register base
718
  * @retval HAL status
719
  */
720
uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
721
{
722
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
723
  uint32_t errorstate = SDMMC_ERROR_NONE;
724
 
725
  /* Set Block Size for Card */
726
  sdmmc_cmdinit.Argument         = (uint32_t)EndAdd;
727
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ERASE_GRP_END;
728
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
729
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
730
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
731
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
732
 
733
  /* Check for error conditions */
734
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
735
 
736
  return errorstate;
737
}
738
 
739
/**
740
  * @brief  Send the Erase command and check the response
741
  * @param  SDIOx: Pointer to SDIO register base
742
  * @retval HAL status
743
  */
744
uint32_t SDMMC_CmdErase(SDIO_TypeDef *SDIOx)
745
{
746
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
747
  uint32_t errorstate = SDMMC_ERROR_NONE;
748
 
749
  /* Set Block Size for Card */
750
  sdmmc_cmdinit.Argument         = 0U;
751
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ERASE;
752
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
753
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
754
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
755
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
756
 
757
  /* Check for error conditions */
758
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE, SDIO_MAXERASETIMEOUT);
759
 
760
  return errorstate;
761
}
762
 
763
/**
764
  * @brief  Send the Stop Transfer command and check the response.
765
  * @param  SDIOx: Pointer to SDIO register base
766
  * @retval HAL status
767
  */
768
uint32_t SDMMC_CmdStopTransfer(SDIO_TypeDef *SDIOx)
769
{
770
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
771
  uint32_t errorstate = SDMMC_ERROR_NONE;
772
 
773
  /* Send CMD12 STOP_TRANSMISSION  */
774
  sdmmc_cmdinit.Argument         = 0U;
775
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_STOP_TRANSMISSION;
776
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
777
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
778
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
779
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
780
 
781
  /* Check for error conditions */
782
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_STOP_TRANSMISSION, 100000000U);
783
 
784
  return errorstate;
785
}
786
 
787
/**
788
  * @brief  Send the Select Deselect command and check the response.
789
  * @param  SDIOx: Pointer to SDIO register base
790
  * @param  addr: Address of the card to be selected  
791
  * @retval HAL status
792
  */
793
uint32_t SDMMC_CmdSelDesel(SDIO_TypeDef *SDIOx, uint64_t Addr)
794
{
795
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
796
  uint32_t errorstate = SDMMC_ERROR_NONE;
797
 
798
  /* Send CMD7 SDMMC_SEL_DESEL_CARD */
799
  sdmmc_cmdinit.Argument         = (uint32_t)Addr;
800
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEL_DESEL_CARD;
801
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
802
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
803
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
804
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
805
 
806
  /* Check for error conditions */
807
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEL_DESEL_CARD, SDIO_CMDTIMEOUT);
808
 
809
  return errorstate;
810
}
811
 
812
/**
813
  * @brief  Send the Go Idle State command and check the response.
814
  * @param  SDIOx: Pointer to SDIO register base
815
  * @retval HAL status
816
  */
817
uint32_t SDMMC_CmdGoIdleState(SDIO_TypeDef *SDIOx)
818
{
819
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
820
  uint32_t errorstate = SDMMC_ERROR_NONE;
821
 
822
  sdmmc_cmdinit.Argument         = 0U;
823
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_GO_IDLE_STATE;
824
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_NO;
825
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
826
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
827
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
828
 
829
  /* Check for error conditions */
830
  errorstate = SDMMC_GetCmdError(SDIOx);
831
 
832
  return errorstate;
833
}
834
 
835
/**
836
  * @brief  Send the Operating Condition command and check the response.
837
  * @param  SDIOx: Pointer to SDIO register base
838
  * @retval HAL status
839
  */
840
uint32_t SDMMC_CmdOperCond(SDIO_TypeDef *SDIOx)
841
{
842
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
843
  uint32_t errorstate = SDMMC_ERROR_NONE;
844
 
845
  /* Send CMD8 to verify SD card interface operating condition */
846
  /* Argument: - [31:12]: Reserved (shall be set to '0')
847
  - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
848
  - [7:0]: Check Pattern (recommended 0xAA) */
849
  /* CMD Response: R7 */
850
  sdmmc_cmdinit.Argument         = SDMMC_CHECK_PATTERN;
851
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_HS_SEND_EXT_CSD;
852
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
853
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
854
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
855
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
856
 
857
  /* Check for error conditions */
858
  errorstate = SDMMC_GetCmdResp7(SDIOx);
859
 
860
  return errorstate;
861
}
862
 
863
/**
864
  * @brief  Send the Application command to verify that that the next command
865
  *         is an application specific com-mand rather than a standard command
866
  *         and check the response.
867
  * @param  SDIOx: Pointer to SDIO register base
868
  * @retval HAL status
869
  */
870
uint32_t SDMMC_CmdAppCommand(SDIO_TypeDef *SDIOx, uint32_t Argument)
871
{
872
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
873
  uint32_t errorstate = SDMMC_ERROR_NONE;
874
 
875
  sdmmc_cmdinit.Argument         = (uint32_t)Argument;
876
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_APP_CMD;
877
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
878
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
879
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
880
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
881
 
882
  /* Check for error conditions */
883
  /* If there is a HAL_ERROR, it is a MMC card, else
884
  it is a SD card: SD card 2.0 (voltage range mismatch)
885
     or SD card 1.x */
886
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_CMD, SDIO_CMDTIMEOUT);
887
 
888
  return errorstate;
889
}
890
 
891
/**
892
  * @brief  Send the command asking the accessed card to send its operating
893
  *         condition register (OCR)
894
  * @param  SDIOx: Pointer to SDIO register base
895
  * @retval HAL status
896
  */
897
uint32_t SDMMC_CmdAppOperCommand(SDIO_TypeDef *SDIOx, uint32_t SdType)
898
{
899
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
900
  uint32_t errorstate = SDMMC_ERROR_NONE;
901
 
902
  sdmmc_cmdinit.Argument         = SDMMC_VOLTAGE_WINDOW_SD | SdType;
903
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_APP_OP_COND;
904
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
905
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
906
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
907
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
908
 
909
  /* Check for error conditions */
910
  errorstate = SDMMC_GetCmdResp3(SDIOx);
911
 
912
  return errorstate;
913
}
914
 
915
/**
916
  * @brief  Send the Bus Width command and check the response.
917
  * @param  SDIOx: Pointer to SDIO register base
918
  * @retval HAL status
919
  */
920
uint32_t SDMMC_CmdBusWidth(SDIO_TypeDef *SDIOx, uint32_t BusWidth)
921
{
922
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
923
  uint32_t errorstate = SDMMC_ERROR_NONE;
924
 
925
  sdmmc_cmdinit.Argument         = (uint32_t)BusWidth;
926
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_APP_SD_SET_BUSWIDTH;
927
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
928
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
929
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
930
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
931
 
932
  /* Check for error conditions */
933
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDIO_CMDTIMEOUT);
934
 
935
  return errorstate;
936
}
937
 
938
/**
939
  * @brief  Send the Send SCR command and check the response.
940
  * @param  SDIOx: Pointer to SDMMC register base
941
  * @retval HAL status
942
  */
943
uint32_t SDMMC_CmdSendSCR(SDIO_TypeDef *SDIOx)
944
{
945
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
946
  uint32_t errorstate = SDMMC_ERROR_NONE;
947
 
948
  /* Send CMD51 SD_APP_SEND_SCR */
949
  sdmmc_cmdinit.Argument         = 0U;
950
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_APP_SEND_SCR;
951
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
952
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
953
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
954
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
955
 
956
  /* Check for error conditions */
957
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_SEND_SCR, SDIO_CMDTIMEOUT);
958
 
959
  return errorstate;
960
}
961
 
962
/**
963
  * @brief  Send the Send CID command and check the response.
964
  * @param  SDIOx: Pointer to SDIO register base
965
  * @retval HAL status
966
  */
967
uint32_t SDMMC_CmdSendCID(SDIO_TypeDef *SDIOx)
968
{
969
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
970
  uint32_t errorstate = SDMMC_ERROR_NONE;
971
 
972
  /* Send CMD2 ALL_SEND_CID */
973
  sdmmc_cmdinit.Argument         = 0U;
974
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ALL_SEND_CID;
975
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_LONG;
976
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
977
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
978
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
979
 
980
  /* Check for error conditions */
981
  errorstate = SDMMC_GetCmdResp2(SDIOx);
982
 
983
  return errorstate;
984
}
985
 
986
/**
987
  * @brief  Send the Send CSD command and check the response.
988
  * @param  SDIOx: Pointer to SDIO register base
989
  * @retval HAL status
990
  */
991
uint32_t SDMMC_CmdSendCSD(SDIO_TypeDef *SDIOx, uint32_t Argument)
992
{
993
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
994
  uint32_t errorstate = SDMMC_ERROR_NONE;
995
 
996
  /* Send CMD9 SEND_CSD */
997
  sdmmc_cmdinit.Argument         = (uint32_t)Argument;
998
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEND_CSD;
999
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_LONG;
1000
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1001
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1002
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1003
 
1004
  /* Check for error conditions */
1005
  errorstate = SDMMC_GetCmdResp2(SDIOx);
1006
 
1007
  return errorstate;
1008
}
1009
 
1010
/**
1011
  * @brief  Send the Send CSD command and check the response.
1012
  * @param  SDIOx: Pointer to SDIO register base
1013
  * @retval HAL status
1014
  */
1015
uint32_t SDMMC_CmdSetRelAdd(SDIO_TypeDef *SDIOx, uint16_t *pRCA)
1016
{
1017
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1018
  uint32_t errorstate = SDMMC_ERROR_NONE;
1019
 
1020
  /* Send CMD3 SD_CMD_SET_REL_ADDR */
1021
  sdmmc_cmdinit.Argument         = 0U;
1022
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SET_REL_ADDR;
1023
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
1024
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1025
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1026
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1027
 
1028
  /* Check for error conditions */
1029
  errorstate = SDMMC_GetCmdResp6(SDIOx, SDMMC_CMD_SET_REL_ADDR, pRCA);
1030
 
1031
  return errorstate;
1032
}
1033
 
1034
/**
1035
  * @brief  Send the Status command and check the response.
1036
  * @param  SDIOx: Pointer to SDIO register base
1037
  * @retval HAL status
1038
  */
1039
uint32_t SDMMC_CmdSendStatus(SDIO_TypeDef *SDIOx, uint32_t Argument)
1040
{
1041
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1042
  uint32_t errorstate = SDMMC_ERROR_NONE;
1043
 
1044
  sdmmc_cmdinit.Argument         = (uint32_t)Argument;
1045
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEND_STATUS;
1046
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
1047
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1048
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1049
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1050
 
1051
  /* Check for error conditions */
1052
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEND_STATUS, SDIO_CMDTIMEOUT);
1053
 
1054
  return errorstate;
1055
}
1056
 
1057
/**
1058
  * @brief  Send the Status register command and check the response.
1059
  * @param  SDIOx: Pointer to SDIO register base
1060
  * @retval HAL status
1061
  */
1062
uint32_t SDMMC_CmdStatusRegister(SDIO_TypeDef *SDIOx)
1063
{
1064
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1065
  uint32_t errorstate = SDMMC_ERROR_NONE;
1066
 
1067
  sdmmc_cmdinit.Argument         = 0U;
1068
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_APP_STATUS;
1069
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
1070
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1071
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1072
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1073
 
1074
  /* Check for error conditions */
1075
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_STATUS, SDIO_CMDTIMEOUT);
1076
 
1077
  return errorstate;
1078
}
1079
 
1080
/**
1081
  * @brief  Sends host capacity support information and activates the card's
1082
  *         initialization process. Send SDMMC_CMD_SEND_OP_COND command
1083
  * @param  SDIOx: Pointer to SDIO register base
1084
  * @parame Argument: Argument used for the command
1085
  * @retval HAL status
1086
  */
1087
uint32_t SDMMC_CmdOpCondition(SDIO_TypeDef *SDIOx, uint32_t Argument)
1088
{
1089
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1090
  uint32_t errorstate = SDMMC_ERROR_NONE;
1091
 
1092
  sdmmc_cmdinit.Argument         = Argument;
1093
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEND_OP_COND;
1094
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
1095
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1096
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1097
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1098
 
1099
  /* Check for error conditions */
1100
  errorstate = SDMMC_GetCmdResp3(SDIOx);
1101
 
1102
  return errorstate;
1103
}
1104
 
1105
/**
1106
  * @brief  Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH comand
1107
  * @param  SDIOx: Pointer to SDIO register base
1108
  * @parame Argument: Argument used for the command
1109
  * @retval HAL status
1110
  */
1111
uint32_t SDMMC_CmdSwitch(SDIO_TypeDef *SDIOx, uint32_t Argument)
1112
{
1113
  SDIO_CmdInitTypeDef  sdmmc_cmdinit;
1114
  uint32_t errorstate = SDMMC_ERROR_NONE;
1115
 
1116
  sdmmc_cmdinit.Argument         = Argument;
1117
  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_HS_SWITCH;
1118
  sdmmc_cmdinit.Response         = SDIO_RESPONSE_SHORT;
1119
  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1120
  sdmmc_cmdinit.CPSM             = SDIO_CPSM_ENABLE;
1121
  SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1122
 
1123
  /* Check for error conditions */
1124
  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_HS_SWITCH, SDIO_CMDTIMEOUT);
1125
 
1126
  return errorstate;
1127
}
1128
 
1129
/**
1130
  * @}
1131
  */
1132
 
1133
/* Private function ----------------------------------------------------------*/  
1134
/** @addtogroup SD_Private_Functions
1135
  * @{
1136
  */
1137
 
1138
/**
1139
  * @brief  Checks for error conditions for CMD0.
1140
  * @param  hsd: SD handle
1141
  * @retval SD Card error state
1142
  */
1143
static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx)
1144
{
1145
  /* 8 is the number of required instructions cycles for the below loop statement.
1146
  The SDMMC_CMDTIMEOUT is expressed in ms */
1147
  register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1148
 
1149
  do
1150
  {
1151
    if (count-- == 0U)
1152
    {
1153
      return SDMMC_ERROR_TIMEOUT;
1154
    }
1155
 
1156
  }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDSENT));
1157
 
1158
  /* Clear all the static flags */
1159
  __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
1160
 
1161
  return SDMMC_ERROR_NONE;
1162
}
1163
 
1164
/**
1165
  * @brief  Checks for error conditions for R1 response.
1166
  * @param  hsd: SD handle
1167
  * @param  SD_CMD: The sent command index  
1168
  * @retval SD Card error state
1169
  */
1170
static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout)
1171
{
1172
  uint32_t response_r1;
1173
 
1174
  /* 8 is the number of required instructions cycles for the below loop statement.
1175
  The Timeout is expressed in ms */
1176
  register uint32_t count = Timeout * (SystemCoreClock / 8U /1000U);
1177
 
1178
  do
1179
  {
1180
    if (count-- == 0U)
1181
    {
1182
      return SDMMC_ERROR_TIMEOUT;
1183
    }
1184
 
1185
  }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
1186
 
1187
  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1188
  {
1189
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1190
 
1191
    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1192
  }
1193
  else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1194
  {
1195
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1196
 
1197
    return SDMMC_ERROR_CMD_CRC_FAIL;
1198
  }
1199
 
1200
  /* Check response received is of desired command */
1201
  if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
1202
  {
1203
    return SDMMC_ERROR_CMD_CRC_FAIL;
1204
  }
1205
 
1206
  /* Clear all the static flags */
1207
  __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
1208
 
1209
  /* We have received response, retrieve it for analysis  */
1210
  response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
1211
 
1212
  if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO)
1213
  {
1214
    return SDMMC_ERROR_NONE;
1215
  }
1216
  else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE)
1217
  {
1218
    return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
1219
  }
1220
  else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED)
1221
  {
1222
    return SDMMC_ERROR_ADDR_MISALIGNED;
1223
  }
1224
  else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR)
1225
  {
1226
    return SDMMC_ERROR_BLOCK_LEN_ERR;
1227
  }
1228
  else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR)
1229
  {
1230
    return SDMMC_ERROR_ERASE_SEQ_ERR;
1231
  }
1232
  else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM)
1233
  {
1234
    return SDMMC_ERROR_BAD_ERASE_PARAM;
1235
  }
1236
  else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION)
1237
  {
1238
    return SDMMC_ERROR_WRITE_PROT_VIOLATION;
1239
  }
1240
  else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED)
1241
  {
1242
    return SDMMC_ERROR_LOCK_UNLOCK_FAILED;
1243
  }
1244
  else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED)
1245
  {
1246
    return SDMMC_ERROR_COM_CRC_FAILED;
1247
  }
1248
  else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD)
1249
  {
1250
    return SDMMC_ERROR_ILLEGAL_CMD;
1251
  }
1252
  else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED)
1253
  {
1254
    return SDMMC_ERROR_CARD_ECC_FAILED;
1255
  }
1256
  else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR)
1257
  {
1258
    return SDMMC_ERROR_CC_ERR;
1259
  }
1260
  else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN)
1261
  {
1262
    return SDMMC_ERROR_STREAM_READ_UNDERRUN;
1263
  }
1264
  else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN)
1265
  {
1266
    return SDMMC_ERROR_STREAM_WRITE_OVERRUN;
1267
  }
1268
  else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE)
1269
  {
1270
    return SDMMC_ERROR_CID_CSD_OVERWRITE;
1271
  }
1272
  else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP)
1273
  {
1274
    return SDMMC_ERROR_WP_ERASE_SKIP;
1275
  }
1276
  else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED)
1277
  {
1278
    return SDMMC_ERROR_CARD_ECC_DISABLED;
1279
  }
1280
  else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET)
1281
  {
1282
    return SDMMC_ERROR_ERASE_RESET;
1283
  }
1284
  else if((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR)
1285
  {
1286
    return SDMMC_ERROR_AKE_SEQ_ERR;
1287
  }
1288
  else
1289
  {
1290
    return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1291
  }
1292
}
1293
 
1294
/**
1295
  * @brief  Checks for error conditions for R2 (CID or CSD) response.
1296
  * @param  hsd: SD handle
1297
  * @retval SD Card error state
1298
  */
1299
static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx)
1300
{
1301
  /* 8 is the number of required instructions cycles for the below loop statement.
1302
  The SDMMC_CMDTIMEOUT is expressed in ms */
1303
  register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1304
 
1305
  do
1306
  {
1307
    if (count-- == 0U)
1308
    {
1309
      return SDMMC_ERROR_TIMEOUT;
1310
    }
1311
 
1312
  }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
1313
 
1314
  if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1315
  {
1316
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1317
 
1318
    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1319
  }
1320
  else if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1321
  {
1322
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1323
 
1324
    return SDMMC_ERROR_CMD_CRC_FAIL;
1325
  }
1326
  else
1327
  {
1328
    /* No error flag set */
1329
    /* Clear all the static flags */
1330
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
1331
  }
1332
 
1333
  return SDMMC_ERROR_NONE;
1334
}
1335
 
1336
/**
1337
  * @brief  Checks for error conditions for R3 (OCR) response.
1338
  * @param  hsd: SD handle
1339
  * @retval SD Card error state
1340
  */
1341
static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx)
1342
{
1343
  /* 8 is the number of required instructions cycles for the below loop statement.
1344
  The SDMMC_CMDTIMEOUT is expressed in ms */
1345
  register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1346
 
1347
  do
1348
  {
1349
    if (count-- == 0U)
1350
    {
1351
      return SDMMC_ERROR_TIMEOUT;
1352
    }
1353
 
1354
  }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
1355
 
1356
  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1357
  {
1358
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1359
 
1360
    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1361
  }
1362
  else
1363
 
1364
  {  
1365
    /* Clear all the static flags */
1366
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
1367
  }
1368
 
1369
  return SDMMC_ERROR_NONE;
1370
}
1371
 
1372
/**
1373
  * @brief  Checks for error conditions for R6 (RCA) response.
1374
  * @param  hsd: SD handle
1375
  * @param  SD_CMD: The sent command index
1376
  * @param  pRCA: Pointer to the variable that will contain the SD card relative
1377
  *         address RCA  
1378
  * @retval SD Card error state
1379
  */
1380
static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA)
1381
{
1382
  uint32_t response_r1;
1383
 
1384
  /* 8 is the number of required instructions cycles for the below loop statement.
1385
  The SDMMC_CMDTIMEOUT is expressed in ms */
1386
  register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1387
 
1388
  do
1389
  {
1390
    if (count-- == 0U)
1391
    {
1392
      return SDMMC_ERROR_TIMEOUT;
1393
    }
1394
 
1395
  }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
1396
 
1397
  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1398
  {
1399
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1400
 
1401
    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1402
  }
1403
  else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1404
  {
1405
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1406
 
1407
    return SDMMC_ERROR_CMD_CRC_FAIL;
1408
  }
1409
 
1410
  /* Check response received is of desired command */
1411
  if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
1412
  {
1413
    return SDMMC_ERROR_CMD_CRC_FAIL;
1414
  }
1415
 
1416
  /* Clear all the static flags */
1417
  __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
1418
 
1419
  /* We have received response, retrieve it.  */
1420
  response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
1421
 
1422
  if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO)
1423
  {
1424
    *pRCA = (uint16_t) (response_r1 >> 16);
1425
 
1426
    return SDMMC_ERROR_NONE;
1427
  }
1428
  else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD)
1429
  {
1430
    return SDMMC_ERROR_ILLEGAL_CMD;
1431
  }
1432
  else if((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED)
1433
  {
1434
    return SDMMC_ERROR_COM_CRC_FAILED;
1435
  }
1436
  else
1437
  {
1438
    return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1439
  }
1440
}
1441
 
1442
/**
1443
  * @brief  Checks for error conditions for R7 response.
1444
  * @param  hsd: SD handle
1445
  * @retval SD Card error state
1446
  */
1447
static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx)
1448
{
1449
  /* 8 is the number of required instructions cycles for the below loop statement.
1450
  The SDIO_CMDTIMEOUT is expressed in ms */
1451
  register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1452
 
1453
  do
1454
  {
1455
    if (count-- == 0U)
1456
    {
1457
      return SDMMC_ERROR_TIMEOUT;
1458
    }
1459
 
1460
  }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
1461
 
1462
  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1463
  {
1464
    /* Card is SD V2.0 compliant */
1465
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CMDREND);
1466
 
1467
    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1468
  }
1469
 
1470
  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDREND))
1471
  {
1472
    /* Card is SD V2.0 compliant */
1473
    __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CMDREND);
1474
  }
1475
 
1476
  return SDMMC_ERROR_NONE;
1477
 
1478
}
1479
 
1480
/**
1481
  * @}
1482
  */
1483
 
1484
/**
1485
  * @}
1486
  */
1487
 
1488
#endif /* STM32F103xE || STM32F103xG */
1489
 
1490
#endif /* (HAL_SD_MODULE_ENABLED) || (HAL_MMC_MODULE_ENABLED) */
1491
 
1492
/**
1493
  * @}
1494
  */
1495
 
1496
/**
1497
  * @}
1498
  */
1499
 
1500
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/