comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c @ 128:c78bcbd5deda FlipDisplay

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