Mercurial > public > ostc4
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>© 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****/ |