]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_STM32F7_STM32756G-EVAL/ST_Library/stm32f7xx_hal_sd.c
Update version number ready for V8.2.1 release.
[freertos] / FreeRTOS / Demo / CORTEX_M7_STM32F7_STM32756G-EVAL / ST_Library / stm32f7xx_hal_sd.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32f7xx_hal_sd.c\r
4   * @author  MCD Application Team\r
5   * @version V0.3.0\r
6   * @date    06-March-2015\r
7   * @brief   SD card HAL module driver.\r
8   *          This file provides firmware functions to manage the following \r
9   *          functionalities of the Secure Digital (SD) peripheral:\r
10   *           + Initialization and de-initialization functions\r
11   *           + IO operation functions\r
12   *           + Peripheral Control functions \r
13   *           + Peripheral State functions\r
14   *         \r
15   @verbatim\r
16   ==============================================================================\r
17                         ##### How to use this driver #####\r
18   ==============================================================================\r
19   [..]\r
20     This driver implements a high level communication layer for read and write from/to \r
21     this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by \r
22     the user in HAL_SD_MspInit() function (MSP layer).                             \r
23     Basically, the MSP layer configuration should be the same as we provide in the \r
24     examples.\r
25     You can easily tailor this configuration according to hardware resources.\r
26 \r
27   [..]\r
28     This driver is a generic layered driver for SDMMC memories which uses the HAL \r
29     SDMMC driver functions to interface with SD and uSD cards devices. \r
30     It is used as follows:\r
31  \r
32     (#)Initialize the SDMMC low level resources by implement the HAL_SD_MspInit() API:\r
33         (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE(); \r
34         (##) SDMMC pins configuration for SD card\r
35             (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();   \r
36             (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()\r
37                   and according to your pin assignment;\r
38         (##) DMA Configuration if you need to use DMA process (HAL_SD_ReadBlocks_DMA()\r
39              and HAL_SD_WriteBlocks_DMA() APIs).\r
40             (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE(); \r
41             (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled. \r
42         (##) NVIC configuration if you need to use interrupt process when using DMA transfer.\r
43             (+++) Configure the SDMMC and DMA interrupt priorities using functions\r
44                   HAL_NVIC_SetPriority(); DMA priority is superior to SDMMC's priority\r
45             (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()\r
46             (+++) SDMMC interrupts are managed using the macros __HAL_SD_SDMMC_ENABLE_IT() \r
47                   and __HAL_SD_SDMMC_DISABLE_IT() inside the communication process.\r
48             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_SD_SDMMC_GET_IT()\r
49                   and __HAL_SD_SDMMC_CLEAR_IT()\r
50     (#) At this stage, you can perform SD read/write/erase operations after SD card initialization  \r
51 \r
52          \r
53   *** SD Card Initialization and configuration ***\r
54   ================================================    \r
55   [..]\r
56     To initialize the SD Card, use the HAL_SD_Init() function.  It Initializes \r
57     the SD Card and put it into StandBy State (Ready for data transfer). \r
58     This function provide the following operations:\r
59   \r
60     (#) Apply the SD Card initialization process at 400KHz and check the SD Card \r
61         type (Standard Capacity or High Capacity). You can change or adapt this \r
62         frequency by adjusting the "ClockDiv" field. \r
63         The SD Card frequency (SDMMC_CK) is computed as follows:\r
64   \r
65            SDMMC_CK = SDMMCCLK / (ClockDiv + 2)\r
66   \r
67         In initialization mode and according to the SD Card standard, \r
68         make sure that the SDMMC_CK frequency doesn't exceed 400KHz.\r
69   \r
70     (#) Get the SD CID and CSD data. All these information are managed by the SDCardInfo \r
71         structure. This structure provide also ready computed SD Card capacity \r
72         and Block size.\r
73         \r
74         -@- These information are stored in SD handle structure in case of future use.  \r
75   \r
76     (#) Configure the SD Card Data transfer frequency. By Default, the card transfer \r
77         frequency is set to 24MHz. You can change or adapt this frequency by adjusting \r
78         the "ClockDiv" field.\r
79         In transfer mode and according to the SD Card standard, make sure that the \r
80         SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.\r
81         To be able to use a frequency higher than 24MHz, you should use the SDMMC \r
82         peripheral in bypass mode. Refer to the corresponding reference manual \r
83         for more details.\r
84   \r
85     (#) Select the corresponding SD Card according to the address read with the step 2.\r
86     \r
87     (#) Configure the SD Card in wide bus mode: 4-bits data.\r
88   \r
89   *** SD Card Read operation ***\r
90   ==============================\r
91   [..] \r
92     (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks(). \r
93         This function support only 512-bytes block length (the block size should be \r
94         chosen as 512 bytes).\r
95         You can choose either one block read operation or multiple block read operation \r
96         by adjusting the "NumberOfBlocks" parameter.\r
97 \r
98     (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA().\r
99         This function support only 512-bytes block length (the block size should be \r
100         chosen as 512 bytes).\r
101         You can choose either one block read operation or multiple block read operation \r
102         by adjusting the "NumberOfBlocks" parameter.\r
103         After this, you have to call the function HAL_SD_CheckReadOperation(), to insure\r
104         that the read transfer is done correctly in both DMA and SD sides.\r
105   \r
106   *** SD Card Write operation ***\r
107   =============================== \r
108   [..] \r
109     (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks(). \r
110         This function support only 512-bytes block length (the block size should be \r
111         chosen as 512 bytes).\r
112         You can choose either one block read operation or multiple block read operation \r
113         by adjusting the "NumberOfBlocks" parameter.\r
114 \r
115     (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA().\r
116         This function support only 512-bytes block length (the block size should be \r
117         chosen as 512 byte).\r
118         You can choose either one block read operation or multiple block read operation \r
119         by adjusting the "NumberOfBlocks" parameter.\r
120         After this, you have to call the function HAL_SD_CheckWriteOperation(), to insure\r
121         that the write transfer is done correctly in both DMA and SD sides.  \r
122   \r
123   *** SD card status ***\r
124   ====================== \r
125   [..]\r
126     (+) At any time, you can check the SD Card status and get the SD card state \r
127         by using the HAL_SD_GetStatus() function. This function checks first if the \r
128         SD card is still connected and then get the internal SD Card transfer state.     \r
129     (+) You can also get the SD card SD Status register by using the HAL_SD_SendSDStatus() \r
130         function.    \r
131 \r
132   *** SD HAL driver macros list ***\r
133   ==================================\r
134   [..]\r
135     Below the list of most used macros in SD HAL driver.\r
136        \r
137     (+) __HAL_SD_SDMMC_ENABLE : Enable the SD device\r
138     (+) __HAL_SD_SDMMC_DISABLE : Disable the SD device\r
139     (+) __HAL_SD_SDMMC_DMA_ENABLE: Enable the SDMMC DMA transfer\r
140     (+) __HAL_SD_SDMMC_DMA_DISABLE: Disable the SDMMC DMA transfer\r
141     (+) __HAL_SD_SDMMC_ENABLE_IT: Enable the SD device interrupt\r
142     (+) __HAL_SD_SDMMC_DISABLE_IT: Disable the SD device interrupt\r
143     (+) __HAL_SD_SDMMC_GET_FLAG:Check whether the specified SD flag is set or not\r
144     (+) __HAL_SD_SDMMC_CLEAR_FLAG: Clear the SD's pending flags\r
145       \r
146     (@) You can refer to the SD HAL driver header file for more useful macros \r
147       \r
148   @endverbatim\r
149   ******************************************************************************\r
150   * @attention\r
151   *\r
152   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>\r
153   *\r
154   * Redistribution and use in source and binary forms, with or without modification,\r
155   * are permitted provided that the following conditions are met:\r
156   *   1. Redistributions of source code must retain the above copyright notice,\r
157   *      this list of conditions and the following disclaimer.\r
158   *   2. Redistributions in binary form must reproduce the above copyright notice,\r
159   *      this list of conditions and the following disclaimer in the documentation\r
160   *      and/or other materials provided with the distribution.\r
161   *   3. Neither the name of STMicroelectronics nor the names of its contributors\r
162   *      may be used to endorse or promote products derived from this software\r
163   *      without specific prior written permission.\r
164   *\r
165   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
166   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
167   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
168   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
169   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
170   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
171   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
172   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
173   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
174   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
175   *\r
176   ******************************************************************************\r
177   */ \r
178 \r
179 /* Includes ------------------------------------------------------------------*/\r
180 #include "stm32f7xx_hal.h"\r
181 \r
182 /** @addtogroup STM32F7xx_HAL_Driver\r
183   * @{\r
184   */\r
185 \r
186 /** @addtogroup SD \r
187   * @{\r
188   */\r
189 \r
190 #ifdef HAL_SD_MODULE_ENABLED\r
191 \r
192 /* Private typedef -----------------------------------------------------------*/\r
193 /* Private define ------------------------------------------------------------*/\r
194 /** @addtogroup SD_Private_Defines\r
195   * @{\r
196   */\r
197 /** \r
198   * @brief  SDMMC Data block size \r
199   */ \r
200 #define DATA_BLOCK_SIZE                  ((uint32_t)(9 << 4))\r
201 /** \r
202   * @brief  SDMMC Static flags, Timeout, FIFO Address  \r
203   */\r
204 #define SDMMC_STATIC_FLAGS               ((uint32_t)(SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_CTIMEOUT |\\r
205                                                     SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_RXOVERR  |\\r
206                                                     SDMMC_FLAG_CMDREND  | SDMMC_FLAG_CMDSENT  | SDMMC_FLAG_DATAEND  |\\r
207                                                     SDMMC_FLAG_DBCKEND))  \r
208 \r
209 #define SDMMC_CMD0TIMEOUT                ((uint32_t)0x00010000)\r
210 \r
211 /** \r
212   * @brief  Mask for errors Card Status R1 (OCR Register) \r
213   */\r
214 #define SD_OCR_ADDR_OUT_OF_RANGE        ((uint32_t)0x80000000)\r
215 #define SD_OCR_ADDR_MISALIGNED          ((uint32_t)0x40000000)\r
216 #define SD_OCR_BLOCK_LEN_ERR            ((uint32_t)0x20000000)\r
217 #define SD_OCR_ERASE_SEQ_ERR            ((uint32_t)0x10000000)\r
218 #define SD_OCR_BAD_ERASE_PARAM          ((uint32_t)0x08000000)\r
219 #define SD_OCR_WRITE_PROT_VIOLATION     ((uint32_t)0x04000000)\r
220 #define SD_OCR_LOCK_UNLOCK_FAILED       ((uint32_t)0x01000000)\r
221 #define SD_OCR_COM_CRC_FAILED           ((uint32_t)0x00800000)\r
222 #define SD_OCR_ILLEGAL_CMD              ((uint32_t)0x00400000)\r
223 #define SD_OCR_CARD_ECC_FAILED          ((uint32_t)0x00200000)\r
224 #define SD_OCR_CC_ERROR                 ((uint32_t)0x00100000)\r
225 #define SD_OCR_GENERAL_UNKNOWN_ERROR    ((uint32_t)0x00080000)\r
226 #define SD_OCR_STREAM_READ_UNDERRUN     ((uint32_t)0x00040000)\r
227 #define SD_OCR_STREAM_WRITE_OVERRUN     ((uint32_t)0x00020000)\r
228 #define SD_OCR_CID_CSD_OVERWRITE        ((uint32_t)0x00010000)\r
229 #define SD_OCR_WP_ERASE_SKIP            ((uint32_t)0x00008000)\r
230 #define SD_OCR_CARD_ECC_DISABLED        ((uint32_t)0x00004000)\r
231 #define SD_OCR_ERASE_RESET              ((uint32_t)0x00002000)\r
232 #define SD_OCR_AKE_SEQ_ERROR            ((uint32_t)0x00000008)\r
233 #define SD_OCR_ERRORBITS                ((uint32_t)0xFDFFE008)\r
234 \r
235 /** \r
236   * @brief  Masks for R6 Response \r
237   */\r
238 #define SD_R6_GENERAL_UNKNOWN_ERROR     ((uint32_t)0x00002000)\r
239 #define SD_R6_ILLEGAL_CMD               ((uint32_t)0x00004000)\r
240 #define SD_R6_COM_CRC_FAILED            ((uint32_t)0x00008000)\r
241 \r
242 #define SD_VOLTAGE_WINDOW_SD            ((uint32_t)0x80100000)\r
243 #define SD_HIGH_CAPACITY                ((uint32_t)0x40000000)\r
244 #define SD_STD_CAPACITY                 ((uint32_t)0x00000000)\r
245 #define SD_CHECK_PATTERN                ((uint32_t)0x000001AA)\r
246 \r
247 #define SD_MAX_VOLT_TRIAL               ((uint32_t)0x0000FFFF)\r
248 #define SD_ALLZERO                      ((uint32_t)0x00000000)\r
249 \r
250 #define SD_WIDE_BUS_SUPPORT             ((uint32_t)0x00040000)\r
251 #define SD_SINGLE_BUS_SUPPORT           ((uint32_t)0x00010000)\r
252 #define SD_CARD_LOCKED                  ((uint32_t)0x02000000)\r
253 \r
254 #define SD_DATATIMEOUT                  ((uint32_t)0xFFFFFFFF)\r
255 #define SD_0TO7BITS                     ((uint32_t)0x000000FF)\r
256 #define SD_8TO15BITS                    ((uint32_t)0x0000FF00)\r
257 #define SD_16TO23BITS                   ((uint32_t)0x00FF0000)\r
258 #define SD_24TO31BITS                   ((uint32_t)0xFF000000)\r
259 #define SD_MAX_DATA_LENGTH              ((uint32_t)0x01FFFFFF)\r
260 \r
261 #define SD_HALFFIFO                     ((uint32_t)0x00000008)\r
262 #define SD_HALFFIFOBYTES                ((uint32_t)0x00000020)\r
263 \r
264 /** \r
265   * @brief  Command Class Supported \r
266   */\r
267 #define SD_CCCC_LOCK_UNLOCK             ((uint32_t)0x00000080)\r
268 #define SD_CCCC_WRITE_PROT              ((uint32_t)0x00000040)\r
269 #define SD_CCCC_ERASE                   ((uint32_t)0x00000020)\r
270 \r
271 /** \r
272   * @brief  Following commands are SD Card Specific commands.\r
273   *         SDMMC_APP_CMD should be sent before sending these commands. \r
274   */\r
275 #define SD_SDMMC_SEND_IF_COND            ((uint32_t)SD_CMD_HS_SEND_EXT_CSD)\r
276 /**\r
277   * @}\r
278   */\r
279   \r
280 /* Private macro -------------------------------------------------------------*/\r
281 /* Private variables ---------------------------------------------------------*/\r
282 /* Private function prototypes -----------------------------------------------*/\r
283 /* Private functions ---------------------------------------------------------*/\r
284 /** @defgroup SD_Private_Functions SD Private Functions\r
285   * @{\r
286   */\r
287 static HAL_SD_ErrorTypedef SD_Initialize_Cards(SD_HandleTypeDef *hsd);\r
288 static HAL_SD_ErrorTypedef SD_Select_Deselect(SD_HandleTypeDef *hsd, uint64_t addr);\r
289 static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd); \r
290 static HAL_SD_ErrorTypedef SD_PowerOFF(SD_HandleTypeDef *hsd);\r
291 static HAL_SD_ErrorTypedef SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus);\r
292 static HAL_SD_CardStateTypedef SD_GetState(SD_HandleTypeDef *hsd);\r
293 static HAL_SD_ErrorTypedef SD_IsCardProgramming(SD_HandleTypeDef *hsd, uint8_t *pStatus);\r
294 static HAL_SD_ErrorTypedef SD_CmdError(SD_HandleTypeDef *hsd);\r
295 static HAL_SD_ErrorTypedef SD_CmdResp1Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD);\r
296 static HAL_SD_ErrorTypedef SD_CmdResp7Error(SD_HandleTypeDef *hsd);\r
297 static HAL_SD_ErrorTypedef SD_CmdResp3Error(SD_HandleTypeDef *hsd);\r
298 static HAL_SD_ErrorTypedef SD_CmdResp2Error(SD_HandleTypeDef *hsd);\r
299 static HAL_SD_ErrorTypedef SD_CmdResp6Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD, uint16_t *pRCA);\r
300 static HAL_SD_ErrorTypedef SD_WideBus_Enable(SD_HandleTypeDef *hsd);\r
301 static HAL_SD_ErrorTypedef SD_WideBus_Disable(SD_HandleTypeDef *hsd);\r
302 static HAL_SD_ErrorTypedef SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR);  \r
303 static void SD_DMA_RxCplt(DMA_HandleTypeDef *hdma);\r
304 static void SD_DMA_RxError(DMA_HandleTypeDef *hdma);\r
305 static void SD_DMA_TxCplt(DMA_HandleTypeDef *hdma);\r
306 static void SD_DMA_TxError(DMA_HandleTypeDef *hdma);\r
307 /**\r
308   * @}\r
309   */\r
310 /* Exported functions --------------------------------------------------------*/\r
311 /** @addtogroup SD_Exported_Functions\r
312   * @{\r
313   */\r
314 \r
315 /** @addtogroup SD_Exported_Functions_Group1\r
316  *  @brief   Initialization and de-initialization functions \r
317  *\r
318 @verbatim    \r
319   ==============================================================================\r
320           ##### Initialization and de-initialization functions #####\r
321   ==============================================================================\r
322   [..]  \r
323     This section provides functions allowing to initialize/de-initialize the SD\r
324     card device to be ready for use.\r
325       \r
326  \r
327 @endverbatim\r
328   * @{\r
329   */\r
330 \r
331 /**\r
332   * @brief  Initializes the SD card according to the specified parameters in the \r
333             SD_HandleTypeDef and create the associated handle.\r
334   * @param  hsd: SD handle\r
335   * @param  SDCardInfo: HAL_SD_CardInfoTypedef structure for SD card information   \r
336   * @retval HAL SD error state\r
337   */\r
338 HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo)\r
339\r
340   __IO HAL_SD_ErrorTypedef errorstate = SD_OK;\r
341   SD_InitTypeDef tmpinit;\r
342   \r
343   /* Initialize the low level hardware (MSP) */\r
344   HAL_SD_MspInit(hsd);\r
345   \r
346   /* Default SDMMC peripheral configuration for SD card initialization */\r
347   tmpinit.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;\r
348   tmpinit.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;\r
349   tmpinit.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;\r
350   tmpinit.BusWide             = SDMMC_BUS_WIDE_1B;\r
351   tmpinit.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;\r
352   tmpinit.ClockDiv            = SDMMC_INIT_CLK_DIV;\r
353   \r
354   /* Initialize SDMMC peripheral interface with default configuration */\r
355   SDMMC_Init(hsd->Instance, tmpinit);\r
356   \r
357   /* Identify card operating voltage */\r
358   errorstate = SD_PowerON(hsd); \r
359   \r
360   if(errorstate != SD_OK)     \r
361   {\r
362     return errorstate;\r
363   }\r
364   \r
365   /* Initialize the present SDMMC card(s) and put them in idle state */\r
366   errorstate = SD_Initialize_Cards(hsd);\r
367   \r
368   if (errorstate != SD_OK)\r
369   {\r
370     return errorstate;\r
371   }\r
372   \r
373   /* Read CSD/CID MSD registers */\r
374   errorstate = HAL_SD_Get_CardInfo(hsd, SDCardInfo);\r
375   \r
376   if (errorstate == SD_OK)\r
377   {\r
378     /* Select the Card */\r
379     errorstate = SD_Select_Deselect(hsd, (uint32_t)(((uint32_t)SDCardInfo->RCA) << 16));\r
380   }\r
381   \r
382   /* Configure SDMMC peripheral interface */\r
383   SDMMC_Init(hsd->Instance, hsd->Init);   \r
384   \r
385   return errorstate;\r
386 }\r
387 \r
388 /**\r
389   * @brief  De-Initializes the SD card.\r
390   * @param  hsd: SD handle\r
391   * @retval HAL status\r
392   */\r
393 HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd)\r
394 {\r
395   \r
396   /* Set SD power state to off */ \r
397   SD_PowerOFF(hsd);\r
398   \r
399   /* De-Initialize the MSP layer */\r
400   HAL_SD_MspDeInit(hsd);\r
401   \r
402   return HAL_OK;\r
403 }\r
404 \r
405 \r
406 /**\r
407   * @brief  Initializes the SD MSP.\r
408   * @param  hsd: SD handle\r
409   * @retval None\r
410   */\r
411 __weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd)\r
412 {\r
413   /* NOTE : This function Should not be modified, when the callback is needed,\r
414             the HAL_SD_MspInit could be implemented in the user file\r
415    */\r
416 }\r
417 \r
418 /**\r
419   * @brief  De-Initialize SD MSP.\r
420   * @param  hsd: SD handle\r
421   * @retval None\r
422   */\r
423 __weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)\r
424 {\r
425   /* NOTE : This function Should not be modified, when the callback is needed,\r
426             the HAL_SD_MspDeInit could be implemented in the user file\r
427    */\r
428 }\r
429 \r
430 /**\r
431   * @}\r
432   */\r
433 \r
434 /** @addtogroup SD_Exported_Functions_Group2\r
435  *  @brief   Data transfer functions \r
436  *\r
437 @verbatim   \r
438   ==============================================================================\r
439                         ##### IO operation functions #####\r
440   ==============================================================================  \r
441   [..]\r
442     This subsection provides a set of functions allowing to manage the data \r
443     transfer from/to SD card.\r
444 \r
445 @endverbatim\r
446   * @{\r
447   */\r
448 \r
449 /**\r
450   * @brief  Reads block(s) from a specified address in a card. The Data transfer \r
451   *         is managed by polling mode.  \r
452   * @param  hsd: SD handle\r
453   * @param  pReadBuffer: pointer to the buffer that will contain the received data\r
454   * @param  ReadAddr: Address from where data is to be read  \r
455   * @param  BlockSize: SD card Data block size \r
456   *   @note BlockSize must be 512 bytes.\r
457   * @param  NumberOfBlocks: Number of SD blocks to read   \r
458   * @retval SD Card error state\r
459   */\r
460 HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)\r
461 {\r
462   SDMMC_CmdInitTypeDef  sdmmc_cmdinitstructure;\r
463   SDMMC_DataInitTypeDef sdmmc_datainitstructure;\r
464   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
465   uint32_t count = 0, *tempbuff = (uint32_t *)pReadBuffer;\r
466   \r
467   /* Initialize data control register */\r
468   hsd->Instance->DCTRL = 0;\r
469   \r
470   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
471   {\r
472     BlockSize = 512;\r
473     ReadAddr /= 512;\r
474   }\r
475   \r
476   /* Set Block Size for Card */ \r
477   sdmmc_cmdinitstructure.Argument         = (uint32_t) BlockSize;\r
478   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;\r
479   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
480   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
481   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
482   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
483   \r
484   /* Check for error conditions */\r
485   errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
486   \r
487   if (errorstate != SD_OK)\r
488   {\r
489     return errorstate;\r
490   }\r
491   \r
492   /* Configure the SD DPSM (Data Path State Machine) */\r
493   sdmmc_datainitstructure.DataTimeOut   = SD_DATATIMEOUT;\r
494   sdmmc_datainitstructure.DataLength    = NumberOfBlocks * BlockSize;\r
495   sdmmc_datainitstructure.DataBlockSize = DATA_BLOCK_SIZE;\r
496   sdmmc_datainitstructure.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;\r
497   sdmmc_datainitstructure.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;\r
498   sdmmc_datainitstructure.DPSM          = SDMMC_DPSM_ENABLE;\r
499   SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);\r
500   \r
501   if(NumberOfBlocks > 1)\r
502   {\r
503     /* Send CMD18 READ_MULT_BLOCK with argument data address */\r
504     sdmmc_cmdinitstructure.CmdIndex = SD_CMD_READ_MULT_BLOCK;\r
505   }\r
506   else\r
507   {\r
508     /* Send CMD17 READ_SINGLE_BLOCK */\r
509     sdmmc_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;    \r
510   }\r
511   \r
512   sdmmc_cmdinitstructure.Argument         = (uint32_t)ReadAddr;\r
513   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
514   \r
515   /* Read block(s) in polling mode */\r
516   if(NumberOfBlocks > 1)\r
517   {\r
518     /* Check for error conditions */\r
519     errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_MULT_BLOCK);\r
520     \r
521     if (errorstate != SD_OK)\r
522     {\r
523       return errorstate;\r
524     }\r
525     \r
526     /* Poll on SDMMC flags */\r
527     while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))\r
528     {\r
529       if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF))\r
530       {\r
531         /* Read data from SDMMC Rx FIFO */\r
532         for (count = 0; count < 8; count++)\r
533         {\r
534           *(tempbuff + count) = SDMMC_ReadFIFO(hsd->Instance);\r
535         }\r
536         \r
537         tempbuff += 8;\r
538       }\r
539     }      \r
540   }\r
541   else\r
542   {\r
543     /* Check for error conditions */\r
544     errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK); \r
545     \r
546     if (errorstate != SD_OK)\r
547     {\r
548       return errorstate;\r
549     }    \r
550     \r
551     /* In case of single block transfer, no need of stop transfer at all */\r
552     while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))\r
553     {\r
554       if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF))\r
555       {\r
556         /* Read data from SDMMC Rx FIFO */\r
557         for (count = 0; count < 8; count++)\r
558         {\r
559           *(tempbuff + count) = SDMMC_ReadFIFO(hsd->Instance);\r
560         }\r
561         \r
562         tempbuff += 8;\r
563       }\r
564     }   \r
565   }\r
566   \r
567   /* Send stop transmission command in case of multiblock read */\r
568   if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1))\r
569   {    \r
570     if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) ||\\r
571       (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\\r
572         (hsd->CardType == HIGH_CAPACITY_SD_CARD))\r
573     {\r
574       /* Send stop transmission command */\r
575       errorstate = HAL_SD_StopTransfer(hsd);\r
576     }\r
577   }\r
578   \r
579   /* Get error state */\r
580   if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT))\r
581   {\r
582     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);\r
583     \r
584     errorstate = SD_DATA_TIMEOUT;\r
585     \r
586     return errorstate;\r
587   }\r
588   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL))\r
589   {\r
590     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);\r
591     \r
592     errorstate = SD_DATA_CRC_FAIL;\r
593     \r
594     return errorstate;\r
595   }\r
596   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR))\r
597   {\r
598     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR);\r
599     \r
600     errorstate = SD_RX_OVERRUN;\r
601     \r
602     return errorstate;\r
603   }\r
604   else\r
605   {\r
606     /* No error flag set */\r
607   }\r
608   \r
609   count = SD_DATATIMEOUT;\r
610   \r
611   /* Empty FIFO if there is still any data */\r
612   while ((__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL)) && (count > 0))\r
613   {\r
614     *tempbuff = SDMMC_ReadFIFO(hsd->Instance);\r
615     tempbuff++;\r
616     count--;\r
617   }\r
618   \r
619   /* Clear all the static flags */\r
620   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
621   \r
622   return errorstate;\r
623 }\r
624 \r
625 /**\r
626   * @brief  Allows to write block(s) to a specified address in a card. The Data\r
627   *         transfer is managed by polling mode.  \r
628   * @param  hsd: SD handle\r
629   * @param  pWriteBuffer: pointer to the buffer that will contain the data to transmit\r
630   * @param  WriteAddr: Address from where data is to be written \r
631   * @param  BlockSize: SD card Data block size \r
632   * @note   BlockSize must be 512 bytes.\r
633   * @param  NumberOfBlocks: Number of SD blocks to write \r
634   * @retval SD Card error state\r
635   */\r
636 HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)\r
637 {\r
638   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
639   SDMMC_DataInitTypeDef sdmmc_datainitstructure;\r
640   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
641   uint32_t totalnumberofbytes = 0, bytestransferred = 0, count = 0, restwords = 0;\r
642   uint32_t *tempbuff = (uint32_t *)pWriteBuffer;\r
643   uint8_t cardstate  = 0;\r
644   \r
645   /* Initialize data control register */\r
646   hsd->Instance->DCTRL = 0;\r
647   \r
648   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
649   {\r
650     BlockSize = 512;\r
651     WriteAddr /= 512;\r
652   }\r
653   \r
654   /* Set Block Size for Card */ \r
655   sdmmc_cmdinitstructure.Argument         = (uint32_t)BlockSize;\r
656   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;\r
657   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
658   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
659   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
660   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
661   \r
662   /* Check for error conditions */\r
663   errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
664   \r
665   if (errorstate != SD_OK)\r
666   {\r
667     return errorstate;\r
668   }\r
669   \r
670   if(NumberOfBlocks > 1)\r
671   {\r
672     /* Send CMD25 WRITE_MULT_BLOCK with argument data address */\r
673     sdmmc_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;\r
674   }\r
675   else\r
676   {\r
677     /* Send CMD24 WRITE_SINGLE_BLOCK */\r
678     sdmmc_cmdinitstructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;\r
679   }\r
680   \r
681   sdmmc_cmdinitstructure.Argument         = (uint32_t)WriteAddr;\r
682   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
683   \r
684   /* Check for error conditions */\r
685   if(NumberOfBlocks > 1)\r
686   {\r
687     errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_MULT_BLOCK);\r
688   }\r
689   else\r
690   {\r
691     errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_SINGLE_BLOCK);\r
692   }  \r
693   \r
694   if (errorstate != SD_OK)\r
695   {\r
696     return errorstate;\r
697   }\r
698   \r
699   /* Set total number of bytes to write */\r
700   totalnumberofbytes = NumberOfBlocks * BlockSize;\r
701   \r
702   /* Configure the SD DPSM (Data Path State Machine) */ \r
703   sdmmc_datainitstructure.DataTimeOut   = SD_DATATIMEOUT;\r
704   sdmmc_datainitstructure.DataLength    = NumberOfBlocks * BlockSize;\r
705   sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;\r
706   sdmmc_datainitstructure.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;\r
707   sdmmc_datainitstructure.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;\r
708   sdmmc_datainitstructure.DPSM          = SDMMC_DPSM_ENABLE;\r
709   SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);\r
710   \r
711   /* Write block(s) in polling mode */\r
712   if(NumberOfBlocks > 1)\r
713   {\r
714     while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))\r
715     {\r
716       if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE))\r
717       {\r
718         if ((totalnumberofbytes - bytestransferred) < 32)\r
719         {\r
720           restwords = ((totalnumberofbytes - bytestransferred) % 4 == 0) ? ((totalnumberofbytes - bytestransferred) / 4) : (( totalnumberofbytes -  bytestransferred) / 4 + 1);\r
721           \r
722           /* Write data to SDMMC Tx FIFO */\r
723           for (count = 0; count < restwords; count++)\r
724           {\r
725             SDMMC_WriteFIFO(hsd->Instance, tempbuff);\r
726             tempbuff++;\r
727             bytestransferred += 4;\r
728           }\r
729         }\r
730         else\r
731         {\r
732           /* Write data to SDMMC Tx FIFO */\r
733           for (count = 0; count < 8; count++)\r
734           {\r
735             SDMMC_WriteFIFO(hsd->Instance, (tempbuff + count));\r
736           }\r
737           \r
738           tempbuff += 8;\r
739           bytestransferred += 32;\r
740         }\r
741       }\r
742     }   \r
743   }\r
744   else\r
745   {\r
746     /* In case of single data block transfer no need of stop command at all */ \r
747     while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))\r
748     {\r
749       if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE))\r
750       {\r
751         if ((totalnumberofbytes - bytestransferred) < 32)\r
752         {\r
753           restwords = ((totalnumberofbytes - bytestransferred) % 4 == 0) ? ((totalnumberofbytes - bytestransferred) / 4) : (( totalnumberofbytes -  bytestransferred) / 4 + 1);\r
754           \r
755           /* Write data to SDMMC Tx FIFO */\r
756           for (count = 0; count < restwords; count++)\r
757           {\r
758             SDMMC_WriteFIFO(hsd->Instance, tempbuff);\r
759             tempbuff++; \r
760             bytestransferred += 4;\r
761           }\r
762         }\r
763         else\r
764         {\r
765           /* Write data to SDMMC Tx FIFO */\r
766           for (count = 0; count < 8; count++)\r
767           {\r
768             SDMMC_WriteFIFO(hsd->Instance, (tempbuff + count));\r
769           }\r
770           \r
771           tempbuff += 8;\r
772           bytestransferred += 32;\r
773         }\r
774       }\r
775     }  \r
776   }\r
777   \r
778   /* Send stop transmission command in case of multiblock write */\r
779   if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1))\r
780   {    \r
781     if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\\r
782       (hsd->CardType == HIGH_CAPACITY_SD_CARD))\r
783     {\r
784       /* Send stop transmission command */\r
785       errorstate = HAL_SD_StopTransfer(hsd);\r
786     }\r
787   }\r
788   \r
789   /* Get error state */\r
790   if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT))\r
791   {\r
792     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);\r
793     \r
794     errorstate = SD_DATA_TIMEOUT;\r
795     \r
796     return errorstate;\r
797   }\r
798   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL))\r
799   {\r
800     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);\r
801     \r
802     errorstate = SD_DATA_CRC_FAIL;\r
803     \r
804     return errorstate;\r
805   }\r
806   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR))\r
807   {\r
808     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_TXUNDERR);\r
809     \r
810     errorstate = SD_TX_UNDERRUN;\r
811     \r
812     return errorstate;\r
813   }\r
814   else\r
815   {\r
816     /* No error flag set */\r
817   }\r
818   \r
819   /* Clear all the static flags */\r
820   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
821   \r
822   /* Wait till the card is in programming state */\r
823   errorstate = SD_IsCardProgramming(hsd, &cardstate);\r
824   \r
825   while ((errorstate == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))\r
826   {\r
827     errorstate = SD_IsCardProgramming(hsd, &cardstate);\r
828   }\r
829   \r
830   return errorstate;\r
831 }\r
832 \r
833 /**\r
834   * @brief  Reads block(s) from a specified address in a card. The Data transfer \r
835   *         is managed by DMA mode. \r
836   * @note   This API should be followed by the function HAL_SD_CheckReadOperation()\r
837   *         to check the completion of the read process   \r
838   * @param  hsd: SD handle                 \r
839   * @param  pReadBuffer: Pointer to the buffer that will contain the received data\r
840   * @param  ReadAddr: Address from where data is to be read  \r
841   * @param  BlockSize: SD card Data block size \r
842   * @note   BlockSize must be 512 bytes.\r
843   * @param  NumberOfBlocks: Number of blocks to read.\r
844   * @retval SD Card error state\r
845   */\r
846 HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)\r
847 {\r
848   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
849   SDMMC_DataInitTypeDef sdmmc_datainitstructure;\r
850   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
851   \r
852   /* Initialize data control register */\r
853   hsd->Instance->DCTRL = 0;\r
854   \r
855   /* Initialize handle flags */\r
856   hsd->SdTransferCplt  = 0;\r
857   hsd->DmaTransferCplt = 0;\r
858   hsd->SdTransferErr   = SD_OK; \r
859   \r
860   /* Initialize SD Read operation */\r
861   if(NumberOfBlocks > 1)\r
862   {\r
863     hsd->SdOperation = SD_READ_MULTIPLE_BLOCK;\r
864   }\r
865   else\r
866   {\r
867     hsd->SdOperation = SD_READ_SINGLE_BLOCK;\r
868   }\r
869   \r
870   /* Enable transfer interrupts */\r
871   __HAL_SD_SDMMC_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL |\\r
872                                  SDMMC_IT_DTIMEOUT |\\r
873                                  SDMMC_IT_DATAEND  |\\r
874                                  SDMMC_IT_RXOVERR));\r
875   \r
876   /* Enable SDMMC DMA transfer */\r
877   __HAL_SD_SDMMC_DMA_ENABLE(hsd);\r
878   \r
879   /* Configure DMA user callbacks */\r
880   hsd->hdmarx->XferCpltCallback  = SD_DMA_RxCplt;\r
881   hsd->hdmarx->XferErrorCallback = SD_DMA_RxError;\r
882   \r
883   /* Enable the DMA Channel */\r
884   HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pReadBuffer, (uint32_t)(BlockSize * NumberOfBlocks)/4);\r
885   \r
886   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
887   {\r
888     BlockSize = 512;\r
889     ReadAddr /= 512;\r
890   }\r
891   \r
892   /* Set Block Size for Card */ \r
893   sdmmc_cmdinitstructure.Argument         = (uint32_t)BlockSize;\r
894   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;\r
895   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
896   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
897   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
898   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
899   \r
900   /* Check for error conditions */\r
901   errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
902   \r
903   if (errorstate != SD_OK)\r
904   {\r
905     return errorstate;\r
906   }\r
907   \r
908   /* Configure the SD DPSM (Data Path State Machine) */ \r
909   sdmmc_datainitstructure.DataTimeOut   = SD_DATATIMEOUT;\r
910   sdmmc_datainitstructure.DataLength    = BlockSize * NumberOfBlocks;\r
911   sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;\r
912   sdmmc_datainitstructure.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;\r
913   sdmmc_datainitstructure.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;\r
914   sdmmc_datainitstructure.DPSM          = SDMMC_DPSM_ENABLE;\r
915   SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);\r
916   \r
917   /* Check number of blocks command */\r
918   if(NumberOfBlocks > 1)\r
919   {\r
920     /* Send CMD18 READ_MULT_BLOCK with argument data address */\r
921     sdmmc_cmdinitstructure.CmdIndex = SD_CMD_READ_MULT_BLOCK;\r
922   }\r
923   else\r
924   {\r
925     /* Send CMD17 READ_SINGLE_BLOCK */\r
926     sdmmc_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;\r
927   }\r
928   \r
929   sdmmc_cmdinitstructure.Argument         = (uint32_t)ReadAddr;\r
930   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
931   \r
932   /* Check for error conditions */\r
933   if(NumberOfBlocks > 1)\r
934   {\r
935     errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_MULT_BLOCK);\r
936   }\r
937   else\r
938   {\r
939     errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK);\r
940   }\r
941   \r
942   /* Update the SD transfer error in SD handle */\r
943   hsd->SdTransferErr = errorstate;\r
944   \r
945   return errorstate;\r
946 }\r
947 \r
948 \r
949 /**\r
950   * @brief  Writes block(s) to a specified address in a card. The Data transfer \r
951   *         is managed by DMA mode. \r
952   * @note   This API should be followed by the function HAL_SD_CheckWriteOperation()\r
953   *         to check the completion of the write process (by SD current status polling).  \r
954   * @param  hsd: SD handle\r
955   * @param  pWriteBuffer: pointer to the buffer that will contain the data to transmit\r
956   * @param  WriteAddr: Address from where data is to be read   \r
957   * @param  BlockSize: the SD card Data block size \r
958   * @note   BlockSize must be 512 bytes.\r
959   * @param  NumberOfBlocks: Number of blocks to write\r
960   * @retval SD Card error state\r
961   */\r
962 HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)\r
963 {\r
964   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
965   SDMMC_DataInitTypeDef sdmmc_datainitstructure;\r
966   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
967   \r
968   /* Initialize data control register */\r
969   hsd->Instance->DCTRL = 0;\r
970   \r
971   /* Initialize handle flags */\r
972   hsd->SdTransferCplt  = 0;\r
973   hsd->DmaTransferCplt = 0;\r
974   hsd->SdTransferErr   = SD_OK;\r
975   \r
976   /* Initialize SD Write operation */\r
977   if(NumberOfBlocks > 1)\r
978   {\r
979     hsd->SdOperation = SD_WRITE_MULTIPLE_BLOCK;\r
980   }\r
981   else\r
982   {\r
983     hsd->SdOperation = SD_WRITE_SINGLE_BLOCK;\r
984   }  \r
985   \r
986   /* Enable transfer interrupts */\r
987   __HAL_SD_SDMMC_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL |\\r
988                                  SDMMC_IT_DTIMEOUT |\\r
989                                  SDMMC_IT_DATAEND  |\\r
990                                  SDMMC_IT_TXUNDERR)); \r
991   \r
992   /* Configure DMA user callbacks */\r
993   hsd->hdmatx->XferCpltCallback  = SD_DMA_TxCplt;\r
994   hsd->hdmatx->XferErrorCallback = SD_DMA_TxError;\r
995   \r
996   /* Enable the DMA Channel */\r
997   HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pWriteBuffer, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BlockSize * NumberOfBlocks)/4);\r
998 \r
999   /* Enable SDMMC DMA transfer */\r
1000   __HAL_SD_SDMMC_DMA_ENABLE(hsd);\r
1001   \r
1002   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
1003   {\r
1004     BlockSize = 512;\r
1005     WriteAddr /= 512;\r
1006   }\r
1007 \r
1008   /* Set Block Size for Card */ \r
1009   sdmmc_cmdinitstructure.Argument         = (uint32_t)BlockSize;\r
1010   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;\r
1011   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
1012   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
1013   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
1014   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
1015 \r
1016   /* Check for error conditions */\r
1017   errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
1018 \r
1019   if (errorstate != SD_OK)\r
1020   {\r
1021     return errorstate;\r
1022   }\r
1023   \r
1024   /* Check number of blocks command */\r
1025   if(NumberOfBlocks <= 1)\r
1026   {\r
1027     /* Send CMD24 WRITE_SINGLE_BLOCK */\r
1028     sdmmc_cmdinitstructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;\r
1029   }\r
1030   else\r
1031   {\r
1032     /* Send CMD25 WRITE_MULT_BLOCK with argument data address */\r
1033     sdmmc_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;\r
1034   }\r
1035   \r
1036   sdmmc_cmdinitstructure.Argument         = (uint32_t)WriteAddr;\r
1037   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
1038 \r
1039   /* Check for error conditions */\r
1040   if(NumberOfBlocks > 1)\r
1041   {\r
1042     errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_MULT_BLOCK);\r
1043   }\r
1044   else\r
1045   {\r
1046     errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_SINGLE_BLOCK);\r
1047   }\r
1048   \r
1049   if (errorstate != SD_OK)\r
1050   {\r
1051     return errorstate;\r
1052   }\r
1053   \r
1054   /* Configure the SD DPSM (Data Path State Machine) */ \r
1055   sdmmc_datainitstructure.DataTimeOut   = SD_DATATIMEOUT;\r
1056   sdmmc_datainitstructure.DataLength    = BlockSize * NumberOfBlocks;\r
1057   sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;\r
1058   sdmmc_datainitstructure.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;\r
1059   sdmmc_datainitstructure.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;\r
1060   sdmmc_datainitstructure.DPSM          = SDMMC_DPSM_ENABLE;\r
1061   SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);\r
1062   \r
1063   hsd->SdTransferErr = errorstate;\r
1064   \r
1065   return errorstate;\r
1066 }\r
1067 \r
1068 /**\r
1069   * @brief  This function waits until the SD DMA data read transfer is finished. \r
1070   *         This API should be called after HAL_SD_ReadBlocks_DMA() function\r
1071   *         to insure that all data sent by the card is already transferred by the \r
1072   *         DMA controller.\r
1073   * @param  hsd: SD handle\r
1074   * @param  Timeout: Timeout duration  \r
1075   * @retval SD Card error state\r
1076   */\r
1077 HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout)\r
1078 {\r
1079   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
1080   uint32_t timeout = Timeout;\r
1081   uint32_t tmp1, tmp2;\r
1082   HAL_SD_ErrorTypedef tmp3;\r
1083   \r
1084   /* Wait for DMA/SD transfer end or SD error variables to be in SD handle */\r
1085   tmp1 = hsd->DmaTransferCplt; \r
1086   tmp2 = hsd->SdTransferCplt;\r
1087   tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;\r
1088     \r
1089   while (((tmp1 & tmp2) == 0) && (tmp3 == SD_OK) && (timeout > 0))\r
1090   {\r
1091     tmp1 = hsd->DmaTransferCplt; \r
1092     tmp2 = hsd->SdTransferCplt;\r
1093     tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;    \r
1094     timeout--;\r
1095   }\r
1096 \r
1097   timeout = Timeout;\r
1098   \r
1099   /* Wait until the Rx transfer is no longer active */\r
1100   while((__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXACT)) && (timeout > 0))\r
1101   {\r
1102     timeout--;  \r
1103   }\r
1104   \r
1105   /* Send stop command in multiblock read */\r
1106   if (hsd->SdOperation == SD_READ_MULTIPLE_BLOCK)\r
1107   {\r
1108     errorstate = HAL_SD_StopTransfer(hsd);\r
1109   }\r
1110   \r
1111   if ((timeout == 0) && (errorstate == SD_OK))\r
1112   {\r
1113     errorstate = SD_DATA_TIMEOUT;\r
1114   }\r
1115   \r
1116   /* Clear all the static flags */\r
1117   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
1118   \r
1119   /* Return error state */\r
1120   if (hsd->SdTransferErr != SD_OK)\r
1121   {\r
1122     return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr);\r
1123   }\r
1124   \r
1125   return errorstate;\r
1126 }\r
1127 \r
1128 /**\r
1129   * @brief  This function waits until the SD DMA data write transfer is finished. \r
1130   *         This API should be called after HAL_SD_WriteBlocks_DMA() function\r
1131   *         to insure that all data sent by the card is already transferred by the \r
1132   *         DMA controller.\r
1133   * @param  hsd: SD handle\r
1134   * @param  Timeout: Timeout duration  \r
1135   * @retval SD Card error state\r
1136   */\r
1137 HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout)\r
1138 {\r
1139   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
1140   uint32_t timeout = Timeout;\r
1141   uint32_t tmp1, tmp2;\r
1142   HAL_SD_ErrorTypedef tmp3;\r
1143 \r
1144   /* Wait for DMA/SD transfer end or SD error variables to be in SD handle */\r
1145   tmp1 = hsd->DmaTransferCplt; \r
1146   tmp2 = hsd->SdTransferCplt;\r
1147   tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;\r
1148     \r
1149   while (((tmp1 & tmp2) == 0) && (tmp3 == SD_OK) && (timeout > 0))\r
1150   {\r
1151     tmp1 = hsd->DmaTransferCplt; \r
1152     tmp2 = hsd->SdTransferCplt;\r
1153     tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;\r
1154     timeout--;\r
1155   }\r
1156   \r
1157   timeout = Timeout;\r
1158   \r
1159   /* Wait until the Tx transfer is no longer active */\r
1160   while((__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXACT))  && (timeout > 0))\r
1161   {\r
1162     timeout--;  \r
1163   }\r
1164 \r
1165   /* Send stop command in multiblock write */\r
1166   if (hsd->SdOperation == SD_WRITE_MULTIPLE_BLOCK)\r
1167   {\r
1168     errorstate = HAL_SD_StopTransfer(hsd);\r
1169   }\r
1170   \r
1171   if ((timeout == 0) && (errorstate == SD_OK))\r
1172   {\r
1173     errorstate = SD_DATA_TIMEOUT;\r
1174   }\r
1175   \r
1176   /* Clear all the static flags */\r
1177   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
1178   \r
1179   /* Return error state */\r
1180   if (hsd->SdTransferErr != SD_OK)\r
1181   {\r
1182     return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr);\r
1183   }\r
1184   \r
1185   /* Wait until write is complete */\r
1186   while(HAL_SD_GetStatus(hsd) != SD_TRANSFER_OK)\r
1187   {    \r
1188   }\r
1189 \r
1190   return errorstate; \r
1191 }\r
1192 \r
1193 /**\r
1194   * @brief  Erases the specified memory area of the given SD card.\r
1195   * @param  hsd: SD handle \r
1196   * @param  startaddr: Start byte address\r
1197   * @param  endaddr: End byte address\r
1198   * @retval SD Card error state\r
1199   */\r
1200 HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t startaddr, uint64_t endaddr)\r
1201 {\r
1202   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
1203   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
1204   \r
1205   uint32_t delay         = 0;\r
1206   __IO uint32_t maxdelay = 0;\r
1207   uint8_t cardstate      = 0;\r
1208   \r
1209   /* Check if the card command class supports erase command */\r
1210   if (((hsd->CSD[1] >> 20) & SD_CCCC_ERASE) == 0)\r
1211   {\r
1212     errorstate = SD_REQUEST_NOT_APPLICABLE;\r
1213     \r
1214     return errorstate;\r
1215   }\r
1216   \r
1217   /* Get max delay value */\r
1218   maxdelay = 120000 / (((hsd->Instance->CLKCR) & 0xFF) + 2);\r
1219   \r
1220   if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)\r
1221   {\r
1222     errorstate = SD_LOCK_UNLOCK_FAILED;\r
1223     \r
1224     return errorstate;\r
1225   }\r
1226   \r
1227   /* Get start and end block for high capacity cards */\r
1228   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
1229   {\r
1230     startaddr /= 512;\r
1231     endaddr   /= 512;\r
1232   }\r
1233   \r
1234   /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */\r
1235   if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\\r
1236     (hsd->CardType == HIGH_CAPACITY_SD_CARD))\r
1237   {\r
1238     /* Send CMD32 SD_ERASE_GRP_START with argument as addr  */\r
1239     sdmmc_cmdinitstructure.Argument         =(uint32_t)startaddr;\r
1240     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SD_ERASE_GRP_START;\r
1241     sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
1242     sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
1243     sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
1244     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
1245     \r
1246     /* Check for error conditions */\r
1247     errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_ERASE_GRP_START);\r
1248     \r
1249     if (errorstate != SD_OK)\r
1250     {\r
1251       return errorstate;\r
1252     }\r
1253     \r
1254     /* Send CMD33 SD_ERASE_GRP_END with argument as addr  */\r
1255     sdmmc_cmdinitstructure.Argument         = (uint32_t)endaddr;\r
1256     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SD_ERASE_GRP_END;\r
1257     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
1258     \r
1259     /* Check for error conditions */\r
1260     errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_ERASE_GRP_END);\r
1261     \r
1262     if (errorstate != SD_OK)\r
1263     {\r
1264       return errorstate;\r
1265     }\r
1266   }\r
1267   \r
1268   /* Send CMD38 ERASE */\r
1269   sdmmc_cmdinitstructure.Argument         = 0;\r
1270   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_ERASE;\r
1271   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
1272   \r
1273   /* Check for error conditions */\r
1274   errorstate = SD_CmdResp1Error(hsd, SD_CMD_ERASE);\r
1275   \r
1276   if (errorstate != SD_OK)\r
1277   {\r
1278     return errorstate;\r
1279   }\r
1280   \r
1281   for (; delay < maxdelay; delay++)\r
1282   {\r
1283   }\r
1284   \r
1285   /* Wait until the card is in programming state */\r
1286   errorstate = SD_IsCardProgramming(hsd, &cardstate);\r
1287   \r
1288   delay = SD_DATATIMEOUT;\r
1289   \r
1290   while ((delay > 0) && (errorstate == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))\r
1291   {\r
1292     errorstate = SD_IsCardProgramming(hsd, &cardstate);\r
1293     delay--;\r
1294   }\r
1295   \r
1296   return errorstate;\r
1297 }\r
1298 \r
1299 /**\r
1300   * @brief  This function handles SD card interrupt request.\r
1301   * @param  hsd: SD handle\r
1302   * @retval None\r
1303   */\r
1304 void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd)\r
1305 {  \r
1306   /* Check for SDMMC interrupt flags */\r
1307   if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_IT_DATAEND))\r
1308   {\r
1309     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_IT_DATAEND);  \r
1310       \r
1311     /* SD transfer is complete */\r
1312     hsd->SdTransferCplt = 1;\r
1313 \r
1314     /* No transfer error */ \r
1315     hsd->SdTransferErr  = SD_OK;\r
1316 \r
1317     HAL_SD_XferCpltCallback(hsd);  \r
1318   }  \r
1319   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_IT_DCRCFAIL))\r
1320   {\r
1321     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);\r
1322     \r
1323     hsd->SdTransferErr = SD_DATA_CRC_FAIL;\r
1324     \r
1325     HAL_SD_XferErrorCallback(hsd);\r
1326     \r
1327   }\r
1328   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_IT_DTIMEOUT))\r
1329   {\r
1330     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);\r
1331     \r
1332     hsd->SdTransferErr = SD_DATA_TIMEOUT;\r
1333     \r
1334     HAL_SD_XferErrorCallback(hsd);\r
1335   }\r
1336   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_IT_RXOVERR))\r
1337   {\r
1338     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR);\r
1339     \r
1340     hsd->SdTransferErr = SD_RX_OVERRUN;\r
1341     \r
1342     HAL_SD_XferErrorCallback(hsd);\r
1343   }\r
1344   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_IT_TXUNDERR))\r
1345   {\r
1346     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_TXUNDERR);\r
1347     \r
1348     hsd->SdTransferErr = SD_TX_UNDERRUN;\r
1349     \r
1350     HAL_SD_XferErrorCallback(hsd);\r
1351   }\r
1352   else\r
1353   {\r
1354     /* No error flag set */\r
1355   }  \r
1356 \r
1357   /* Disable all SDMMC peripheral interrupt sources */\r
1358   __HAL_SD_SDMMC_DISABLE_IT(hsd, SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_DATAEND  |\\r
1359                                  SDMMC_IT_TXFIFOHE | SDMMC_IT_RXFIFOHF | SDMMC_IT_TXUNDERR |\\r
1360                                  SDMMC_IT_RXOVERR);                               \r
1361 }\r
1362 \r
1363 \r
1364 /**\r
1365   * @brief  SD end of transfer callback.\r
1366   * @param  hsd: SD handle \r
1367   * @retval None\r
1368   */\r
1369 __weak void HAL_SD_XferCpltCallback(SD_HandleTypeDef *hsd)\r
1370 {\r
1371   /* NOTE : This function Should not be modified, when the callback is needed,\r
1372             the HAL_SD_XferCpltCallback could be implemented in the user file\r
1373    */ \r
1374 }\r
1375 \r
1376 /**\r
1377   * @brief  SD Transfer Error callback.\r
1378   * @param  hsd: SD handle\r
1379   * @retval None\r
1380   */\r
1381 __weak void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd)\r
1382 {\r
1383   /* NOTE : This function Should not be modified, when the callback is needed,\r
1384             the HAL_SD_XferErrorCallback could be implemented in the user file\r
1385    */ \r
1386 }\r
1387 \r
1388 /**\r
1389   * @brief  SD Transfer complete Rx callback in non blocking mode.\r
1390   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
1391   *                the configuration information for the specified DMA module.\r
1392   * @retval None\r
1393   */\r
1394 __weak void HAL_SD_DMA_RxCpltCallback(DMA_HandleTypeDef *hdma)\r
1395 {\r
1396   /* NOTE : This function Should not be modified, when the callback is needed,\r
1397             the HAL_SD_DMA_RxCpltCallback could be implemented in the user file\r
1398    */ \r
1399 }  \r
1400 \r
1401 /**\r
1402   * @brief  SD DMA transfer complete Rx error callback.\r
1403   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
1404   *                the configuration information for the specified DMA module.\r
1405   * @retval None\r
1406   */\r
1407 __weak void HAL_SD_DMA_RxErrorCallback(DMA_HandleTypeDef *hdma)\r
1408 {\r
1409   /* NOTE : This function Should not be modified, when the callback is needed,\r
1410             the HAL_SD_DMA_RxErrorCallback could be implemented in the user file\r
1411    */ \r
1412 }\r
1413 \r
1414 /**\r
1415   * @brief  SD Transfer complete Tx callback in non blocking mode.\r
1416   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
1417   *                the configuration information for the specified DMA module.\r
1418   * @retval None\r
1419   */\r
1420 __weak void HAL_SD_DMA_TxCpltCallback(DMA_HandleTypeDef *hdma)\r
1421 {\r
1422   /* NOTE : This function Should not be modified, when the callback is needed,\r
1423             the HAL_SD_DMA_TxCpltCallback could be implemented in the user file\r
1424    */ \r
1425 }  \r
1426 \r
1427 /**\r
1428   * @brief  SD DMA transfer complete error Tx callback.\r
1429   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
1430   *                the configuration information for the specified DMA module.\r
1431   * @retval None\r
1432   */\r
1433 __weak void HAL_SD_DMA_TxErrorCallback(DMA_HandleTypeDef *hdma)\r
1434 {\r
1435   /* NOTE : This function Should not be modified, when the callback is needed,\r
1436             the HAL_SD_DMA_TxErrorCallback could be implemented in the user file\r
1437    */ \r
1438 }\r
1439 \r
1440 /**\r
1441   * @}\r
1442   */\r
1443 \r
1444 /** @addtogroup SD_Exported_Functions_Group3\r
1445  *  @brief   management functions \r
1446  *\r
1447 @verbatim   \r
1448   ==============================================================================\r
1449                       ##### Peripheral Control functions #####\r
1450   ==============================================================================  \r
1451   [..]\r
1452     This subsection provides a set of functions allowing to control the SD card \r
1453     operations.\r
1454 \r
1455 @endverbatim\r
1456   * @{\r
1457   */\r
1458 \r
1459 /**\r
1460   * @brief  Returns information about specific card.\r
1461   * @param  hsd: SD handle\r
1462   * @param  pCardInfo: Pointer to a HAL_SD_CardInfoTypedef structure that  \r
1463   *         contains all SD cardinformation  \r
1464   * @retval SD Card error state\r
1465   */\r
1466 HAL_SD_ErrorTypedef HAL_SD_Get_CardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *pCardInfo)\r
1467 {\r
1468   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
1469   uint32_t tmp = 0;\r
1470   \r
1471   pCardInfo->CardType = (uint8_t)(hsd->CardType);\r
1472   pCardInfo->RCA      = (uint16_t)(hsd->RCA);\r
1473   \r
1474   /* Byte 0 */\r
1475   tmp = (hsd->CSD[0] & 0xFF000000) >> 24;\r
1476   pCardInfo->SD_csd.CSDStruct      = (uint8_t)((tmp & 0xC0) >> 6);\r
1477   pCardInfo->SD_csd.SysSpecVersion = (uint8_t)((tmp & 0x3C) >> 2);\r
1478   pCardInfo->SD_csd.Reserved1      = tmp & 0x03;\r
1479   \r
1480   /* Byte 1 */\r
1481   tmp = (hsd->CSD[0] & 0x00FF0000) >> 16;\r
1482   pCardInfo->SD_csd.TAAC = (uint8_t)tmp;\r
1483   \r
1484   /* Byte 2 */\r
1485   tmp = (hsd->CSD[0] & 0x0000FF00) >> 8;\r
1486   pCardInfo->SD_csd.NSAC = (uint8_t)tmp;\r
1487   \r
1488   /* Byte 3 */\r
1489   tmp = hsd->CSD[0] & 0x000000FF;\r
1490   pCardInfo->SD_csd.MaxBusClkFrec = (uint8_t)tmp;\r
1491   \r
1492   /* Byte 4 */\r
1493   tmp = (hsd->CSD[1] & 0xFF000000) >> 24;\r
1494   pCardInfo->SD_csd.CardComdClasses = (uint16_t)(tmp << 4);\r
1495   \r
1496   /* Byte 5 */\r
1497   tmp = (hsd->CSD[1] & 0x00FF0000) >> 16;\r
1498   pCardInfo->SD_csd.CardComdClasses |= (uint16_t)((tmp & 0xF0) >> 4);\r
1499   pCardInfo->SD_csd.RdBlockLen       = (uint8_t)(tmp & 0x0F);\r
1500   \r
1501   /* Byte 6 */\r
1502   tmp = (hsd->CSD[1] & 0x0000FF00) >> 8;\r
1503   pCardInfo->SD_csd.PartBlockRead   = (uint8_t)((tmp & 0x80) >> 7);\r
1504   pCardInfo->SD_csd.WrBlockMisalign = (uint8_t)((tmp & 0x40) >> 6);\r
1505   pCardInfo->SD_csd.RdBlockMisalign = (uint8_t)((tmp & 0x20) >> 5);\r
1506   pCardInfo->SD_csd.DSRImpl         = (uint8_t)((tmp & 0x10) >> 4);\r
1507   pCardInfo->SD_csd.Reserved2       = 0; /*!< Reserved */\r
1508   \r
1509   if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0))\r
1510   {\r
1511     pCardInfo->SD_csd.DeviceSize = (tmp & 0x03) << 10;\r
1512     \r
1513     /* Byte 7 */\r
1514     tmp = (uint8_t)(hsd->CSD[1] & 0x000000FF);\r
1515     pCardInfo->SD_csd.DeviceSize |= (tmp) << 2;\r
1516     \r
1517     /* Byte 8 */\r
1518     tmp = (uint8_t)((hsd->CSD[2] & 0xFF000000) >> 24);\r
1519     pCardInfo->SD_csd.DeviceSize |= (tmp & 0xC0) >> 6;\r
1520     \r
1521     pCardInfo->SD_csd.MaxRdCurrentVDDMin = (tmp & 0x38) >> 3;\r
1522     pCardInfo->SD_csd.MaxRdCurrentVDDMax = (tmp & 0x07);\r
1523     \r
1524     /* Byte 9 */\r
1525     tmp = (uint8_t)((hsd->CSD[2] & 0x00FF0000) >> 16);\r
1526     pCardInfo->SD_csd.MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5;\r
1527     pCardInfo->SD_csd.MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2;\r
1528     pCardInfo->SD_csd.DeviceSizeMul      = (tmp & 0x03) << 1;\r
1529     /* Byte 10 */\r
1530     tmp = (uint8_t)((hsd->CSD[2] & 0x0000FF00) >> 8);\r
1531     pCardInfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7;\r
1532     \r
1533     pCardInfo->CardCapacity  = (pCardInfo->SD_csd.DeviceSize + 1) ;\r
1534     pCardInfo->CardCapacity *= (1 << (pCardInfo->SD_csd.DeviceSizeMul + 2));\r
1535     pCardInfo->CardBlockSize = 1 << (pCardInfo->SD_csd.RdBlockLen);\r
1536     pCardInfo->CardCapacity *= pCardInfo->CardBlockSize;\r
1537   }\r
1538   else if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
1539   {\r
1540     /* Byte 7 */\r
1541     tmp = (uint8_t)(hsd->CSD[1] & 0x000000FF);\r
1542     pCardInfo->SD_csd.DeviceSize = (tmp & 0x3F) << 16;\r
1543     \r
1544     /* Byte 8 */\r
1545     tmp = (uint8_t)((hsd->CSD[2] & 0xFF000000) >> 24);\r
1546     \r
1547     pCardInfo->SD_csd.DeviceSize |= (tmp << 8);\r
1548     \r
1549     /* Byte 9 */\r
1550     tmp = (uint8_t)((hsd->CSD[2] & 0x00FF0000) >> 16);\r
1551     \r
1552     pCardInfo->SD_csd.DeviceSize |= (tmp);\r
1553     \r
1554     /* Byte 10 */\r
1555     tmp = (uint8_t)((hsd->CSD[2] & 0x0000FF00) >> 8);\r
1556     \r
1557     pCardInfo->CardCapacity  = ((pCardInfo->SD_csd.DeviceSize + 1)) * 512 * 1024;\r
1558     pCardInfo->CardBlockSize = 512;    \r
1559   }\r
1560   else\r
1561   {\r
1562     /* Not supported card type */\r
1563     errorstate = SD_ERROR;\r
1564   }\r
1565       \r
1566   pCardInfo->SD_csd.EraseGrSize = (tmp & 0x40) >> 6;\r
1567   pCardInfo->SD_csd.EraseGrMul  = (tmp & 0x3F) << 1;\r
1568   \r
1569   /* Byte 11 */\r
1570   tmp = (uint8_t)(hsd->CSD[2] & 0x000000FF);\r
1571   pCardInfo->SD_csd.EraseGrMul     |= (tmp & 0x80) >> 7;\r
1572   pCardInfo->SD_csd.WrProtectGrSize = (tmp & 0x7F);\r
1573   \r
1574   /* Byte 12 */\r
1575   tmp = (uint8_t)((hsd->CSD[3] & 0xFF000000) >> 24);\r
1576   pCardInfo->SD_csd.WrProtectGrEnable = (tmp & 0x80) >> 7;\r
1577   pCardInfo->SD_csd.ManDeflECC        = (tmp & 0x60) >> 5;\r
1578   pCardInfo->SD_csd.WrSpeedFact       = (tmp & 0x1C) >> 2;\r
1579   pCardInfo->SD_csd.MaxWrBlockLen     = (tmp & 0x03) << 2;\r
1580   \r
1581   /* Byte 13 */\r
1582   tmp = (uint8_t)((hsd->CSD[3] & 0x00FF0000) >> 16);\r
1583   pCardInfo->SD_csd.MaxWrBlockLen      |= (tmp & 0xC0) >> 6;\r
1584   pCardInfo->SD_csd.WriteBlockPaPartial = (tmp & 0x20) >> 5;\r
1585   pCardInfo->SD_csd.Reserved3           = 0;\r
1586   pCardInfo->SD_csd.ContentProtectAppli = (tmp & 0x01);\r
1587   \r
1588   /* Byte 14 */\r
1589   tmp = (uint8_t)((hsd->CSD[3] & 0x0000FF00) >> 8);\r
1590   pCardInfo->SD_csd.FileFormatGrouop = (tmp & 0x80) >> 7;\r
1591   pCardInfo->SD_csd.CopyFlag         = (tmp & 0x40) >> 6;\r
1592   pCardInfo->SD_csd.PermWrProtect    = (tmp & 0x20) >> 5;\r
1593   pCardInfo->SD_csd.TempWrProtect    = (tmp & 0x10) >> 4;\r
1594   pCardInfo->SD_csd.FileFormat       = (tmp & 0x0C) >> 2;\r
1595   pCardInfo->SD_csd.ECC              = (tmp & 0x03);\r
1596   \r
1597   /* Byte 15 */\r
1598   tmp = (uint8_t)(hsd->CSD[3] & 0x000000FF);\r
1599   pCardInfo->SD_csd.CSD_CRC   = (tmp & 0xFE) >> 1;\r
1600   pCardInfo->SD_csd.Reserved4 = 1;\r
1601   \r
1602   /* Byte 0 */\r
1603   tmp = (uint8_t)((hsd->CID[0] & 0xFF000000) >> 24);\r
1604   pCardInfo->SD_cid.ManufacturerID = tmp;\r
1605   \r
1606   /* Byte 1 */\r
1607   tmp = (uint8_t)((hsd->CID[0] & 0x00FF0000) >> 16);\r
1608   pCardInfo->SD_cid.OEM_AppliID = tmp << 8;\r
1609   \r
1610   /* Byte 2 */\r
1611   tmp = (uint8_t)((hsd->CID[0] & 0x000000FF00) >> 8);\r
1612   pCardInfo->SD_cid.OEM_AppliID |= tmp;\r
1613   \r
1614   /* Byte 3 */\r
1615   tmp = (uint8_t)(hsd->CID[0] & 0x000000FF);\r
1616   pCardInfo->SD_cid.ProdName1 = tmp << 24;\r
1617   \r
1618   /* Byte 4 */\r
1619   tmp = (uint8_t)((hsd->CID[1] & 0xFF000000) >> 24);\r
1620   pCardInfo->SD_cid.ProdName1 |= tmp << 16;\r
1621   \r
1622   /* Byte 5 */\r
1623   tmp = (uint8_t)((hsd->CID[1] & 0x00FF0000) >> 16);\r
1624   pCardInfo->SD_cid.ProdName1 |= tmp << 8;\r
1625   \r
1626   /* Byte 6 */\r
1627   tmp = (uint8_t)((hsd->CID[1] & 0x0000FF00) >> 8);\r
1628   pCardInfo->SD_cid.ProdName1 |= tmp;\r
1629   \r
1630   /* Byte 7 */\r
1631   tmp = (uint8_t)(hsd->CID[1] & 0x000000FF);\r
1632   pCardInfo->SD_cid.ProdName2 = tmp;\r
1633   \r
1634   /* Byte 8 */\r
1635   tmp = (uint8_t)((hsd->CID[2] & 0xFF000000) >> 24);\r
1636   pCardInfo->SD_cid.ProdRev = tmp;\r
1637   \r
1638   /* Byte 9 */\r
1639   tmp = (uint8_t)((hsd->CID[2] & 0x00FF0000) >> 16);\r
1640   pCardInfo->SD_cid.ProdSN = tmp << 24;\r
1641   \r
1642   /* Byte 10 */\r
1643   tmp = (uint8_t)((hsd->CID[2] & 0x0000FF00) >> 8);\r
1644   pCardInfo->SD_cid.ProdSN |= tmp << 16;\r
1645   \r
1646   /* Byte 11 */\r
1647   tmp = (uint8_t)(hsd->CID[2] & 0x000000FF);\r
1648   pCardInfo->SD_cid.ProdSN |= tmp << 8;\r
1649   \r
1650   /* Byte 12 */\r
1651   tmp = (uint8_t)((hsd->CID[3] & 0xFF000000) >> 24);\r
1652   pCardInfo->SD_cid.ProdSN |= tmp;\r
1653   \r
1654   /* Byte 13 */\r
1655   tmp = (uint8_t)((hsd->CID[3] & 0x00FF0000) >> 16);\r
1656   pCardInfo->SD_cid.Reserved1   |= (tmp & 0xF0) >> 4;\r
1657   pCardInfo->SD_cid.ManufactDate = (tmp & 0x0F) << 8;\r
1658   \r
1659   /* Byte 14 */\r
1660   tmp = (uint8_t)((hsd->CID[3] & 0x0000FF00) >> 8);\r
1661   pCardInfo->SD_cid.ManufactDate |= tmp;\r
1662   \r
1663   /* Byte 15 */\r
1664   tmp = (uint8_t)(hsd->CID[3] & 0x000000FF);\r
1665   pCardInfo->SD_cid.CID_CRC   = (tmp & 0xFE) >> 1;\r
1666   pCardInfo->SD_cid.Reserved2 = 1;\r
1667   \r
1668   return errorstate;\r
1669 }\r
1670 \r
1671 /**\r
1672   * @brief  Enables wide bus operation for the requested card if supported by \r
1673   *         card.\r
1674   * @param  hsd: SD handle       \r
1675   * @param  WideMode: Specifies the SD card wide bus mode \r
1676   *          This parameter can be one of the following values:\r
1677   *            @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer (Only for MMC)\r
1678   *            @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer\r
1679   *            @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer\r
1680   * @retval SD Card error state\r
1681   */\r
1682 HAL_SD_ErrorTypedef HAL_SD_WideBusOperation_Config(SD_HandleTypeDef *hsd, uint32_t WideMode)\r
1683 {\r
1684   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
1685   SDMMC_InitTypeDef tmpinit;\r
1686   \r
1687   /* MMC Card does not support this feature */\r
1688   if (hsd->CardType == MULTIMEDIA_CARD)\r
1689   {\r
1690     errorstate = SD_UNSUPPORTED_FEATURE;\r
1691     \r
1692     return errorstate;\r
1693   }\r
1694   else if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\\r
1695     (hsd->CardType == HIGH_CAPACITY_SD_CARD))\r
1696   {\r
1697     if (WideMode == SDMMC_BUS_WIDE_8B)\r
1698     {\r
1699       errorstate = SD_UNSUPPORTED_FEATURE;\r
1700     }\r
1701     else if (WideMode == SDMMC_BUS_WIDE_4B)\r
1702     {\r
1703       errorstate = SD_WideBus_Enable(hsd);\r
1704     }\r
1705     else if (WideMode == SDMMC_BUS_WIDE_1B)\r
1706     {\r
1707       errorstate = SD_WideBus_Disable(hsd);\r
1708     }\r
1709     else\r
1710     {\r
1711       /* WideMode is not a valid argument*/\r
1712       errorstate = SD_INVALID_PARAMETER;\r
1713     }\r
1714       \r
1715     if (errorstate == SD_OK)\r
1716     {\r
1717       /* Configure the SDMMC peripheral */\r
1718       tmpinit.ClockEdge           = hsd->Init.ClockEdge;\r
1719       tmpinit.ClockBypass         = hsd->Init.ClockBypass;\r
1720       tmpinit.ClockPowerSave      = hsd->Init.ClockPowerSave;\r
1721       tmpinit.BusWide             = WideMode;\r
1722       tmpinit.HardwareFlowControl = hsd->Init.HardwareFlowControl;\r
1723       tmpinit.ClockDiv            = hsd->Init.ClockDiv;\r
1724       SDMMC_Init(hsd->Instance, tmpinit);\r
1725     }\r
1726   }\r
1727   \r
1728   return errorstate;\r
1729 }\r
1730 \r
1731 /**\r
1732   * @brief  Aborts an ongoing data transfer.\r
1733   * @param  hsd: SD handle\r
1734   * @retval SD Card error state\r
1735   */\r
1736 HAL_SD_ErrorTypedef HAL_SD_StopTransfer(SD_HandleTypeDef *hsd)\r
1737 {\r
1738   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
1739   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
1740   \r
1741   /* Send CMD12 STOP_TRANSMISSION  */\r
1742   sdmmc_cmdinitstructure.Argument         = 0;\r
1743   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_STOP_TRANSMISSION;\r
1744   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
1745   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
1746   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
1747   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
1748   \r
1749   /* Check for error conditions */\r
1750   errorstate = SD_CmdResp1Error(hsd, SD_CMD_STOP_TRANSMISSION);\r
1751   \r
1752   return errorstate;\r
1753 }\r
1754 \r
1755 /**\r
1756   * @brief  Switches the SD card to High Speed mode.\r
1757   *         This API must be used after "Transfer State"\r
1758   * @note   This operation should be followed by the configuration \r
1759   *         of PLL to have SDMMCCK clock between 67 and 75 MHz\r
1760   * @param  hsd: SD handle\r
1761   * @retval SD Card error state\r
1762   */\r
1763 HAL_SD_ErrorTypedef HAL_SD_HighSpeed (SD_HandleTypeDef *hsd)\r
1764 {\r
1765   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
1766   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
1767   SDMMC_DataInitTypeDef sdmmc_datainitstructure;\r
1768   \r
1769   uint8_t SD_hs[64]  = {0};\r
1770   uint32_t SD_scr[2] = {0, 0};\r
1771   uint32_t SD_SPEC   = 0 ;\r
1772   uint32_t count = 0, *tempbuff = (uint32_t *)SD_hs;\r
1773   \r
1774   /* Initialize the Data control register */\r
1775   hsd->Instance->DCTRL = 0;\r
1776   \r
1777   /* Get SCR Register */\r
1778   errorstate = SD_FindSCR(hsd, SD_scr);\r
1779   \r
1780   if (errorstate != SD_OK)\r
1781   {\r
1782     return errorstate;\r
1783   }\r
1784   \r
1785   /* Test the Version supported by the card*/ \r
1786   SD_SPEC = (SD_scr[1]  & 0x01000000) | (SD_scr[1]  & 0x02000000);\r
1787   \r
1788   if (SD_SPEC != SD_ALLZERO)\r
1789   {\r
1790     /* Set Block Size for Card */\r
1791     sdmmc_cmdinitstructure.Argument         = (uint32_t)64;\r
1792     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;\r
1793     sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
1794     sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
1795     sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
1796     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
1797     \r
1798     /* Check for error conditions */\r
1799     errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
1800     \r
1801     if (errorstate != SD_OK)\r
1802     {\r
1803       return errorstate;\r
1804     }\r
1805     \r
1806     /* Configure the SD DPSM (Data Path State Machine) */\r
1807     sdmmc_datainitstructure.DataTimeOut   = SD_DATATIMEOUT;\r
1808     sdmmc_datainitstructure.DataLength    = 64;\r
1809     sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B ;\r
1810     sdmmc_datainitstructure.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;\r
1811     sdmmc_datainitstructure.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;\r
1812     sdmmc_datainitstructure.DPSM          = SDMMC_DPSM_ENABLE;\r
1813     SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);\r
1814     \r
1815     /* Send CMD6 switch mode */\r
1816     sdmmc_cmdinitstructure.Argument         = 0x80FFFF01;\r
1817     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_HS_SWITCH;\r
1818     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure); \r
1819     \r
1820     /* Check for error conditions */\r
1821     errorstate = SD_CmdResp1Error(hsd, SD_CMD_HS_SWITCH);\r
1822     \r
1823     if (errorstate != SD_OK)\r
1824     {\r
1825       return errorstate;\r
1826     }\r
1827         \r
1828     while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))\r
1829     {\r
1830       if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF))\r
1831       {\r
1832         for (count = 0; count < 8; count++)\r
1833         {\r
1834           *(tempbuff + count) = SDMMC_ReadFIFO(hsd->Instance);\r
1835         }\r
1836         \r
1837         tempbuff += 8;\r
1838       }\r
1839     }\r
1840     \r
1841     if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT))\r
1842     {\r
1843       __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);\r
1844       \r
1845       errorstate = SD_DATA_TIMEOUT;\r
1846       \r
1847       return errorstate;\r
1848     }\r
1849     else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL))\r
1850     {\r
1851       __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);\r
1852       \r
1853       errorstate = SD_DATA_CRC_FAIL;\r
1854       \r
1855       return errorstate;\r
1856     }\r
1857     else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR))\r
1858     {\r
1859       __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR);\r
1860       \r
1861       errorstate = SD_RX_OVERRUN;\r
1862       \r
1863       return errorstate;\r
1864     }\r
1865     else\r
1866     {\r
1867       /* No error flag set */\r
1868     }\r
1869         \r
1870     count = SD_DATATIMEOUT;\r
1871     \r
1872     while ((__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL)) && (count > 0))\r
1873     {\r
1874       *tempbuff = SDMMC_ReadFIFO(hsd->Instance);\r
1875       tempbuff++;\r
1876       count--;\r
1877     }\r
1878     \r
1879     /* Clear all the static flags */\r
1880     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
1881     \r
1882     /* Test if the switch mode HS is ok */\r
1883     if ((SD_hs[13]& 2) != 2)\r
1884     {\r
1885       errorstate = SD_UNSUPPORTED_FEATURE;\r
1886     } \r
1887   }\r
1888   \r
1889   return errorstate;\r
1890 }\r
1891 \r
1892 /**\r
1893   * @}\r
1894   */\r
1895 \r
1896 /** @addtogroup SD_Exported_Functions_Group4\r
1897  *  @brief   Peripheral State functions \r
1898  *\r
1899 @verbatim   \r
1900   ==============================================================================\r
1901                       ##### Peripheral State functions #####\r
1902   ==============================================================================  \r
1903   [..]\r
1904     This subsection permits to get in runtime the status of the peripheral \r
1905     and the data flow.\r
1906 \r
1907 @endverbatim\r
1908   * @{\r
1909   */\r
1910 \r
1911 /**\r
1912   * @brief  Returns the current SD card's status.\r
1913   * @param  hsd: SD handle\r
1914   * @param  pSDstatus: Pointer to the buffer that will contain the SD card status \r
1915   *         SD Status register)\r
1916   * @retval SD Card error state\r
1917   */\r
1918 HAL_SD_ErrorTypedef HAL_SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus)\r
1919 {\r
1920   SDMMC_CmdInitTypeDef  sdmmc_cmdinitstructure;\r
1921   SDMMC_DataInitTypeDef sdmmc_datainitstructure;\r
1922   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
1923   uint32_t count = 0;\r
1924   \r
1925   /* Check SD response */\r
1926   if ((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)\r
1927   {\r
1928     errorstate = SD_LOCK_UNLOCK_FAILED;\r
1929     \r
1930     return errorstate;\r
1931   }\r
1932   \r
1933   /* Set block size for card if it is not equal to current block size for card */\r
1934   sdmmc_cmdinitstructure.Argument         = 64;\r
1935   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;\r
1936   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
1937   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
1938   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
1939   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
1940   \r
1941   /* Check for error conditions */\r
1942   errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
1943   \r
1944   if (errorstate != SD_OK)\r
1945   {\r
1946     return errorstate;\r
1947   }\r
1948   \r
1949   /* Send CMD55 */\r
1950   sdmmc_cmdinitstructure.Argument         = (uint32_t)(hsd->RCA << 16);\r
1951   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_APP_CMD;\r
1952   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
1953   \r
1954   /* Check for error conditions */\r
1955   errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
1956   \r
1957   if (errorstate != SD_OK)\r
1958   {\r
1959     return errorstate;\r
1960   }\r
1961   \r
1962   /* Configure the SD DPSM (Data Path State Machine) */ \r
1963   sdmmc_datainitstructure.DataTimeOut   = SD_DATATIMEOUT;\r
1964   sdmmc_datainitstructure.DataLength    = 64;\r
1965   sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B;\r
1966   sdmmc_datainitstructure.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;\r
1967   sdmmc_datainitstructure.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;\r
1968   sdmmc_datainitstructure.DPSM          = SDMMC_DPSM_ENABLE;\r
1969   SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);\r
1970   \r
1971   /* Send ACMD13 (SD_APP_STAUS)  with argument as card's RCA */\r
1972   sdmmc_cmdinitstructure.Argument         = 0;\r
1973   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SD_APP_STATUS;\r
1974   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
1975   \r
1976   /* Check for error conditions */\r
1977   errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_APP_STATUS);\r
1978   \r
1979   if (errorstate != SD_OK)\r
1980   {\r
1981     return errorstate;\r
1982   }\r
1983   \r
1984   /* Get status data */\r
1985   while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))\r
1986   {\r
1987     if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF))\r
1988     {\r
1989       for (count = 0; count < 8; count++)\r
1990       {\r
1991         *(pSDstatus + count) = SDMMC_ReadFIFO(hsd->Instance);\r
1992       }\r
1993       \r
1994       pSDstatus += 8;\r
1995     }\r
1996   }\r
1997   \r
1998   if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT))\r
1999   {\r
2000     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);\r
2001     \r
2002     errorstate = SD_DATA_TIMEOUT;\r
2003     \r
2004     return errorstate;\r
2005   }\r
2006   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL))\r
2007   {\r
2008     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);\r
2009     \r
2010     errorstate = SD_DATA_CRC_FAIL;\r
2011     \r
2012     return errorstate;\r
2013   }\r
2014   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR))\r
2015   {\r
2016     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR);\r
2017     \r
2018     errorstate = SD_RX_OVERRUN;\r
2019     \r
2020     return errorstate;\r
2021   }\r
2022   else\r
2023   {\r
2024     /* No error flag set */\r
2025   }  \r
2026   \r
2027   count = SD_DATATIMEOUT;\r
2028   while ((__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL)) && (count > 0))\r
2029   {\r
2030     *pSDstatus = SDMMC_ReadFIFO(hsd->Instance);\r
2031     pSDstatus++;\r
2032     count--;\r
2033   }\r
2034   \r
2035   /* Clear all the static status flags*/\r
2036   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
2037   \r
2038   return errorstate;\r
2039 }\r
2040 \r
2041 /**\r
2042   * @brief  Gets the current sd card data status.\r
2043   * @param  hsd: SD handle\r
2044   * @retval Data Transfer state\r
2045   */\r
2046 HAL_SD_TransferStateTypedef HAL_SD_GetStatus(SD_HandleTypeDef *hsd)\r
2047 {\r
2048   HAL_SD_CardStateTypedef cardstate =  SD_CARD_TRANSFER;\r
2049 \r
2050   /* Get SD card state */\r
2051   cardstate = SD_GetState(hsd);\r
2052   \r
2053   /* Find SD status according to card state*/\r
2054   if (cardstate == SD_CARD_TRANSFER)\r
2055   {\r
2056     return SD_TRANSFER_OK;\r
2057   }\r
2058   else if(cardstate == SD_CARD_ERROR)\r
2059   {\r
2060     return SD_TRANSFER_ERROR;\r
2061   }\r
2062   else\r
2063   {\r
2064     return SD_TRANSFER_BUSY;\r
2065   }\r
2066 }\r
2067 \r
2068 /**\r
2069   * @brief  Gets the SD card status.\r
2070   * @param  hsd: SD handle      \r
2071   * @param  pCardStatus: Pointer to the HAL_SD_CardStatusTypedef structure that \r
2072   *         will contain the SD card status information \r
2073   * @retval SD Card error state\r
2074   */\r
2075 HAL_SD_ErrorTypedef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypedef *pCardStatus)\r
2076 {\r
2077   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2078   uint32_t tmp = 0;\r
2079   uint32_t sd_status[16];\r
2080   \r
2081   errorstate = HAL_SD_SendSDStatus(hsd, sd_status);\r
2082   \r
2083   if (errorstate  != SD_OK)\r
2084   {\r
2085     return errorstate;\r
2086   }\r
2087   \r
2088   /* Byte 0 */\r
2089   tmp = (sd_status[0] & 0xC0) >> 6;\r
2090   pCardStatus->DAT_BUS_WIDTH = (uint8_t)tmp;\r
2091   \r
2092   /* Byte 0 */\r
2093   tmp = (sd_status[0] & 0x20) >> 5;\r
2094   pCardStatus->SECURED_MODE = (uint8_t)tmp;\r
2095   \r
2096   /* Byte 2 */\r
2097   tmp = (sd_status[2] & 0xFF);\r
2098   pCardStatus->SD_CARD_TYPE = (uint8_t)(tmp << 8);\r
2099   \r
2100   /* Byte 3 */\r
2101   tmp = (sd_status[3] & 0xFF);\r
2102   pCardStatus->SD_CARD_TYPE |= (uint8_t)tmp;\r
2103   \r
2104   /* Byte 4 */\r
2105   tmp = (sd_status[4] & 0xFF);\r
2106   pCardStatus->SIZE_OF_PROTECTED_AREA = (uint8_t)(tmp << 24);\r
2107   \r
2108   /* Byte 5 */\r
2109   tmp = (sd_status[5] & 0xFF);\r
2110   pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(tmp << 16);\r
2111   \r
2112   /* Byte 6 */\r
2113   tmp = (sd_status[6] & 0xFF);\r
2114   pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(tmp << 8);\r
2115   \r
2116   /* Byte 7 */\r
2117   tmp = (sd_status[7] & 0xFF);\r
2118   pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)tmp;\r
2119   \r
2120   /* Byte 8 */\r
2121   tmp = (sd_status[8] & 0xFF);\r
2122   pCardStatus->SPEED_CLASS = (uint8_t)tmp;\r
2123   \r
2124   /* Byte 9 */\r
2125   tmp = (sd_status[9] & 0xFF);\r
2126   pCardStatus->PERFORMANCE_MOVE = (uint8_t)tmp;\r
2127   \r
2128   /* Byte 10 */\r
2129   tmp = (sd_status[10] & 0xF0) >> 4;\r
2130   pCardStatus->AU_SIZE = (uint8_t)tmp;\r
2131   \r
2132   /* Byte 11 */\r
2133   tmp = (sd_status[11] & 0xFF);\r
2134   pCardStatus->ERASE_SIZE = (uint8_t)(tmp << 8);\r
2135   \r
2136   /* Byte 12 */\r
2137   tmp = (sd_status[12] & 0xFF);\r
2138   pCardStatus->ERASE_SIZE |= (uint8_t)tmp;\r
2139   \r
2140   /* Byte 13 */\r
2141   tmp = (sd_status[13] & 0xFC) >> 2;\r
2142   pCardStatus->ERASE_TIMEOUT = (uint8_t)tmp;\r
2143   \r
2144   /* Byte 13 */\r
2145   tmp = (sd_status[13] & 0x3);\r
2146   pCardStatus->ERASE_OFFSET = (uint8_t)tmp;\r
2147   \r
2148   return errorstate;\r
2149 }\r
2150          \r
2151 /**\r
2152   * @}\r
2153   */\r
2154   \r
2155 /**\r
2156   * @}\r
2157   */\r
2158   \r
2159 /* Private function ----------------------------------------------------------*/  \r
2160 /** @addtogroup SD_Private_Functions\r
2161   * @{\r
2162   */\r
2163   \r
2164 /**\r
2165   * @brief  SD DMA transfer complete Rx callback.\r
2166   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
2167   *                the configuration information for the specified DMA module.\r
2168   * @retval None\r
2169   */\r
2170 static void SD_DMA_RxCplt(DMA_HandleTypeDef *hdma)\r
2171 {\r
2172   SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;\r
2173   \r
2174   /* DMA transfer is complete */\r
2175   hsd->DmaTransferCplt = 1;\r
2176   \r
2177   /* Wait until SD transfer is complete */\r
2178   while(hsd->SdTransferCplt == 0)\r
2179   {\r
2180   }\r
2181   \r
2182   /* Disable the DMA channel */\r
2183   HAL_DMA_Abort(hdma);\r
2184 \r
2185   /* Transfer complete user callback */\r
2186   HAL_SD_DMA_RxCpltCallback(hsd->hdmarx);   \r
2187 }\r
2188 \r
2189 /**\r
2190   * @brief  SD DMA transfer Error Rx callback.\r
2191   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
2192   *                the configuration information for the specified DMA module.\r
2193   * @retval None\r
2194   */\r
2195 static void SD_DMA_RxError(DMA_HandleTypeDef *hdma)\r
2196 {\r
2197   SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;\r
2198   \r
2199   /* Transfer complete user callback */\r
2200   HAL_SD_DMA_RxErrorCallback(hsd->hdmarx);\r
2201 }\r
2202 \r
2203 /**\r
2204   * @brief  SD DMA transfer complete Tx callback.\r
2205   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
2206   *                the configuration information for the specified DMA module.\r
2207   * @retval None\r
2208   */\r
2209 static void SD_DMA_TxCplt(DMA_HandleTypeDef *hdma)\r
2210 {\r
2211   SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;\r
2212   \r
2213   /* DMA transfer is complete */\r
2214   hsd->DmaTransferCplt = 1;\r
2215   \r
2216   /* Wait until SD transfer is complete */\r
2217   while(hsd->SdTransferCplt == 0)\r
2218   {\r
2219   }\r
2220  \r
2221   /* Disable the DMA channel */\r
2222   HAL_DMA_Abort(hdma);\r
2223 \r
2224   /* Transfer complete user callback */\r
2225   HAL_SD_DMA_TxCpltCallback(hsd->hdmatx);  \r
2226 }\r
2227 \r
2228 /**\r
2229   * @brief  SD DMA transfer Error Tx callback.\r
2230   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains\r
2231   *                the configuration information for the specified DMA module.\r
2232   * @retval None\r
2233   */\r
2234 static void SD_DMA_TxError(DMA_HandleTypeDef *hdma)\r
2235 {\r
2236   SD_HandleTypeDef *hsd = ( SD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
2237   \r
2238   /* Transfer complete user callback */\r
2239   HAL_SD_DMA_TxErrorCallback(hsd->hdmatx);\r
2240 }\r
2241 \r
2242 /**\r
2243   * @brief  Returns the SD current state.\r
2244   * @param  hsd: SD handle\r
2245   * @retval SD card current state\r
2246   */\r
2247 static HAL_SD_CardStateTypedef SD_GetState(SD_HandleTypeDef *hsd)\r
2248 {\r
2249   uint32_t resp1 = 0;\r
2250   \r
2251   if (SD_SendStatus(hsd, &resp1) != SD_OK)\r
2252   {\r
2253     return SD_CARD_ERROR;\r
2254   }\r
2255   else\r
2256   {\r
2257     return (HAL_SD_CardStateTypedef)((resp1 >> 9) & 0x0F);\r
2258   }\r
2259 }\r
2260 \r
2261 /**\r
2262   * @brief  Initializes all cards or single card as the case may be Card(s) come \r
2263   *         into standby state.\r
2264   * @param  hsd: SD handle\r
2265   * @retval SD Card error state\r
2266   */\r
2267 static HAL_SD_ErrorTypedef SD_Initialize_Cards(SD_HandleTypeDef *hsd)\r
2268 {\r
2269   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure; \r
2270   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2271   uint16_t sd_rca = 1;\r
2272   \r
2273   if(SDMMC_GetPowerState(hsd->Instance) == 0) /* Power off */\r
2274   {\r
2275     errorstate = SD_REQUEST_NOT_APPLICABLE;\r
2276     \r
2277     return errorstate;\r
2278   }\r
2279   \r
2280   if(hsd->CardType != SECURE_DIGITAL_IO_CARD)\r
2281   {\r
2282     /* Send CMD2 ALL_SEND_CID */\r
2283     sdmmc_cmdinitstructure.Argument         = 0;\r
2284     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_ALL_SEND_CID;\r
2285     sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_LONG;\r
2286     sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
2287     sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
2288     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2289     \r
2290     /* Check for error conditions */\r
2291     errorstate = SD_CmdResp2Error(hsd);\r
2292     \r
2293     if(errorstate != SD_OK)\r
2294     {\r
2295       return errorstate;\r
2296     }\r
2297     \r
2298     /* Get Card identification number data */\r
2299     hsd->CID[0] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);\r
2300     hsd->CID[1] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2);\r
2301     hsd->CID[2] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3);\r
2302     hsd->CID[3] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4);\r
2303   }\r
2304   \r
2305   if((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1)    || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\\r
2306      (hsd->CardType == SECURE_DIGITAL_IO_COMBO_CARD) || (hsd->CardType == HIGH_CAPACITY_SD_CARD))\r
2307   {\r
2308     /* Send CMD3 SET_REL_ADDR with argument 0 */\r
2309     /* SD Card publishes its RCA. */\r
2310     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SET_REL_ADDR;\r
2311     sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
2312     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2313     \r
2314     /* Check for error conditions */\r
2315     errorstate = SD_CmdResp6Error(hsd, SD_CMD_SET_REL_ADDR, &sd_rca);\r
2316     \r
2317     if(errorstate != SD_OK)\r
2318     {\r
2319       return errorstate;\r
2320     }\r
2321   }\r
2322   \r
2323   if (hsd->CardType != SECURE_DIGITAL_IO_CARD)\r
2324   {\r
2325     /* Get the SD card RCA */\r
2326     hsd->RCA = sd_rca;\r
2327     \r
2328     /* Send CMD9 SEND_CSD with argument as card's RCA */\r
2329     sdmmc_cmdinitstructure.Argument         = (uint32_t)(hsd->RCA << 16);\r
2330     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SEND_CSD;\r
2331     sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_LONG;\r
2332     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2333     \r
2334     /* Check for error conditions */\r
2335     errorstate = SD_CmdResp2Error(hsd);\r
2336     \r
2337     if(errorstate != SD_OK)\r
2338     {\r
2339       return errorstate;\r
2340     }\r
2341     \r
2342     /* Get Card Specific Data */\r
2343     hsd->CSD[0] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);\r
2344     hsd->CSD[1] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2);\r
2345     hsd->CSD[2] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3);\r
2346     hsd->CSD[3] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4);\r
2347   }\r
2348   \r
2349   /* All cards are initialized */\r
2350   return errorstate;\r
2351 }\r
2352 \r
2353 /**\r
2354   * @brief  Selects od Deselects the corresponding card.\r
2355   * @param  hsd: SD handle\r
2356   * @param  addr: Address of the card to be selected  \r
2357   * @retval SD Card error state\r
2358   */\r
2359 static HAL_SD_ErrorTypedef SD_Select_Deselect(SD_HandleTypeDef *hsd, uint64_t addr)\r
2360 {\r
2361   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
2362   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2363   \r
2364   /* Send CMD7 SDMMC_SEL_DESEL_CARD */\r
2365   sdmmc_cmdinitstructure.Argument         = (uint32_t)addr;\r
2366   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SEL_DESEL_CARD;\r
2367   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
2368   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
2369   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
2370   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2371   \r
2372   /* Check for error conditions */\r
2373   errorstate = SD_CmdResp1Error(hsd, SD_CMD_SEL_DESEL_CARD);\r
2374   \r
2375   return errorstate;\r
2376 }\r
2377 \r
2378 /**\r
2379   * @brief  Enquires cards about their operating voltage and configures clock\r
2380   *         controls and stores SD information that will be needed in future\r
2381   *         in the SD handle.\r
2382   * @param  hsd: SD handle\r
2383   * @retval SD Card error state\r
2384   */\r
2385 static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd)\r
2386 {\r
2387   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure; \r
2388   __IO HAL_SD_ErrorTypedef errorstate = SD_OK; \r
2389   uint32_t response = 0, count = 0, validvoltage = 0;\r
2390   uint32_t sdtype = SD_STD_CAPACITY;\r
2391   \r
2392   /* Power ON Sequence -------------------------------------------------------*/\r
2393   /* Disable SDMMC Clock */\r
2394   __HAL_SD_SDMMC_DISABLE(hsd); \r
2395   \r
2396   /* Set Power State to ON */\r
2397   SDMMC_PowerState_ON(hsd->Instance);\r
2398 \r
2399   /* 1ms: required power up waiting time before starting the SD initialization \r
2400      sequence */\r
2401   HAL_Delay(1);\r
2402   \r
2403   /* Enable SDMMC Clock */\r
2404   __HAL_SD_SDMMC_ENABLE(hsd);\r
2405   \r
2406   /* CMD0: GO_IDLE_STATE -----------------------------------------------------*/\r
2407   /* No CMD response required */\r
2408   sdmmc_cmdinitstructure.Argument         = 0;\r
2409   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_GO_IDLE_STATE;\r
2410   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_NO;\r
2411   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
2412   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
2413   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2414   \r
2415   /* Check for error conditions */\r
2416   errorstate = SD_CmdError(hsd);\r
2417   \r
2418   if(errorstate != SD_OK)\r
2419   {\r
2420     /* CMD Response Timeout (wait for CMDSENT flag) */\r
2421     return errorstate;\r
2422   }\r
2423   \r
2424   /* CMD8: SEND_IF_COND ------------------------------------------------------*/\r
2425   /* Send CMD8 to verify SD card interface operating condition */\r
2426   /* Argument: - [31:12]: Reserved (shall be set to '0')\r
2427   - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)\r
2428   - [7:0]: Check Pattern (recommended 0xAA) */\r
2429   /* CMD Response: R7 */\r
2430   sdmmc_cmdinitstructure.Argument         = SD_CHECK_PATTERN;\r
2431   sdmmc_cmdinitstructure.CmdIndex         = SD_SDMMC_SEND_IF_COND;\r
2432   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
2433   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2434   \r
2435   /* Check for error conditions */ \r
2436   errorstate = SD_CmdResp7Error(hsd);\r
2437   \r
2438   if (errorstate == SD_OK)\r
2439   {\r
2440     /* SD Card 2.0 */\r
2441     hsd->CardType = STD_CAPACITY_SD_CARD_V2_0; \r
2442     sdtype        = SD_HIGH_CAPACITY;\r
2443   }\r
2444   \r
2445   /* Send CMD55 */\r
2446   sdmmc_cmdinitstructure.Argument         = 0;\r
2447   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_APP_CMD;\r
2448   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2449   \r
2450   /* Check for error conditions */\r
2451   errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
2452   \r
2453   /* If errorstate is Command Timeout, it is a MMC card */\r
2454   /* If errorstate is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch)\r
2455      or SD card 1.x */\r
2456   if(errorstate == SD_OK)\r
2457   {\r
2458     /* SD CARD */\r
2459     /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */\r
2460     while((!validvoltage) && (count < SD_MAX_VOLT_TRIAL))\r
2461     {\r
2462       \r
2463       /* SEND CMD55 APP_CMD with RCA as 0 */\r
2464       sdmmc_cmdinitstructure.Argument         = 0;\r
2465       sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_APP_CMD;\r
2466       sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
2467       sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
2468       sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
2469       SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2470       \r
2471       /* Check for error conditions */\r
2472       errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
2473       \r
2474       if(errorstate != SD_OK)\r
2475       {\r
2476         return errorstate;\r
2477       }\r
2478       \r
2479       /* Send CMD41 */\r
2480       sdmmc_cmdinitstructure.Argument         = SD_VOLTAGE_WINDOW_SD | sdtype;\r
2481       sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SD_APP_OP_COND;\r
2482       sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
2483       sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
2484       sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
2485       SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2486       \r
2487       /* Check for error conditions */\r
2488       errorstate = SD_CmdResp3Error(hsd);\r
2489       \r
2490       if(errorstate != SD_OK)\r
2491       {\r
2492         return errorstate;\r
2493       }\r
2494       \r
2495       /* Get command response */\r
2496       response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);\r
2497       \r
2498       /* Get operating voltage*/\r
2499       validvoltage = (((response >> 31) == 1) ? 1 : 0);\r
2500       \r
2501       count++;\r
2502     }\r
2503     \r
2504     if(count >= SD_MAX_VOLT_TRIAL)\r
2505     {\r
2506       errorstate = SD_INVALID_VOLTRANGE;\r
2507       \r
2508       return errorstate;\r
2509     }\r
2510     \r
2511     if((response & SD_HIGH_CAPACITY) == SD_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */\r
2512     {\r
2513       hsd->CardType = HIGH_CAPACITY_SD_CARD;\r
2514     }\r
2515     \r
2516   } /* else MMC Card */\r
2517   \r
2518   return errorstate;\r
2519 }\r
2520 \r
2521 /**\r
2522   * @brief  Turns the SDMMC output signals off.\r
2523   * @param  hsd: SD handle\r
2524   * @retval SD Card error state\r
2525   */\r
2526 static HAL_SD_ErrorTypedef SD_PowerOFF(SD_HandleTypeDef *hsd)\r
2527 {\r
2528   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2529   \r
2530   /* Set Power State to OFF */\r
2531   SDMMC_PowerState_OFF(hsd->Instance);\r
2532   \r
2533   return errorstate;\r
2534 }\r
2535 \r
2536 /**\r
2537   * @brief  Returns the current card's status.\r
2538   * @param  hsd: SD handle\r
2539   * @param  pCardStatus: pointer to the buffer that will contain the SD card \r
2540   *         status (Card Status register)  \r
2541   * @retval SD Card error state\r
2542   */\r
2543 static HAL_SD_ErrorTypedef SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus)\r
2544 {\r
2545   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
2546   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2547   \r
2548   if(pCardStatus == NULL)\r
2549   {\r
2550     errorstate = SD_INVALID_PARAMETER;\r
2551     \r
2552     return errorstate;\r
2553   }\r
2554   \r
2555   /* Send Status command */\r
2556   sdmmc_cmdinitstructure.Argument         = (uint32_t)(hsd->RCA << 16);\r
2557   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SEND_STATUS;\r
2558   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
2559   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
2560   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
2561   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2562   \r
2563   /* Check for error conditions */\r
2564   errorstate = SD_CmdResp1Error(hsd, SD_CMD_SEND_STATUS);\r
2565   \r
2566   if(errorstate != SD_OK)\r
2567   {\r
2568     return errorstate;\r
2569   }\r
2570   \r
2571   /* Get SD card status */\r
2572   *pCardStatus = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);\r
2573   \r
2574   return errorstate;\r
2575 }\r
2576 \r
2577 /**\r
2578   * @brief  Checks for error conditions for CMD0.\r
2579   * @param  hsd: SD handle\r
2580   * @retval SD Card error state\r
2581   */\r
2582 static HAL_SD_ErrorTypedef SD_CmdError(SD_HandleTypeDef *hsd)\r
2583 {\r
2584   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2585   uint32_t timeout, tmp;\r
2586   \r
2587   timeout = SDMMC_CMD0TIMEOUT;\r
2588   \r
2589   tmp = __HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CMDSENT);\r
2590     \r
2591   while((timeout > 0) && (!tmp))\r
2592   {\r
2593     tmp = __HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CMDSENT);\r
2594     timeout--;\r
2595   }\r
2596   \r
2597   if(timeout == 0)\r
2598   {\r
2599     errorstate = SD_CMD_RSP_TIMEOUT;\r
2600     return errorstate;\r
2601   }\r
2602   \r
2603   /* Clear all the static flags */\r
2604   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
2605   \r
2606   return errorstate;\r
2607 }\r
2608 \r
2609 /**\r
2610   * @brief  Checks for error conditions for R7 response.\r
2611   * @param  hsd: SD handle\r
2612   * @retval SD Card error state\r
2613   */\r
2614 static HAL_SD_ErrorTypedef SD_CmdResp7Error(SD_HandleTypeDef *hsd)\r
2615 {\r
2616   HAL_SD_ErrorTypedef errorstate = SD_ERROR;\r
2617   uint32_t timeout = SDMMC_CMD0TIMEOUT, tmp;\r
2618   \r
2619   tmp = __HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT); \r
2620   \r
2621   while((!tmp) && (timeout > 0))\r
2622   {\r
2623     tmp = __HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT);\r
2624     timeout--;\r
2625   }\r
2626   \r
2627   tmp = __HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT); \r
2628   \r
2629   if((timeout == 0) || tmp)\r
2630   {\r
2631     /* Card is not V2.0 compliant or card does not support the set voltage range */\r
2632     errorstate = SD_CMD_RSP_TIMEOUT;\r
2633     \r
2634     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);\r
2635     \r
2636     return errorstate;\r
2637   }\r
2638   \r
2639   if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CMDREND))\r
2640   {\r
2641     /* Card is SD V2.0 compliant */\r
2642     errorstate = SD_OK;\r
2643     \r
2644     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CMDREND);\r
2645     \r
2646     return errorstate;\r
2647   }\r
2648   \r
2649   return errorstate;\r
2650 }\r
2651 \r
2652 /**\r
2653   * @brief  Checks for error conditions for R1 response.\r
2654   * @param  hsd: SD handle\r
2655   * @param  SD_CMD: The sent command index  \r
2656   * @retval SD Card error state\r
2657   */\r
2658 static HAL_SD_ErrorTypedef SD_CmdResp1Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD)\r
2659 {\r
2660   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2661   uint32_t response_r1;\r
2662   \r
2663   while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT))\r
2664   {\r
2665   }\r
2666   \r
2667   if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT))\r
2668   {\r
2669     errorstate = SD_CMD_RSP_TIMEOUT;\r
2670     \r
2671     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);\r
2672     \r
2673     return errorstate;\r
2674   }\r
2675   else if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL))\r
2676   {\r
2677     errorstate = SD_CMD_CRC_FAIL;\r
2678     \r
2679     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CCRCFAIL);\r
2680     \r
2681     return errorstate;\r
2682   }\r
2683   \r
2684   /* Check response received is of desired command */\r
2685   if(SDMMC_GetCommandResponse(hsd->Instance) != SD_CMD)\r
2686   {\r
2687     errorstate = SD_ILLEGAL_CMD;\r
2688     \r
2689     return errorstate;\r
2690   }\r
2691   \r
2692   /* Clear all the static flags */\r
2693   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
2694   \r
2695   /* We have received response, retrieve it for analysis  */\r
2696   response_r1 = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);\r
2697   \r
2698   if((response_r1 & SD_OCR_ERRORBITS) == SD_ALLZERO)\r
2699   {\r
2700     return errorstate;\r
2701   }\r
2702   \r
2703   if((response_r1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE)\r
2704   {\r
2705     return(SD_ADDR_OUT_OF_RANGE);\r
2706   }\r
2707   \r
2708   if((response_r1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED)\r
2709   {\r
2710     return(SD_ADDR_MISALIGNED);\r
2711   }\r
2712   \r
2713   if((response_r1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR)\r
2714   {\r
2715     return(SD_BLOCK_LEN_ERR);\r
2716   }\r
2717   \r
2718   if((response_r1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR)\r
2719   {\r
2720     return(SD_ERASE_SEQ_ERR);\r
2721   }\r
2722   \r
2723   if((response_r1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM)\r
2724   {\r
2725     return(SD_BAD_ERASE_PARAM);\r
2726   }\r
2727   \r
2728   if((response_r1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION)\r
2729   {\r
2730     return(SD_WRITE_PROT_VIOLATION);\r
2731   }\r
2732   \r
2733   if((response_r1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED)\r
2734   {\r
2735     return(SD_LOCK_UNLOCK_FAILED);\r
2736   }\r
2737   \r
2738   if((response_r1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED)\r
2739   {\r
2740     return(SD_COM_CRC_FAILED);\r
2741   }\r
2742   \r
2743   if((response_r1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD)\r
2744   {\r
2745     return(SD_ILLEGAL_CMD);\r
2746   }\r
2747   \r
2748   if((response_r1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED)\r
2749   {\r
2750     return(SD_CARD_ECC_FAILED);\r
2751   }\r
2752   \r
2753   if((response_r1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR)\r
2754   {\r
2755     return(SD_CC_ERROR);\r
2756   }\r
2757   \r
2758   if((response_r1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR)\r
2759   {\r
2760     return(SD_GENERAL_UNKNOWN_ERROR);\r
2761   }\r
2762   \r
2763   if((response_r1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN)\r
2764   {\r
2765     return(SD_STREAM_READ_UNDERRUN);\r
2766   }\r
2767   \r
2768   if((response_r1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN)\r
2769   {\r
2770     return(SD_STREAM_WRITE_OVERRUN);\r
2771   }\r
2772   \r
2773   if((response_r1 & SD_OCR_CID_CSD_OVERWRITE) == SD_OCR_CID_CSD_OVERWRITE)\r
2774   {\r
2775     return(SD_CID_CSD_OVERWRITE);\r
2776   }\r
2777   \r
2778   if((response_r1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP)\r
2779   {\r
2780     return(SD_WP_ERASE_SKIP);\r
2781   }\r
2782   \r
2783   if((response_r1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED)\r
2784   {\r
2785     return(SD_CARD_ECC_DISABLED);\r
2786   }\r
2787   \r
2788   if((response_r1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET)\r
2789   {\r
2790     return(SD_ERASE_RESET);\r
2791   }\r
2792   \r
2793   if((response_r1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR)\r
2794   {\r
2795     return(SD_AKE_SEQ_ERROR);\r
2796   }\r
2797   \r
2798   return errorstate;\r
2799 }\r
2800 \r
2801 /**\r
2802   * @brief  Checks for error conditions for R3 (OCR) response.\r
2803   * @param  hsd: SD handle\r
2804   * @retval SD Card error state\r
2805   */\r
2806 static HAL_SD_ErrorTypedef SD_CmdResp3Error(SD_HandleTypeDef *hsd)\r
2807 {\r
2808   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2809   \r
2810   while (!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT))\r
2811   {\r
2812   }\r
2813   \r
2814   if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT))\r
2815   {\r
2816     errorstate = SD_CMD_RSP_TIMEOUT;\r
2817     \r
2818     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);\r
2819     \r
2820     return errorstate;\r
2821   }\r
2822   \r
2823   /* Clear all the static flags */\r
2824   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
2825   \r
2826   return errorstate;\r
2827 }\r
2828 \r
2829 /**\r
2830   * @brief  Checks for error conditions for R2 (CID or CSD) response.\r
2831   * @param  hsd: SD handle\r
2832   * @retval SD Card error state\r
2833   */\r
2834 static HAL_SD_ErrorTypedef SD_CmdResp2Error(SD_HandleTypeDef *hsd)\r
2835 {\r
2836   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2837   \r
2838   while (!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT))\r
2839   {\r
2840   }\r
2841     \r
2842   if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT))\r
2843   {\r
2844     errorstate = SD_CMD_RSP_TIMEOUT;\r
2845     \r
2846     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);\r
2847     \r
2848     return errorstate;\r
2849   }\r
2850   else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL))\r
2851   {\r
2852     errorstate = SD_CMD_CRC_FAIL;\r
2853     \r
2854     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CCRCFAIL);\r
2855     \r
2856     return errorstate;\r
2857   }\r
2858   else\r
2859   {\r
2860     /* No error flag set */\r
2861   }  \r
2862   \r
2863   /* Clear all the static flags */\r
2864   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
2865   \r
2866   return errorstate;\r
2867 }\r
2868 \r
2869 /**\r
2870   * @brief  Checks for error conditions for R6 (RCA) response.\r
2871   * @param  hsd: SD handle\r
2872   * @param  SD_CMD: The sent command index\r
2873   * @param  pRCA: Pointer to the variable that will contain the SD card relative \r
2874   *         address RCA   \r
2875   * @retval SD Card error state\r
2876   */\r
2877 static HAL_SD_ErrorTypedef SD_CmdResp6Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD, uint16_t *pRCA)\r
2878 {\r
2879   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2880   uint32_t response_r1;\r
2881   \r
2882   while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT))\r
2883   {\r
2884   }\r
2885   \r
2886   if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT))\r
2887   {\r
2888     errorstate = SD_CMD_RSP_TIMEOUT;\r
2889     \r
2890     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);\r
2891     \r
2892     return errorstate;\r
2893   }\r
2894   else if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL))\r
2895   {\r
2896     errorstate = SD_CMD_CRC_FAIL;\r
2897     \r
2898     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CCRCFAIL);\r
2899     \r
2900     return errorstate;\r
2901   }\r
2902   else\r
2903   {\r
2904     /* No error flag set */\r
2905   }  \r
2906   \r
2907   /* Check response received is of desired command */\r
2908   if(SDMMC_GetCommandResponse(hsd->Instance) != SD_CMD)\r
2909   {\r
2910     errorstate = SD_ILLEGAL_CMD;\r
2911     \r
2912     return errorstate;\r
2913   }\r
2914   \r
2915   /* Clear all the static flags */\r
2916   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
2917   \r
2918   /* We have received response, retrieve it.  */\r
2919   response_r1 = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);\r
2920   \r
2921   if((response_r1 & (SD_R6_GENERAL_UNKNOWN_ERROR | SD_R6_ILLEGAL_CMD | SD_R6_COM_CRC_FAILED)) == SD_ALLZERO)\r
2922   {\r
2923     *pRCA = (uint16_t) (response_r1 >> 16);\r
2924     \r
2925     return errorstate;\r
2926   }\r
2927   \r
2928   if((response_r1 & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR)\r
2929   {\r
2930     return(SD_GENERAL_UNKNOWN_ERROR);\r
2931   }\r
2932   \r
2933   if((response_r1 & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD)\r
2934   {\r
2935     return(SD_ILLEGAL_CMD);\r
2936   }\r
2937   \r
2938   if((response_r1 & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED)\r
2939   {\r
2940     return(SD_COM_CRC_FAILED);\r
2941   }\r
2942   \r
2943   return errorstate;\r
2944 }\r
2945 \r
2946 /**\r
2947   * @brief  Enables the SDMMC wide bus mode.\r
2948   * @param  hsd: SD handle\r
2949   * @retval SD Card error state\r
2950   */\r
2951 static HAL_SD_ErrorTypedef SD_WideBus_Enable(SD_HandleTypeDef *hsd)\r
2952 {\r
2953   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
2954   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
2955   \r
2956   uint32_t scr[2] = {0, 0};\r
2957   \r
2958   if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)\r
2959   {\r
2960     errorstate = SD_LOCK_UNLOCK_FAILED;\r
2961     \r
2962     return errorstate;\r
2963   }\r
2964   \r
2965   /* Get SCR Register */\r
2966   errorstate = SD_FindSCR(hsd, scr);\r
2967   \r
2968   if(errorstate != SD_OK)\r
2969   {\r
2970     return errorstate;\r
2971   }\r
2972   \r
2973   /* If requested card supports wide bus operation */\r
2974   if((scr[1] & SD_WIDE_BUS_SUPPORT) != SD_ALLZERO)\r
2975   {\r
2976     /* Send CMD55 APP_CMD with argument as card's RCA.*/\r
2977     sdmmc_cmdinitstructure.Argument         = (uint32_t)(hsd->RCA << 16);\r
2978     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_APP_CMD;\r
2979     sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
2980     sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
2981     sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
2982     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2983     \r
2984     /* Check for error conditions */\r
2985     errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
2986     \r
2987     if(errorstate != SD_OK)\r
2988     {\r
2989       return errorstate;\r
2990     }\r
2991     \r
2992     /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */\r
2993     sdmmc_cmdinitstructure.Argument         = 2;\r
2994     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_APP_SD_SET_BUSWIDTH;\r
2995     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
2996     \r
2997     /* Check for error conditions */\r
2998     errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_SD_SET_BUSWIDTH);\r
2999     \r
3000     if(errorstate != SD_OK)\r
3001     {\r
3002       return errorstate;\r
3003     }\r
3004     \r
3005     return errorstate;\r
3006   }\r
3007   else\r
3008   {\r
3009     errorstate = SD_REQUEST_NOT_APPLICABLE;\r
3010     \r
3011     return errorstate;\r
3012   }\r
3013 }   \r
3014 \r
3015 /**\r
3016   * @brief  Disables the SDMMC wide bus mode.\r
3017   * @param  hsd: SD handle\r
3018   * @retval SD Card error state\r
3019   */\r
3020 static HAL_SD_ErrorTypedef SD_WideBus_Disable(SD_HandleTypeDef *hsd)\r
3021 {\r
3022   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
3023   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
3024   \r
3025   uint32_t scr[2] = {0, 0};\r
3026   \r
3027   if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)\r
3028   {\r
3029     errorstate = SD_LOCK_UNLOCK_FAILED;\r
3030     \r
3031     return errorstate;\r
3032   }\r
3033   \r
3034   /* Get SCR Register */\r
3035   errorstate = SD_FindSCR(hsd, scr);\r
3036   \r
3037   if(errorstate != SD_OK)\r
3038   {\r
3039     return errorstate;\r
3040   }\r
3041   \r
3042   /* If requested card supports 1 bit mode operation */\r
3043   if((scr[1] & SD_SINGLE_BUS_SUPPORT) != SD_ALLZERO)\r
3044   {\r
3045     /* Send CMD55 APP_CMD with argument as card's RCA */\r
3046     sdmmc_cmdinitstructure.Argument         = (uint32_t)(hsd->RCA << 16);\r
3047     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_APP_CMD;\r
3048     sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
3049     sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
3050     sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
3051     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
3052     \r
3053     /* Check for error conditions */\r
3054     errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
3055     \r
3056     if(errorstate != SD_OK)\r
3057     {\r
3058       return errorstate;\r
3059     }\r
3060     \r
3061     /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */\r
3062     sdmmc_cmdinitstructure.Argument         = 0;\r
3063     sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_APP_SD_SET_BUSWIDTH;\r
3064     SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
3065     \r
3066     /* Check for error conditions */\r
3067     errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_SD_SET_BUSWIDTH);\r
3068     \r
3069     if(errorstate != SD_OK)\r
3070     {\r
3071       return errorstate;\r
3072     }\r
3073     \r
3074     return errorstate;\r
3075   }\r
3076   else\r
3077   {\r
3078     errorstate = SD_REQUEST_NOT_APPLICABLE;\r
3079     \r
3080     return errorstate;\r
3081   }\r
3082 }\r
3083   \r
3084   \r
3085 /**\r
3086   * @brief  Finds the SD card SCR register value.\r
3087   * @param  hsd: SD handle\r
3088   * @param  pSCR: pointer to the buffer that will contain the SCR value  \r
3089   * @retval SD Card error state\r
3090   */\r
3091 static HAL_SD_ErrorTypedef SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR)\r
3092 {\r
3093   SDMMC_CmdInitTypeDef  sdmmc_cmdinitstructure;\r
3094   SDMMC_DataInitTypeDef sdmmc_datainitstructure;\r
3095   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
3096   uint32_t index = 0;\r
3097   uint32_t tempscr[2] = {0, 0};\r
3098   \r
3099   /* Set Block Size To 8 Bytes */\r
3100   /* Send CMD55 APP_CMD with argument as card's RCA */\r
3101   sdmmc_cmdinitstructure.Argument         = (uint32_t)8;\r
3102   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;\r
3103   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
3104   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
3105   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
3106   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
3107   \r
3108   /* Check for error conditions */\r
3109   errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
3110   \r
3111   if(errorstate != SD_OK)\r
3112   {\r
3113     return errorstate;\r
3114   }\r
3115   \r
3116   /* Send CMD55 APP_CMD with argument as card's RCA */\r
3117   sdmmc_cmdinitstructure.Argument         = (uint32_t)((hsd->RCA) << 16);\r
3118   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_APP_CMD;\r
3119   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
3120   \r
3121   /* Check for error conditions */\r
3122   errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
3123   \r
3124   if(errorstate != SD_OK)\r
3125   {\r
3126     return errorstate;\r
3127   }\r
3128   sdmmc_datainitstructure.DataTimeOut   = SD_DATATIMEOUT;\r
3129   sdmmc_datainitstructure.DataLength    = 8;\r
3130   sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_8B;\r
3131   sdmmc_datainitstructure.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;\r
3132   sdmmc_datainitstructure.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;\r
3133   sdmmc_datainitstructure.DPSM          = SDMMC_DPSM_ENABLE;\r
3134   SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);\r
3135   \r
3136   /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */\r
3137   sdmmc_cmdinitstructure.Argument         = 0;\r
3138   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SD_APP_SEND_SCR;\r
3139   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
3140   \r
3141   /* Check for error conditions */\r
3142   errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_APP_SEND_SCR);\r
3143   \r
3144   if(errorstate != SD_OK)\r
3145   {\r
3146     return errorstate;\r
3147   }\r
3148   \r
3149   while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))\r
3150   {\r
3151     if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL))\r
3152     {\r
3153       *(tempscr + index) = SDMMC_ReadFIFO(hsd->Instance);\r
3154       index++;\r
3155     }\r
3156   }\r
3157   \r
3158   if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT))\r
3159   {\r
3160     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);\r
3161     \r
3162     errorstate = SD_DATA_TIMEOUT;\r
3163     \r
3164     return errorstate;\r
3165   }\r
3166   else if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL))\r
3167   {\r
3168     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);\r
3169     \r
3170     errorstate = SD_DATA_CRC_FAIL;\r
3171     \r
3172     return errorstate;\r
3173   }\r
3174   else if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR))\r
3175   {\r
3176     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR);\r
3177     \r
3178     errorstate = SD_RX_OVERRUN;\r
3179     \r
3180     return errorstate;\r
3181   }\r
3182   else\r
3183   {\r
3184     /* No error flag set */\r
3185   }\r
3186   \r
3187   /* Clear all the static flags */\r
3188   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
3189   \r
3190   *(pSCR + 1) = ((tempscr[0] & SD_0TO7BITS) << 24)  | ((tempscr[0] & SD_8TO15BITS) << 8) |\\r
3191     ((tempscr[0] & SD_16TO23BITS) >> 8) | ((tempscr[0] & SD_24TO31BITS) >> 24);\r
3192   \r
3193   *(pSCR) = ((tempscr[1] & SD_0TO7BITS) << 24)  | ((tempscr[1] & SD_8TO15BITS) << 8) |\\r
3194     ((tempscr[1] & SD_16TO23BITS) >> 8) | ((tempscr[1] & SD_24TO31BITS) >> 24);\r
3195   \r
3196   return errorstate;\r
3197 }\r
3198 \r
3199 /**\r
3200   * @brief  Checks if the SD card is in programming state.\r
3201   * @param  hsd: SD handle\r
3202   * @param  pStatus: pointer to the variable that will contain the SD card state  \r
3203   * @retval SD Card error state\r
3204   */\r
3205 static HAL_SD_ErrorTypedef SD_IsCardProgramming(SD_HandleTypeDef *hsd, uint8_t *pStatus)\r
3206 {\r
3207   SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;\r
3208   HAL_SD_ErrorTypedef errorstate = SD_OK;\r
3209   __IO uint32_t responseR1 = 0;\r
3210   \r
3211   sdmmc_cmdinitstructure.Argument         = (uint32_t)(hsd->RCA << 16);\r
3212   sdmmc_cmdinitstructure.CmdIndex         = SD_CMD_SEND_STATUS;\r
3213   sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;\r
3214   sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;\r
3215   sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;\r
3216   SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);\r
3217   \r
3218   while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT))\r
3219   {\r
3220   }\r
3221   \r
3222   if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT))\r
3223   {\r
3224     errorstate = SD_CMD_RSP_TIMEOUT;\r
3225     \r
3226     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);\r
3227     \r
3228     return errorstate;\r
3229   }\r
3230   else if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL))\r
3231   {\r
3232     errorstate = SD_CMD_CRC_FAIL;\r
3233     \r
3234     __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CCRCFAIL);\r
3235     \r
3236     return errorstate;\r
3237   }\r
3238   else\r
3239   {\r
3240     /* No error flag set */\r
3241   }\r
3242   \r
3243   /* Check response received is of desired command */\r
3244   if((uint32_t)SDMMC_GetCommandResponse(hsd->Instance) != SD_CMD_SEND_STATUS)\r
3245   {\r
3246     errorstate = SD_ILLEGAL_CMD;\r
3247     \r
3248     return errorstate;\r
3249   }\r
3250   \r
3251   /* Clear all the static flags */\r
3252   __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);\r
3253   \r
3254   \r
3255   /* We have received response, retrieve it for analysis */\r
3256   responseR1 = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);\r
3257   \r
3258   /* Find out card status */\r
3259   *pStatus = (uint8_t)((responseR1 >> 9) & 0x0000000F);\r
3260   \r
3261   if((responseR1 & SD_OCR_ERRORBITS) == SD_ALLZERO)\r
3262   {\r
3263     return errorstate;\r
3264   }\r
3265   \r
3266   if((responseR1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE)\r
3267   {\r
3268     return(SD_ADDR_OUT_OF_RANGE);\r
3269   }\r
3270   \r
3271   if((responseR1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED)\r
3272   {\r
3273     return(SD_ADDR_MISALIGNED);\r
3274   }\r
3275   \r
3276   if((responseR1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR)\r
3277   {\r
3278     return(SD_BLOCK_LEN_ERR);\r
3279   }\r
3280   \r
3281   if((responseR1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR)\r
3282   {\r
3283     return(SD_ERASE_SEQ_ERR);\r
3284   }\r
3285   \r
3286   if((responseR1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM)\r
3287   {\r
3288     return(SD_BAD_ERASE_PARAM);\r
3289   }\r
3290   \r
3291   if((responseR1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION)\r
3292   {\r
3293     return(SD_WRITE_PROT_VIOLATION);\r
3294   }\r
3295   \r
3296   if((responseR1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED)\r
3297   {\r
3298     return(SD_LOCK_UNLOCK_FAILED);\r
3299   }\r
3300   \r
3301   if((responseR1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED)\r
3302   {\r
3303     return(SD_COM_CRC_FAILED);\r
3304   }\r
3305   \r
3306   if((responseR1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD)\r
3307   {\r
3308     return(SD_ILLEGAL_CMD);\r
3309   }\r
3310   \r
3311   if((responseR1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED)\r
3312   {\r
3313     return(SD_CARD_ECC_FAILED);\r
3314   }\r
3315   \r
3316   if((responseR1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR)\r
3317   {\r
3318     return(SD_CC_ERROR);\r
3319   }\r
3320   \r
3321   if((responseR1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR)\r
3322   {\r
3323     return(SD_GENERAL_UNKNOWN_ERROR);\r
3324   }\r
3325   \r
3326   if((responseR1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN)\r
3327   {\r
3328     return(SD_STREAM_READ_UNDERRUN);\r
3329   }\r
3330   \r
3331   if((responseR1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN)\r
3332   {\r
3333     return(SD_STREAM_WRITE_OVERRUN);\r
3334   }\r
3335   \r
3336   if((responseR1 & SD_OCR_CID_CSD_OVERWRITE) == SD_OCR_CID_CSD_OVERWRITE)\r
3337   {\r
3338     return(SD_CID_CSD_OVERWRITE);\r
3339   }\r
3340   \r
3341   if((responseR1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP)\r
3342   {\r
3343     return(SD_WP_ERASE_SKIP);\r
3344   }\r
3345   \r
3346   if((responseR1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED)\r
3347   {\r
3348     return(SD_CARD_ECC_DISABLED);\r
3349   }\r
3350   \r
3351   if((responseR1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET)\r
3352   {\r
3353     return(SD_ERASE_RESET);\r
3354   }\r
3355   \r
3356   if((responseR1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR)\r
3357   {\r
3358     return(SD_AKE_SEQ_ERROR);\r
3359   }\r
3360   \r
3361   return errorstate;\r
3362 }   \r
3363 \r
3364 /**\r
3365   * @}\r
3366   */\r
3367 \r
3368 #endif /* HAL_SD_MODULE_ENABLED */\r
3369 \r
3370 /**\r
3371   * @}\r
3372   */\r
3373 \r
3374 /**\r
3375   * @}\r
3376   */\r
3377 \r
3378 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r