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