+++ /dev/null
-/**\r
- ******************************************************************************\r
- * @file stm32f4xx_hal_sd.c\r
- * @author MCD Application Team\r
- * @version V1.0.0\r
- * @date 18-February-2014\r
- * @brief SD card HAL module driver.\r
- * This file provides firmware functions to manage the following \r
- * functionalities of the Secure Digital (SD) peripheral:\r
- * + Initialization and de-initialization functions\r
- * + IO operation functions\r
- * + Peripheral Control functions \r
- * + Peripheral State functions\r
- * \r
- @verbatim\r
- ==============================================================================\r
- ##### How to use this driver #####\r
- ==============================================================================\r
- [..]\r
- This driver implements a high level communication layer for read and write from/to \r
- this memory. The needed STM32 hardware resources (SDIO and GPIO) are performed by \r
- the user in HAL_SD_MspInit() function (MSP layer). \r
- Basically, the MSP layer configuration should be the same as we provide in the \r
- examples.\r
- You can easily tailor this configuration according to hardware resources.\r
-\r
- [..]\r
- This driver is a generic layered driver for SDIO memories which uses the HAL \r
- SDIO driver functions to interface with SD and uSD cards devices. \r
- It is used as follows:\r
- \r
- (#)Initialize the SDIO low level resources by implement the HAL_SD_MspInit() API:\r
- (##) Enable the SDIO interface clock using __SDIO_CLK_ENABLE(); \r
- (##) SDIO pins configuration for SD card\r
- (+++) Enable the clock for the SDIO GPIOs using the functions __GPIOx_CLK_ENABLE(); \r
- (+++) Configure these SDIO pins as alternate function pull-up using HAL_GPIO_Init()\r
- and according to your pin assignment;\r
- (##) DMA Configuration if you need to use DMA process (HAL_SD_ReadBlocks_DMA()\r
- and HAL_SD_WriteBlocks_DMA() APIs).\r
- (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE(); \r
- (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled. \r
- (##) NVIC configuration if you need to use interrupt process when using DMA transfer.\r
- (+++) Configure the SDIO and DMA interrupt priorities using functions\r
- HAL_NVIC_SetPriority(); DMA priority is superior to SDIO's priority\r
- (+++) Enable the NVIC DMA and SDIO IRQs using function HAL_NVIC_EnableIRQ()\r
- (+++) SDIO interrupts are managed using the macros __HAL_SD_SDIO_ENABLE_IT() \r
- and __HAL_SD_SDIO_DISABLE_IT() inside the communication process.\r
- (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_SDIO_GET_IT()\r
- and __HAL_SD_SDIO_CLEAR_IT()\r
- (#) At this stage, you can perform SD read/write/erase operations after SD card initialization \r
-\r
- \r
- *** SD Card Initialization and configuration ***\r
- ================================================ \r
- [..]\r
- To initialize the SD Card, use the HAL_SD_Init() function. It Initializes \r
- the SD Card and put it into StandBy State (Ready for data transfer). \r
- This function provide the following operations:\r
- \r
- (#) Apply the SD Card initialization process at 400KHz and check the SD Card \r
- type (Standard Capacity or High Capacity). You can change or adapt this \r
- frequency by adjusting the "ClockDiv" field. \r
- The SD Card frequency (SDIO_CK) is computed as follows:\r
- \r
- SDIO_CK = SDIOCLK / (ClockDiv + 2)\r
- \r
- In initialization mode and according to the SD Card standard, \r
- make sure that the SDIO_CK frequency doesn't exceed 400KHz.\r
- \r
- (#) Get the SD CID and CSD data. All these information are managed by the SDCardInfo \r
- structure. This structure provide also ready computed SD Card capacity \r
- and Block size.\r
- \r
- -@- These information are stored in SD handle structure in case of future use. \r
- \r
- (#) Configure the SD Card Data transfer frequency. By Default, the card transfer \r
- frequency is set to 24MHz. You can change or adapt this frequency by adjusting \r
- the "ClockDiv" field.\r
- The SD Card frequency (SDIO_CK) is computed as follows:\r
-\r
- SDIO_CK = SDIOCLK / (ClockDiv + 2) \r
-\r
- In transfer mode and according to the SD Card standard, make sure that the \r
- SDIO_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.\r
- To be able to use a frequency higher than 24MHz, you should use the SDIO \r
- peripheral in bypass mode. Refer to the corresponding reference manual \r
- for more details.\r
- \r
- (#) Select the corresponding SD Card according to the address read with the step 2.\r
- \r
- (#) Configure the SD Card in wide bus mode: 4-bits data.\r
- \r
- *** SD Card Read operation ***\r
- ==============================\r
- [..] \r
- (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks(). \r
- This function support only 512-byte block length (the block size should be \r
- chosen as 512 byte).\r
- You can choose either one block read operation or multiple block read operation \r
- by adjusting the "NumberOfBlocks" parameter.\r
-\r
- (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA().\r
- This function support only 512-byte block length (the block size should be \r
- chosen as 512 byte).\r
- You can choose either one block read operation or multiple block read operation \r
- by adjusting the "NumberOfBlocks" parameter.\r
- After this, you have to call the function HAL_SD_CheckReadOperation(), to insure\r
- that the read transfer is done correctly in both DMA and SD sides.\r
- \r
- *** SD Card Write operation ***\r
- =============================== \r
- [..] \r
- (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks(). \r
- This function support only 512-byte block length (the block size should be \r
- chosen as 512 byte).\r
- You can choose either one block read operation or multiple block read operation \r
- by adjusting the "NumberOfBlocks" parameter.\r
-\r
- (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA().\r
- This function support only 512-byte block length (the block size should be \r
- chosen as 512 byte).\r
- You can choose either one block read operation or multiple block read operation \r
- by adjusting the "NumberOfBlocks" parameter.\r
- After this, you have to call the function HAL_SD_CheckWriteOperation(), to insure\r
- that the write transfer is done correctly in both DMA and SD sides. \r
- \r
- *** SD card status ***\r
- ====================== \r
- [..]\r
- (+) At any time, you can check the SD Card status and get the SD card state \r
- by using the HAL_SD_GetStatus() function. This function checks first if the \r
- SD card is still connected and then get the internal SD Card transfer state. \r
- (+) You can also get the SD card SD Status register by using the HAL_SD_SendSDStatus() \r
- function. \r
-\r
- *** SD HAL driver macros list ***\r
- ==================================\r
- [..]\r
- Below the list of most used macros in SD HAL driver.\r
- \r
- (+) __HAL_SD_SDIO_ENABLE : Enable the SD device\r
- (+) __HAL_SD_SDIO_DISABLE : Disable the SD device\r
- (+) __HAL_SD_SDIO_DMA_ENABLE: Enable the SDIO DMA transfer\r
- (+) __HAL_SD_SDIO_DMA_DISABLE: Disable the SDIO DMA transfer\r
- (+) __HAL_SD_SDIO_ENABLE_IT: Enable the SD device interrupt\r
- (+) __HAL_SD_SDIO_DISABLE_IT: Disable the SD device interrupt\r
- (+) __HAL_SD_SDIO_GET_FLAG:Check whether the specified SD flag is set or not\r
- (+) __HAL_SD_SDIO_CLEAR_FLAG: Clear the SD's pending flags\r
- \r
- (@) You can refer to the SD HAL driver header file for more useful macros \r
- \r
- @endverbatim\r
- ******************************************************************************\r
- * @attention\r
- *\r
- * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>\r
- *\r
- * Redistribution and use in source and binary forms, with or without modification,\r
- * are permitted provided that the following conditions are met:\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- * this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- * this list of conditions and the following disclaimer in the documentation\r
- * and/or other materials provided with the distribution.\r
- * 3. Neither the name of STMicroelectronics nor the names of its contributors\r
- * may be used to endorse or promote products derived from this software\r
- * without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- *\r
- ******************************************************************************\r
- */ \r
-\r
-/* Includes ------------------------------------------------------------------*/\r
-#include "stm32f4xx_hal.h"\r
-\r
-/** @addtogroup STM32F4xx_HAL_Driver\r
- * @{\r
- */\r
-\r
-/** @defgroup SD\r
- * @brief SD HAL module driver\r
- * @{\r
- */\r
-\r
-#ifdef HAL_SD_MODULE_ENABLED\r
-\r
-/* Private typedef -----------------------------------------------------------*/\r
-/* Private define ------------------------------------------------------------*/\r
-\r
-/** \r
- * @brief SDIO Static flags, TimeOut, FIFO Address \r
- */\r
-#define SDIO_STATIC_FLAGS ((uint32_t)0x000005FF)\r
-#define SDIO_CMD0TIMEOUT ((uint32_t)0x00010000)\r
-\r
-/** \r
- * @brief Mask for errors Card Status R1 (OCR Register) \r
- */\r
-#define SD_OCR_ADDR_OUT_OF_RANGE ((uint32_t)0x80000000)\r
-#define SD_OCR_ADDR_MISALIGNED ((uint32_t)0x40000000)\r
-#define SD_OCR_BLOCK_LEN_ERR ((uint32_t)0x20000000)\r
-#define SD_OCR_ERASE_SEQ_ERR ((uint32_t)0x10000000)\r
-#define SD_OCR_BAD_ERASE_PARAM ((uint32_t)0x08000000)\r
-#define SD_OCR_WRITE_PROT_VIOLATION ((uint32_t)0x04000000)\r
-#define SD_OCR_LOCK_UNLOCK_FAILED ((uint32_t)0x01000000)\r
-#define SD_OCR_COM_CRC_FAILED ((uint32_t)0x00800000)\r
-#define SD_OCR_ILLEGAL_CMD ((uint32_t)0x00400000)\r
-#define SD_OCR_CARD_ECC_FAILED ((uint32_t)0x00200000)\r
-#define SD_OCR_CC_ERROR ((uint32_t)0x00100000)\r
-#define SD_OCR_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00080000)\r
-#define SD_OCR_STREAM_READ_UNDERRUN ((uint32_t)0x00040000)\r
-#define SD_OCR_STREAM_WRITE_OVERRUN ((uint32_t)0x00020000)\r
-#define SD_OCR_CID_CSD_OVERWRIETE ((uint32_t)0x00010000)\r
-#define SD_OCR_WP_ERASE_SKIP ((uint32_t)0x00008000)\r
-#define SD_OCR_CARD_ECC_DISABLED ((uint32_t)0x00004000)\r
-#define SD_OCR_ERASE_RESET ((uint32_t)0x00002000)\r
-#define SD_OCR_AKE_SEQ_ERROR ((uint32_t)0x00000008)\r
-#define SD_OCR_ERRORBITS ((uint32_t)0xFDFFE008)\r
-\r
-/** \r
- * @brief Masks for R6 Response \r
- */\r
-#define SD_R6_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00002000)\r
-#define SD_R6_ILLEGAL_CMD ((uint32_t)0x00004000)\r
-#define SD_R6_COM_CRC_FAILED ((uint32_t)0x00008000)\r
-\r
-#define SD_VOLTAGE_WINDOW_SD ((uint32_t)0x80100000)\r
-#define SD_HIGH_CAPACITY ((uint32_t)0x40000000)\r
-#define SD_STD_CAPACITY ((uint32_t)0x00000000)\r
-#define SD_CHECK_PATTERN ((uint32_t)0x000001AA)\r
-\r
-#define SD_MAX_VOLT_TRIAL ((uint32_t)0x0000FFFF)\r
-#define SD_ALLZERO ((uint32_t)0x00000000)\r
-\r
-#define SD_WIDE_BUS_SUPPORT ((uint32_t)0x00040000)\r
-#define SD_SINGLE_BUS_SUPPORT ((uint32_t)0x00010000)\r
-#define SD_CARD_LOCKED ((uint32_t)0x02000000)\r
-\r
-#define SD_DATATIMEOUT ((uint32_t)0xFFFFFFFF)\r
-#define SD_0TO7BITS ((uint32_t)0x000000FF)\r
-#define SD_8TO15BITS ((uint32_t)0x0000FF00)\r
-#define SD_16TO23BITS ((uint32_t)0x00FF0000)\r
-#define SD_24TO31BITS ((uint32_t)0xFF000000)\r
-#define SD_MAX_DATA_LENGTH ((uint32_t)0x01FFFFFF)\r
-\r
-#define SD_HALFFIFO ((uint32_t)0x00000008)\r
-#define SD_HALFFIFOBYTES ((uint32_t)0x00000020)\r
-\r
-/** \r
- * @brief Command Class Supported \r
- */\r
-#define SD_CCCC_LOCK_UNLOCK ((uint32_t)0x00000080)\r
-#define SD_CCCC_WRITE_PROT ((uint32_t)0x00000040)\r
-#define SD_CCCC_ERASE ((uint32_t)0x00000020)\r
-\r
-/** \r
- * @brief Following commands are SD Card Specific commands.\r
- * SDIO_APP_CMD should be sent before sending these commands. \r
- */\r
-#define SD_SDIO_SEND_IF_COND ((uint32_t)SD_CMD_HS_SEND_EXT_CSD)\r
-\r
- \r
-/* Private macro -------------------------------------------------------------*/\r
-/* Private variables ---------------------------------------------------------*/\r
-/* Private function prototypes -----------------------------------------------*/\r
-/* Private functions ---------------------------------------------------------*/\r
-static HAL_SD_ErrorTypedef SD_Initialize_Cards(SD_HandleTypeDef *hsd);\r
-static HAL_SD_ErrorTypedef SD_Select_Deselect(SD_HandleTypeDef *hsd, uint64_t addr);\r
-static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd); \r
-static HAL_SD_ErrorTypedef SD_PowerOFF(SD_HandleTypeDef *hsd);\r
-static HAL_SD_ErrorTypedef SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus);\r
-static HAL_SD_CardStateTypedef SD_GetState(SD_HandleTypeDef *hsd);\r
-static HAL_SD_ErrorTypedef SD_IsCardProgramming(SD_HandleTypeDef *hsd, uint8_t *pStatus);\r
-static HAL_SD_ErrorTypedef SD_CmdError(SD_HandleTypeDef *hsd);\r
-static HAL_SD_ErrorTypedef SD_CmdResp1Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD);\r
-static HAL_SD_ErrorTypedef SD_CmdResp7Error(SD_HandleTypeDef *hsd);\r
-static HAL_SD_ErrorTypedef SD_CmdResp3Error(SD_HandleTypeDef *hsd);\r
-static HAL_SD_ErrorTypedef SD_CmdResp2Error(SD_HandleTypeDef *hsd);\r
-static HAL_SD_ErrorTypedef SD_CmdResp6Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD, uint16_t *pRCA);\r
-static HAL_SD_ErrorTypedef SD_WideBus_Enable(SD_HandleTypeDef *hsd);\r
-static HAL_SD_ErrorTypedef SD_WideBus_Disable(SD_HandleTypeDef *hsd);\r
-static HAL_SD_ErrorTypedef SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR); \r
-static void SD_DMA_RxCplt(DMA_HandleTypeDef *hdma);\r
-static void SD_DMA_RxError(DMA_HandleTypeDef *hdma);\r
-static void SD_DMA_TxCplt(DMA_HandleTypeDef *hdma);\r
-static void SD_DMA_TxError(DMA_HandleTypeDef *hdma);\r
-\r
-/** @defgroup SD_Private_Functions\r
- * @{\r
- */\r
-\r
-/** @defgroup SD_Group1 Initialization and de-initialization functions \r
- * @brief Initialization and Configuration functions \r
- *\r
-@verbatim \r
- ==============================================================================\r
- ##### Initialization and de-initialization functions #####\r
- ==============================================================================\r
- [..] \r
- This section provides functions allowing to initialize/de-initialize the SD\r
- card device to be ready for use.\r
- \r
- \r
-@endverbatim\r
- * @{\r
- */\r
-\r
-/**\r
- * @brief Initializes the SD card according to the specified parameters in the \r
- SD_HandleTypeDef and create the associated handle.\r
- * @param hsd: SD handle\r
- * @param SDCardInfo: HAL_SD_CardInfoTypedef structure for SD card information \r
- * @retval HAL SD error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo)\r
-{ \r
- __IO HAL_SD_ErrorTypedef errorState = SD_OK;\r
- SD_InitTypeDef tmpInit;\r
- \r
- /* Initialize the low level hardware (MSP) */\r
- HAL_SD_MspInit(hsd);\r
- \r
- /* Default SDIO peripheral configuration for SD card initialization */\r
- tmpInit.ClockEdge = SDIO_CLOCK_EDGE_RISING;\r
- tmpInit.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;\r
- tmpInit.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;\r
- tmpInit.BusWide = SDIO_BUS_WIDE_1B;\r
- tmpInit.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;\r
- tmpInit.ClockDiv = SDIO_INIT_CLK_DIV;\r
- \r
- /* Initialize SDIO peripheral interface with default configuration */\r
- SDIO_Init(hsd->Instance, tmpInit);\r
- \r
- /* Identify card operating voltage */\r
- errorState = SD_PowerON(hsd); \r
- \r
- if(errorState != SD_OK) \r
- {\r
- return errorState;\r
- }\r
- \r
- /* Initialize the present SDIO card(s) and put them in idle state */\r
- errorState = SD_Initialize_Cards(hsd);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Read CSD/CID MSD registers */\r
- errorState = HAL_SD_Get_CardInfo(hsd, SDCardInfo);\r
- \r
- if (errorState == SD_OK)\r
- {\r
- /* Select the Card */\r
- errorState = SD_Select_Deselect(hsd, (uint32_t)(((uint32_t)SDCardInfo->RCA) << 16));\r
- }\r
- \r
- /* Configure SDIO peripheral interface */\r
- SDIO_Init(hsd->Instance, hsd->Init); \r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief De-Initializes the SD card.\r
- * @param hsd: SD handle\r
- * @retval HAL status\r
- */\r
-HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd)\r
-{\r
- \r
- /* Set SD power state to off */ \r
- SD_PowerOFF(hsd);\r
- \r
- /* De-Initialize the MSP layer */\r
- HAL_SD_MspDeInit(hsd);\r
- \r
- return HAL_OK;\r
-}\r
-\r
-\r
-/**\r
- * @brief Initializes the SD MSP.\r
- * @param hsd: SD handle\r
- * @retval None\r
- */\r
-__weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd)\r
-{\r
- /* NOTE : This function Should not be modified, when the callback is needed,\r
- the HAL_SD_MspInit could be implemented in the user file\r
- */\r
-}\r
-\r
-/**\r
- * @brief De-Initialize SD MSP.\r
- * @param hsd: SD handle\r
- * @retval None\r
- */\r
-__weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)\r
-{\r
- /* NOTE : This function Should not be modified, when the callback is needed,\r
- the HAL_SD_MspDeInit could be implemented in the user file\r
- */\r
-}\r
-\r
-/**\r
- * @}\r
- */\r
-\r
-/** @defgroup SD_Group2 IO operation functions \r
- * @brief Data transfer functions \r
- *\r
-@verbatim \r
- ==============================================================================\r
- ##### IO operation functions #####\r
- ============================================================================== \r
- [..]\r
- This subsection provides a set of functions allowing to manage the data \r
- transfer from/to SD card.\r
-\r
-@endverbatim\r
- * @{\r
- */\r
-\r
-/**\r
- * @brief Reads block(s) from a specified address in a card. The Data transfer \r
- * is managed by polling mode. \r
- * @param hsd: SD handle\r
- * @param pReadBuffer: pointer to the buffer that will contain the received data\r
- * @param ReadAddr: Address from where data is to be read \r
- * @param BlockSize: SD card Data block size \r
- * This parameter should be 512\r
- * @param NumberOfBlocks: Number of SD blocks to read \r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- SDIO_DataInitTypeDef SDIO_DataInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t count = 0, *tempbuff = (uint32_t *)pReadBuffer;\r
- \r
- /* Initialize data control register */\r
- hsd->Instance->DCTRL = 0;\r
- \r
- if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
- {\r
- BlockSize = 512;\r
- ReadAddr /= 512;\r
- }\r
- \r
- /* Set Block Size for Card */ \r
- SDIO_CmdInitStructure.Argument = (uint32_t) BlockSize;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SET_BLOCKLEN;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Configure the SD DPSM (Data Path State Machine) */\r
- SDIO_DataInitStructure.DataTimeOut = SD_DATATIMEOUT;\r
- SDIO_DataInitStructure.DataLength = NumberOfBlocks * BlockSize;\r
- SDIO_DataInitStructure.DataBlockSize = (uint32_t)(9 << 4);\r
- SDIO_DataInitStructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;\r
- SDIO_DataInitStructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;\r
- SDIO_DataInitStructure.DPSM = SDIO_DPSM_ENABLE;\r
- SDIO_DataConfig(hsd->Instance, &SDIO_DataInitStructure);\r
- \r
- if(NumberOfBlocks > 1)\r
- {\r
- /* Send CMD18 READ_MULT_BLOCK with argument data address */\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_READ_MULT_BLOCK;\r
- }\r
- else\r
- {\r
- /* Send CMD17 READ_SINGLE_BLOCK */\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK; \r
- }\r
- \r
- SDIO_CmdInitStructure.Argument = (uint32_t)ReadAddr;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Read block(s) in polling mode */\r
- if(NumberOfBlocks > 1)\r
- {\r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_READ_MULT_BLOCK);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Poll on SDIO flags */\r
- while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))\r
- {\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))\r
- {\r
- /* Read data from SDIO Rx FIFO */\r
- for (count = 0; count < 8; count++)\r
- {\r
- *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance);\r
- }\r
- \r
- tempbuff += 8;\r
- }\r
- } \r
- }\r
- else\r
- {\r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK); \r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- } \r
- \r
- /* In case of single block transfer, no need of stop transfer at all */\r
- while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))\r
- {\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))\r
- {\r
- /* Read data from SDIO Rx FIFO */\r
- for (count = 0; count < 8; count++)\r
- {\r
- *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance);\r
- }\r
- \r
- tempbuff += 8;\r
- }\r
- } \r
- }\r
- \r
- /* Send stop transmission command in case of multiblock read */\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1))\r
- { \r
- if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) ||\\r
- (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\\r
- (hsd->CardType == HIGH_CAPACITY_SD_CARD))\r
- {\r
- /* Send stop transmission command */\r
- errorState = HAL_SD_StopTransfer(hsd);\r
- }\r
- }\r
- \r
- /* Get error state */\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);\r
- \r
- errorState = SD_DATA_TIMEOUT;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);\r
- \r
- errorState = SD_DATA_CRC_FAIL;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);\r
- \r
- errorState = SD_RX_OVERRUN;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);\r
- \r
- errorState = SD_START_BIT_ERR;\r
- \r
- return errorState;\r
- }\r
- \r
- count = SD_DATATIMEOUT;\r
- \r
- /* Empty FIFO if there is still any data */\r
- while ((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (count > 0))\r
- {\r
- *tempbuff = SDIO_ReadFIFO(hsd->Instance);\r
- tempbuff++;\r
- count--;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Allows to write block(s) to a specified address in a card. The Data\r
- * transfer is managed by polling mode. \r
- * @param hsd: SD handle\r
- * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit\r
- * @param WriteAddr: Address from where data is to be written \r
- * @param BlockSize: SD card Data block size \r
- * This parameter should be 512.\r
- * @param NumberOfBlocks: Number of SD blocks to write \r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- SDIO_DataInitTypeDef SDIO_DataInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t TotalNumberOfBytes = 0, bytestransferred = 0, count = 0, restwords = 0;\r
- uint32_t *tempbuff = (uint32_t *)pWriteBuffer;\r
- uint8_t cardstate = 0;\r
- \r
- /* Initialize data control register */\r
- hsd->Instance->DCTRL = 0;\r
- \r
- if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
- {\r
- BlockSize = 512;\r
- WriteAddr /= 512;\r
- }\r
- \r
- /* Set Block Size for Card */ \r
- SDIO_CmdInitStructure.Argument = (uint32_t)BlockSize;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SET_BLOCKLEN;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- if(NumberOfBlocks > 1)\r
- {\r
- /* Send CMD25 WRITE_MULT_BLOCK with argument data address */\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;\r
- }\r
- else\r
- {\r
- /* Send CMD24 WRITE_SINGLE_BLOCK */\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;\r
- }\r
- \r
- SDIO_CmdInitStructure.Argument = (uint32_t)WriteAddr;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- if(NumberOfBlocks > 1)\r
- {\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_WRITE_MULT_BLOCK);\r
- }\r
- else\r
- {\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_WRITE_SINGLE_BLOCK);\r
- } \r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Set total number of bytes to write */\r
- TotalNumberOfBytes = NumberOfBlocks * BlockSize;\r
- \r
- /* Configure the SD DPSM (Data Path State Machine) */ \r
- SDIO_DataInitStructure.DataTimeOut = SD_DATATIMEOUT;\r
- SDIO_DataInitStructure.DataLength = NumberOfBlocks * BlockSize;\r
- SDIO_DataInitStructure.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;\r
- SDIO_DataInitStructure.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;\r
- SDIO_DataInitStructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;\r
- SDIO_DataInitStructure.DPSM = SDIO_DPSM_ENABLE;\r
- SDIO_DataConfig(hsd->Instance, &SDIO_DataInitStructure);\r
- \r
- /* Write block(s) in polling mode */\r
- if(NumberOfBlocks > 1)\r
- {\r
- while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))\r
- {\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE))\r
- {\r
- if ((TotalNumberOfBytes - bytestransferred) < 32)\r
- {\r
- restwords = ((TotalNumberOfBytes - bytestransferred) % 4 == 0) ? ((TotalNumberOfBytes - bytestransferred) / 4) : (( TotalNumberOfBytes - bytestransferred) / 4 + 1);\r
- \r
- /* Write data to SDIO Tx FIFO */\r
- for (count = 0; count < restwords; count++)\r
- {\r
- SDIO_WriteFIFO(hsd->Instance, tempbuff);\r
- tempbuff++;\r
- bytestransferred += 4;\r
- }\r
- }\r
- else\r
- {\r
- /* Write data to SDIO Tx FIFO */\r
- for (count = 0; count < 8; count++)\r
- {\r
- SDIO_WriteFIFO(hsd->Instance, (tempbuff + count));\r
- }\r
- \r
- tempbuff += 8;\r
- bytestransferred += 32;\r
- }\r
- }\r
- } \r
- }\r
- else\r
- {\r
- /* In case of single data block transfer no need of stop command at all */ \r
- while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))\r
- {\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE))\r
- {\r
- if ((TotalNumberOfBytes - bytestransferred) < 32)\r
- {\r
- restwords = ((TotalNumberOfBytes - bytestransferred) % 4 == 0) ? ((TotalNumberOfBytes - bytestransferred) / 4) : (( TotalNumberOfBytes - bytestransferred) / 4 + 1);\r
- \r
- /* Write data to SDIO Tx FIFO */\r
- for (count = 0; count < restwords; count++)\r
- {\r
- SDIO_WriteFIFO(hsd->Instance, tempbuff);\r
- tempbuff++; \r
- bytestransferred += 4;\r
- }\r
- }\r
- else\r
- {\r
- /* Write data to SDIO Tx FIFO */\r
- for (count = 0; count < 8; count++)\r
- {\r
- SDIO_WriteFIFO(hsd->Instance, (tempbuff + count));\r
- }\r
- \r
- tempbuff += 8;\r
- bytestransferred += 32;\r
- }\r
- }\r
- } \r
- }\r
- \r
- /* Send stop transmission command in case of multiblock write */\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1))\r
- { \r
- if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\\r
- (hsd->CardType == HIGH_CAPACITY_SD_CARD))\r
- {\r
- /* Send stop transmission command */\r
- errorState = HAL_SD_StopTransfer(hsd);\r
- }\r
- }\r
- \r
- /* Get error state */\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);\r
- \r
- errorState = SD_DATA_TIMEOUT;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);\r
- \r
- errorState = SD_DATA_CRC_FAIL;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_TXUNDERR);\r
- \r
- errorState = SD_TX_UNDERRUN;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);\r
- \r
- errorState = SD_START_BIT_ERR;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- /* Wait till the card is in programming state */\r
- errorState = SD_IsCardProgramming(hsd, &cardstate);\r
- \r
- while ((errorState == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))\r
- {\r
- errorState = SD_IsCardProgramming(hsd, &cardstate);\r
- }\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Reads block(s) from a specified address in a card. The Data transfer \r
- * is managed by DMA mode. \r
- * @note This API should be followed by the function HAL_SD_CheckReadOperation()\r
- * to check the completion of the read process \r
- * @param hsd: SD handle \r
- * @param pReadBuffer: Pointer to the buffer that will contain the received data\r
- * @param ReadAddr: Address from where data is to be read \r
- * @param BlockSize: SD card Data block size \r
- * This paramater should be 512.\r
- * @param NumberOfBlocks: Number of blocks to read.\r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- SDIO_DataInitTypeDef SDIO_DataInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- \r
- /* Initialize data control register */\r
- hsd->Instance->DCTRL = 0;\r
- \r
- /* Initialize handle flags */\r
- hsd->SdTransferCplt = 0;\r
- hsd->DmaTransferCplt = 0;\r
- hsd->SdTransferErr = SD_OK; \r
- \r
- /* Initialize SD Read operation */\r
- if(NumberOfBlocks > 1)\r
- {\r
- hsd->SdOperation = SD_READ_MULTIPLE_BLOCK;\r
- }\r
- else\r
- {\r
- hsd->SdOperation = SD_READ_SINGLE_BLOCK;\r
- }\r
- \r
- /* Enable transfer interrupts */\r
- __HAL_SD_SDIO_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL |\\r
- SDIO_IT_DTIMEOUT |\\r
- SDIO_IT_DATAEND |\\r
- SDIO_IT_RXOVERR |\\r
- SDIO_IT_STBITERR));\r
- \r
- /* Enable SDIO DMA transfer */\r
- __HAL_SD_SDIO_DMA_ENABLE();\r
- \r
- /* Configure DMA user callbacks */\r
- hsd->hdmarx->XferCpltCallback = SD_DMA_RxCplt;\r
- hsd->hdmarx->XferErrorCallback = SD_DMA_RxError;\r
- \r
- /* Enable the DMA Stream */\r
- HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)SDIO_FIFO_ADDRESS, (uint32_t)pReadBuffer, (uint32_t)(BlockSize * NumberOfBlocks));\r
- \r
- if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
- {\r
- BlockSize = 512;\r
- ReadAddr /= 512;\r
- }\r
- \r
- /* Set Block Size for Card */ \r
- SDIO_CmdInitStructure.Argument = (uint32_t)BlockSize;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SET_BLOCKLEN;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Configure the SD DPSM (Data Path State Machine) */ \r
- SDIO_DataInitStructure.DataTimeOut = SD_DATATIMEOUT;\r
- SDIO_DataInitStructure.DataLength = BlockSize * NumberOfBlocks;\r
- SDIO_DataInitStructure.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;\r
- SDIO_DataInitStructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;\r
- SDIO_DataInitStructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;\r
- SDIO_DataInitStructure.DPSM = SDIO_DPSM_ENABLE;\r
- SDIO_DataConfig(hsd->Instance, &SDIO_DataInitStructure);\r
- \r
- /* Check number of blocks command */\r
- if(NumberOfBlocks > 1)\r
- {\r
- /* Send CMD18 READ_MULT_BLOCK with argument data address */\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_READ_MULT_BLOCK;\r
- }\r
- else\r
- {\r
- /* Send CMD17 READ_SINGLE_BLOCK */\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;\r
- }\r
- \r
- SDIO_CmdInitStructure.Argument = (uint32_t)ReadAddr;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- if(NumberOfBlocks > 1)\r
- {\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_READ_MULT_BLOCK);\r
- }\r
- else\r
- {\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK);\r
- }\r
- \r
- /* Update the SD transfer error in SD handle */\r
- hsd->SdTransferErr = errorState;\r
- \r
- return errorState;\r
-}\r
-\r
-\r
-/**\r
- * @brief Writes block(s) to a specified address in a card. The Data transfer \r
- * is managed by DMA mode. \r
- * @note This API should be followed by the function HAL_SD_CheckWriteOperation()\r
- * to check the completion of the write process (by SD current status polling). \r
- * @param hsd: SD handle\r
- * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit\r
- * @param WriteAddr: Address from where data is to be read \r
- * @param BlockSize: the SD card Data block size \r
- * This parameter should be 512.\r
- * @param NumberOfBlocks: Number of blocks to write\r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- SDIO_DataInitTypeDef SDIO_DataInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- \r
- /* Initialize data control register */\r
- hsd->Instance->DCTRL = 0;\r
- \r
- /* Initialize handle flags */\r
- hsd->SdTransferCplt = 0;\r
- hsd->DmaTransferCplt = 0;\r
- hsd->SdTransferErr = SD_OK;\r
- \r
- /* Initialize SD Write operation */\r
- if(NumberOfBlocks > 1)\r
- {\r
- hsd->SdOperation = SD_WRITE_MULTIPLE_BLOCK;\r
- }\r
- else\r
- {\r
- hsd->SdOperation = SD_WRITE_SINGLE_BLOCK;\r
- } \r
- \r
- /* Enable transfer interrupts */\r
- __HAL_SD_SDIO_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL |\\r
- SDIO_IT_DTIMEOUT |\\r
- SDIO_IT_DATAEND |\\r
- SDIO_IT_TXUNDERR |\\r
- SDIO_IT_STBITERR)); \r
- \r
- /* Configure DMA user callbacks */\r
- hsd->hdmatx->XferCpltCallback = SD_DMA_TxCplt;\r
- hsd->hdmatx->XferErrorCallback = SD_DMA_TxError;\r
- \r
- /* Enable the DMA Stream */\r
- HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pWriteBuffer, (uint32_t)SDIO_FIFO_ADDRESS, (uint32_t)(BlockSize * NumberOfBlocks));\r
-\r
- /* Enable SDIO DMA transfer */\r
- __HAL_SD_SDIO_DMA_ENABLE();\r
- \r
- if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
- {\r
- BlockSize = 512;\r
- WriteAddr /= 512;\r
- }\r
-\r
- /* Set Block Size for Card */ \r
- SDIO_CmdInitStructure.Argument = (uint32_t)BlockSize;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SET_BLOCKLEN;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
-\r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
-\r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Check number of blocks command */\r
- if(NumberOfBlocks <= 1)\r
- {\r
- /* Send CMD24 WRITE_SINGLE_BLOCK */\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;\r
- }\r
- else\r
- {\r
- /* Send CMD25 WRITE_MULT_BLOCK with argument data address */\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;\r
- }\r
- \r
- SDIO_CmdInitStructure.Argument = (uint32_t)WriteAddr;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
-\r
- /* Check for error conditions */\r
- if(NumberOfBlocks > 1)\r
- {\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_WRITE_MULT_BLOCK);\r
- }\r
- else\r
- {\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_WRITE_SINGLE_BLOCK);\r
- }\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Configure the SD DPSM (Data Path State Machine) */ \r
- SDIO_DataInitStructure.DataTimeOut = SD_DATATIMEOUT;\r
- SDIO_DataInitStructure.DataLength = BlockSize * NumberOfBlocks;\r
- SDIO_DataInitStructure.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;\r
- SDIO_DataInitStructure.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;\r
- SDIO_DataInitStructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;\r
- SDIO_DataInitStructure.DPSM = SDIO_DPSM_ENABLE;\r
- SDIO_DataConfig(hsd->Instance, &SDIO_DataInitStructure);\r
- \r
- hsd->SdTransferErr = errorState;\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief This function waits until the SD DMA data read transfer is finished. \r
- * This API should be called after HAL_SD_ReadBlocks_DMA() function\r
- * to insure that all data sent by the card is already transferred by the \r
- * DMA controller.\r
- * @param hsd: SD handle\r
- * @param Timeout: Timeout duration \r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t timeout = Timeout;\r
- uint32_t tmp1, tmp2;\r
- HAL_SD_ErrorTypedef tmp3;\r
- \r
- /* Wait for DMA/SD transfer end or SD error variables to be in SD handle */\r
- tmp1 = hsd->DmaTransferCplt; \r
- tmp2 = hsd->SdTransferCplt;\r
- tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;\r
- \r
- while ((tmp1 == 0) && (tmp2 == 0) && (tmp3 == SD_OK) && (timeout > 0))\r
- {\r
- tmp1 = hsd->DmaTransferCplt; \r
- tmp2 = hsd->SdTransferCplt;\r
- tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr; \r
- timeout--;\r
- }\r
- \r
- timeout = Timeout;\r
- \r
- /* Wait until the Rx transfer is no longer active */\r
- while((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXACT)) && (timeout > 0))\r
- {\r
- timeout--; \r
- }\r
- \r
- /* Send stop command in multiblock read */\r
- if (hsd->SdOperation == SD_READ_MULTIPLE_BLOCK)\r
- {\r
- errorState = HAL_SD_StopTransfer(hsd);\r
- }\r
- \r
- if ((timeout == 0) && (errorState == SD_OK))\r
- {\r
- errorState = SD_DATA_TIMEOUT;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- /* Return error state */\r
- if (hsd->SdTransferErr != SD_OK)\r
- {\r
- return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr);\r
- }\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief This function waits until the SD DMA data write transfer is finished. \r
- * This API should be called after HAL_SD_WriteBlocks_DMA() function\r
- * to insure that all data sent by the card is already transferred by the \r
- * DMA controller.\r
- * @param hsd: SD handle\r
- * @param Timeout: Timeout duration \r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t timeout = Timeout;\r
- uint32_t tmp1, tmp2;\r
- HAL_SD_ErrorTypedef tmp3;\r
-\r
- /* Wait for DMA/SD transfer end or SD error variables to be in SD handle */\r
- tmp1 = hsd->DmaTransferCplt; \r
- tmp2 = hsd->SdTransferCplt;\r
- tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;\r
- \r
- while ((tmp1 == 0) && (tmp2 == 0) && (tmp3 == SD_OK) && (timeout > 0))\r
- {\r
- tmp1 = hsd->DmaTransferCplt; \r
- tmp2 = hsd->SdTransferCplt;\r
- tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;\r
- timeout--;\r
- }\r
- \r
- timeout = Timeout;\r
- \r
- /* Wait until the Tx transfer is no longer active */\r
- while((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXACT)) && (timeout > 0))\r
- {\r
- timeout--; \r
- }\r
-\r
- /* Send stop command in multiblock write */\r
- if (hsd->SdOperation == SD_WRITE_MULTIPLE_BLOCK)\r
- {\r
- errorState = HAL_SD_StopTransfer(hsd);\r
- }\r
- \r
- if ((timeout == 0) && (errorState == SD_OK))\r
- {\r
- errorState = SD_DATA_TIMEOUT;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- /* Return error state */\r
- if (hsd->SdTransferErr != SD_OK)\r
- {\r
- return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr);\r
- }\r
- \r
- /* Wait until write is complete */\r
- while(HAL_SD_GetStatus(hsd) != SD_TRANSFER_OK)\r
- { \r
- }\r
-\r
- return errorState; \r
-}\r
-\r
-/**\r
- * @brief Erases the specified memory area of the given SD card.\r
- * @param hsd: SD handle \r
- * @param startaddr: Start byte address\r
- * @param endaddr: End byte address\r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t startaddr, uint64_t endaddr)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- \r
- uint32_t delay = 0;\r
- __IO uint32_t maxdelay = 0;\r
- uint8_t cardstate = 0;\r
- \r
- /* Check if the card command class supports erase command */\r
- if (((hsd->CSD[1] >> 20) & SD_CCCC_ERASE) == 0)\r
- {\r
- errorState = SD_REQUEST_NOT_APPLICABLE;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Get max delay value */\r
- maxdelay = 120000 / (((hsd->Instance->CLKCR) & 0xFF) + 2);\r
- \r
- if((SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)\r
- {\r
- errorState = SD_LOCK_UNLOCK_FAILED;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Get start and end block for high capacity cards */\r
- if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
- {\r
- startaddr /= 512;\r
- endaddr /= 512;\r
- }\r
- \r
- /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */\r
- if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\\r
- (hsd->CardType == HIGH_CAPACITY_SD_CARD))\r
- {\r
- /* Send CMD32 SD_ERASE_GRP_START with argument as addr */\r
- SDIO_CmdInitStructure.Argument =(uint32_t)startaddr;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SD_ERASE_GRP_START;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SD_ERASE_GRP_START);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Send CMD33 SD_ERASE_GRP_END with argument as addr */\r
- SDIO_CmdInitStructure.Argument = (uint32_t)endaddr;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SD_ERASE_GRP_END;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SD_ERASE_GRP_END);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- }\r
- \r
- /* Send CMD38 ERASE */\r
- SDIO_CmdInitStructure.Argument = 0;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_ERASE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_ERASE);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- for (; delay < maxdelay; delay++)\r
- {\r
- }\r
- \r
- /* Wait untill the card is in programming state */\r
- errorState = SD_IsCardProgramming(hsd, &cardstate);\r
- \r
- delay = SD_DATATIMEOUT;\r
- \r
- while ((delay > 0) && (errorState == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))\r
- {\r
- errorState = SD_IsCardProgramming(hsd, &cardstate);\r
- delay--;\r
- }\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief This function handles SD card interrupt request.\r
- * @param hsd: SD handle\r
- * @retval None\r
- */\r
-void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd)\r
-{ \r
- /* Check for SDIO interrupt flags */\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_DATAEND))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_IT_DATAEND); \r
- \r
- /* SD transfer is complete */\r
- hsd->SdTransferCplt = 1;\r
-\r
- /* No transfer error */ \r
- hsd->SdTransferErr = SD_OK;\r
-\r
- HAL_SD_XferCpltCallback(hsd); \r
- } \r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_DCRCFAIL))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);\r
- \r
- hsd->SdTransferErr = SD_DATA_CRC_FAIL;\r
- \r
- HAL_SD_XferErrorCallback(hsd);\r
- \r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_DTIMEOUT))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);\r
- \r
- hsd->SdTransferErr = SD_DATA_TIMEOUT;\r
- \r
- HAL_SD_XferErrorCallback(hsd);\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_RXOVERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);\r
- \r
- hsd->SdTransferErr = SD_RX_OVERRUN;\r
- \r
- HAL_SD_XferErrorCallback(hsd);\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_TXUNDERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_TXUNDERR);\r
- \r
- hsd->SdTransferErr = SD_TX_UNDERRUN;\r
- \r
- HAL_SD_XferErrorCallback(hsd);\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_STBITERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);\r
- \r
- hsd->SdTransferErr = SD_START_BIT_ERR;\r
- \r
- HAL_SD_XferErrorCallback(hsd);\r
- }\r
-\r
- /* Disable all SDIO peripheral interrupt sources */\r
- __HAL_SD_SDIO_DISABLE_IT(hsd, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |\\r
- SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |\\r
- SDIO_IT_RXOVERR | SDIO_IT_STBITERR); \r
-}\r
-\r
-\r
-/**\r
- * @brief SD end of transfer callback.\r
- * @param hsd: SD handle \r
- * @retval None\r
- */\r
-__weak void HAL_SD_XferCpltCallback(SD_HandleTypeDef *hsd)\r
-{\r
- /* NOTE : This function Should not be modified, when the callback is needed,\r
- the HAL_SD_XferCpltCallback could be implemented in the user file\r
- */ \r
-}\r
-\r
-/**\r
- * @brief SD Transfer Error callback.\r
- * @param hsd: SD handle\r
- * @retval None\r
- */\r
-__weak void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd)\r
-{\r
- /* NOTE : This function Should not be modified, when the callback is needed,\r
- the HAL_SD_XferErrorCallback could be implemented in the user file\r
- */ \r
-}\r
-\r
-/**\r
- * @brief SD Transfer complete Rx callback in non blocking mode.\r
- * @param hdma: DMA handle \r
- * @retval None\r
- */\r
-__weak void HAL_SD_DMA_RxCpltCallback(DMA_HandleTypeDef *hdma)\r
-{\r
- /* NOTE : This function Should not be modified, when the callback is needed,\r
- the HAL_SD_DMA_RxCpltCallback could be implemented in the user file\r
- */ \r
-} \r
-\r
-/**\r
- * @brief SD DMA transfer complete Rx error callback.\r
- * @param hdma: DMA handle \r
- * @retval None\r
- */\r
-__weak void HAL_SD_DMA_RxErrorCallback(DMA_HandleTypeDef *hdma)\r
-{\r
- /* NOTE : This function Should not be modified, when the callback is needed,\r
- the HAL_SD_DMA_RxErrorCallback could be implemented in the user file\r
- */ \r
-}\r
-\r
-/**\r
- * @brief SD Transfer complete Tx callback in non blocking mode.\r
- * @param hdma: DMA handle \r
- * @retval None\r
- */\r
-__weak void HAL_SD_DMA_TxCpltCallback(DMA_HandleTypeDef *hdma)\r
-{\r
- /* NOTE : This function Should not be modified, when the callback is needed,\r
- the HAL_SD_DMA_TxCpltCallback could be implemented in the user file\r
- */ \r
-} \r
-\r
-/**\r
- * @brief SD DMA transfer complete error Tx callback.\r
- * @param hdma: DMA handle \r
- * @retval None\r
- */\r
-__weak void HAL_SD_DMA_TxErrorCallback(DMA_HandleTypeDef *hdma)\r
-{\r
- /* NOTE : This function Should not be modified, when the callback is needed,\r
- the HAL_SD_DMA_TxErrorCallback could be implemented in the user file\r
- */ \r
-}\r
-\r
-/**\r
- * @}\r
- */\r
-\r
-/** @defgroup SD_Group3 Peripheral Control functions \r
- * @brief management functions \r
- *\r
-@verbatim \r
- ==============================================================================\r
- ##### Peripheral Control functions #####\r
- ============================================================================== \r
- [..]\r
- This subsection provides a set of functions allowing to control the SD card \r
- operations.\r
-\r
-@endverbatim\r
- * @{\r
- */\r
-\r
-/**\r
- * @brief Returns information about specific card.\r
- * @param hsd: SD handle\r
- * @param pCardInfo: Pointer to a HAL_SD_CardInfoTypedef structure that \r
- * contains all SD cardinformation \r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_Get_CardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *pCardInfo)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t tmp = 0;\r
- \r
- pCardInfo->CardType = (uint8_t)(hsd->CardType);\r
- pCardInfo->RCA = (uint16_t)(hsd->RCA);\r
- \r
- /* Byte 0 */\r
- tmp = (hsd->CSD[0] & 0xFF000000) >> 24;\r
- pCardInfo->SD_csd.CSDStruct = (uint8_t)((tmp & 0xC0) >> 6);\r
- pCardInfo->SD_csd.SysSpecVersion = (uint8_t)((tmp & 0x3C) >> 2);\r
- pCardInfo->SD_csd.Reserved1 = tmp & 0x03;\r
- \r
- /* Byte 1 */\r
- tmp = (hsd->CSD[0] & 0x00FF0000) >> 16;\r
- pCardInfo->SD_csd.TAAC = (uint8_t)tmp;\r
- \r
- /* Byte 2 */\r
- tmp = (hsd->CSD[0] & 0x0000FF00) >> 8;\r
- pCardInfo->SD_csd.NSAC = (uint8_t)tmp;\r
- \r
- /* Byte 3 */\r
- tmp = hsd->CSD[0] & 0x000000FF;\r
- pCardInfo->SD_csd.MaxBusClkFrec = (uint8_t)tmp;\r
- \r
- /* Byte 4 */\r
- tmp = (hsd->CSD[1] & 0xFF000000) >> 24;\r
- pCardInfo->SD_csd.CardComdClasses = (uint16_t)(tmp << 4);\r
- \r
- /* Byte 5 */\r
- tmp = (hsd->CSD[1] & 0x00FF0000) >> 16;\r
- pCardInfo->SD_csd.CardComdClasses |= (uint16_t)((tmp & 0xF0) >> 4);\r
- pCardInfo->SD_csd.RdBlockLen = (uint8_t)(tmp & 0x0F);\r
- \r
- /* Byte 6 */\r
- tmp = (hsd->CSD[1] & 0x0000FF00) >> 8;\r
- pCardInfo->SD_csd.PartBlockRead = (uint8_t)((tmp & 0x80) >> 7);\r
- pCardInfo->SD_csd.WrBlockMisalign = (uint8_t)((tmp & 0x40) >> 6);\r
- pCardInfo->SD_csd.RdBlockMisalign = (uint8_t)((tmp & 0x20) >> 5);\r
- pCardInfo->SD_csd.DSRImpl = (uint8_t)((tmp & 0x10) >> 4);\r
- pCardInfo->SD_csd.Reserved2 = 0; /*!< Reserved */\r
- \r
- if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0))\r
- {\r
- pCardInfo->SD_csd.DeviceSize = (tmp & 0x03) << 10;\r
- \r
- /* Byte 7 */\r
- tmp = (uint8_t)(hsd->CSD[1] & 0x000000FF);\r
- pCardInfo->SD_csd.DeviceSize |= (tmp) << 2;\r
- \r
- /* Byte 8 */\r
- tmp = (uint8_t)((hsd->CSD[2] & 0xFF000000) >> 24);\r
- pCardInfo->SD_csd.DeviceSize |= (tmp & 0xC0) >> 6;\r
- \r
- pCardInfo->SD_csd.MaxRdCurrentVDDMin = (tmp & 0x38) >> 3;\r
- pCardInfo->SD_csd.MaxRdCurrentVDDMax = (tmp & 0x07);\r
- \r
- /* Byte 9 */\r
- tmp = (uint8_t)((hsd->CSD[2] & 0x00FF0000) >> 16);\r
- pCardInfo->SD_csd.MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5;\r
- pCardInfo->SD_csd.MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2;\r
- pCardInfo->SD_csd.DeviceSizeMul = (tmp & 0x03) << 1;\r
- /* Byte 10 */\r
- tmp = (uint8_t)((hsd->CSD[2] & 0x0000FF00) >> 8);\r
- pCardInfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7;\r
- \r
- pCardInfo->CardCapacity = (pCardInfo->SD_csd.DeviceSize + 1) ;\r
- pCardInfo->CardCapacity *= (1 << (pCardInfo->SD_csd.DeviceSizeMul + 2));\r
- pCardInfo->CardBlockSize = 1 << (pCardInfo->SD_csd.RdBlockLen);\r
- pCardInfo->CardCapacity *= pCardInfo->CardBlockSize;\r
- }\r
- else if (hsd->CardType == HIGH_CAPACITY_SD_CARD)\r
- {\r
- /* Byte 7 */\r
- tmp = (uint8_t)(hsd->CSD[1] & 0x000000FF);\r
- pCardInfo->SD_csd.DeviceSize = (tmp & 0x3F) << 16;\r
- \r
- /* Byte 8 */\r
- tmp = (uint8_t)((hsd->CSD[2] & 0xFF000000) >> 24);\r
- \r
- pCardInfo->SD_csd.DeviceSize |= (tmp << 8);\r
- \r
- /* Byte 9 */\r
- tmp = (uint8_t)((hsd->CSD[2] & 0x00FF0000) >> 16);\r
- \r
- pCardInfo->SD_csd.DeviceSize |= (tmp);\r
- \r
- /* Byte 10 */\r
- tmp = (uint8_t)((hsd->CSD[2] & 0x0000FF00) >> 8);\r
- \r
- pCardInfo->CardCapacity = ((pCardInfo->SD_csd.DeviceSize + 1)) * 512 * 1024;\r
- pCardInfo->CardBlockSize = 512; \r
- }\r
- \r
- pCardInfo->SD_csd.EraseGrSize = (tmp & 0x40) >> 6;\r
- pCardInfo->SD_csd.EraseGrMul = (tmp & 0x3F) << 1;\r
- \r
- /* Byte 11 */\r
- tmp = (uint8_t)(hsd->CSD[2] & 0x000000FF);\r
- pCardInfo->SD_csd.EraseGrMul |= (tmp & 0x80) >> 7;\r
- pCardInfo->SD_csd.WrProtectGrSize = (tmp & 0x7F);\r
- \r
- /* Byte 12 */\r
- tmp = (uint8_t)((hsd->CSD[3] & 0xFF000000) >> 24);\r
- pCardInfo->SD_csd.WrProtectGrEnable = (tmp & 0x80) >> 7;\r
- pCardInfo->SD_csd.ManDeflECC = (tmp & 0x60) >> 5;\r
- pCardInfo->SD_csd.WrSpeedFact = (tmp & 0x1C) >> 2;\r
- pCardInfo->SD_csd.MaxWrBlockLen = (tmp & 0x03) << 2;\r
- \r
- /* Byte 13 */\r
- tmp = (uint8_t)((hsd->CSD[3] & 0x00FF0000) >> 16);\r
- pCardInfo->SD_csd.MaxWrBlockLen |= (tmp & 0xC0) >> 6;\r
- pCardInfo->SD_csd.WriteBlockPaPartial = (tmp & 0x20) >> 5;\r
- pCardInfo->SD_csd.Reserved3 = 0;\r
- pCardInfo->SD_csd.ContentProtectAppli = (tmp & 0x01);\r
- \r
- /* Byte 14 */\r
- tmp = (uint8_t)((hsd->CSD[3] & 0x0000FF00) >> 8);\r
- pCardInfo->SD_csd.FileFormatGrouop = (tmp & 0x80) >> 7;\r
- pCardInfo->SD_csd.CopyFlag = (tmp & 0x40) >> 6;\r
- pCardInfo->SD_csd.PermWrProtect = (tmp & 0x20) >> 5;\r
- pCardInfo->SD_csd.TempWrProtect = (tmp & 0x10) >> 4;\r
- pCardInfo->SD_csd.FileFormat = (tmp & 0x0C) >> 2;\r
- pCardInfo->SD_csd.ECC = (tmp & 0x03);\r
- \r
- /* Byte 15 */\r
- tmp = (uint8_t)(hsd->CSD[3] & 0x000000FF);\r
- pCardInfo->SD_csd.CSD_CRC = (tmp & 0xFE) >> 1;\r
- pCardInfo->SD_csd.Reserved4 = 1;\r
- \r
- /* Byte 0 */\r
- tmp = (uint8_t)((hsd->CID[0] & 0xFF000000) >> 24);\r
- pCardInfo->SD_cid.ManufacturerID = tmp;\r
- \r
- /* Byte 1 */\r
- tmp = (uint8_t)((hsd->CID[0] & 0x00FF0000) >> 16);\r
- pCardInfo->SD_cid.OEM_AppliID = tmp << 8;\r
- \r
- /* Byte 2 */\r
- tmp = (uint8_t)((hsd->CID[0] & 0x000000FF00) >> 8);\r
- pCardInfo->SD_cid.OEM_AppliID |= tmp;\r
- \r
- /* Byte 3 */\r
- tmp = (uint8_t)(hsd->CID[0] & 0x000000FF);\r
- pCardInfo->SD_cid.ProdName1 = tmp << 24;\r
- \r
- /* Byte 4 */\r
- tmp = (uint8_t)((hsd->CID[1] & 0xFF000000) >> 24);\r
- pCardInfo->SD_cid.ProdName1 |= tmp << 16;\r
- \r
- /* Byte 5 */\r
- tmp = (uint8_t)((hsd->CID[1] & 0x00FF0000) >> 16);\r
- pCardInfo->SD_cid.ProdName1 |= tmp << 8;\r
- \r
- /* Byte 6 */\r
- tmp = (uint8_t)((hsd->CID[1] & 0x0000FF00) >> 8);\r
- pCardInfo->SD_cid.ProdName1 |= tmp;\r
- \r
- /* Byte 7 */\r
- tmp = (uint8_t)(hsd->CID[1] & 0x000000FF);\r
- pCardInfo->SD_cid.ProdName2 = tmp;\r
- \r
- /* Byte 8 */\r
- tmp = (uint8_t)((hsd->CID[2] & 0xFF000000) >> 24);\r
- pCardInfo->SD_cid.ProdRev = tmp;\r
- \r
- /* Byte 9 */\r
- tmp = (uint8_t)((hsd->CID[2] & 0x00FF0000) >> 16);\r
- pCardInfo->SD_cid.ProdSN = tmp << 24;\r
- \r
- /* Byte 10 */\r
- tmp = (uint8_t)((hsd->CID[2] & 0x0000FF00) >> 8);\r
- pCardInfo->SD_cid.ProdSN |= tmp << 16;\r
- \r
- /* Byte 11 */\r
- tmp = (uint8_t)(hsd->CID[2] & 0x000000FF);\r
- pCardInfo->SD_cid.ProdSN |= tmp << 8;\r
- \r
- /* Byte 12 */\r
- tmp = (uint8_t)((hsd->CID[3] & 0xFF000000) >> 24);\r
- pCardInfo->SD_cid.ProdSN |= tmp;\r
- \r
- /* Byte 13 */\r
- tmp = (uint8_t)((hsd->CID[3] & 0x00FF0000) >> 16);\r
- pCardInfo->SD_cid.Reserved1 |= (tmp & 0xF0) >> 4;\r
- pCardInfo->SD_cid.ManufactDate = (tmp & 0x0F) << 8;\r
- \r
- /* Byte 14 */\r
- tmp = (uint8_t)((hsd->CID[3] & 0x0000FF00) >> 8);\r
- pCardInfo->SD_cid.ManufactDate |= tmp;\r
- \r
- /* Byte 15 */\r
- tmp = (uint8_t)(hsd->CID[3] & 0x000000FF);\r
- pCardInfo->SD_cid.CID_CRC = (tmp & 0xFE) >> 1;\r
- pCardInfo->SD_cid.Reserved2 = 1;\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Enables wide bus operation for the requested card if supported by \r
- * card.\r
- * @param hsd: SD handle \r
- * @param WideMode: Specifies the SD card wide bus mode \r
- * This parameter can be one of the following values:\r
- * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer (Only for MMC)\r
- * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer\r
- * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer\r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_WideBusOperation_Config(SD_HandleTypeDef *hsd, uint32_t WideMode)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- SDIO_InitTypeDef Init;\r
- \r
- /* MMC Card does not support this feature */\r
- if (hsd->CardType == MULTIMEDIA_CARD)\r
- {\r
- errorState = SD_UNSUPPORTED_FEATURE;\r
- \r
- return errorState;\r
- }\r
- else if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\\r
- (hsd->CardType == HIGH_CAPACITY_SD_CARD))\r
- {\r
- if (WideMode == SDIO_BUS_WIDE_8B)\r
- {\r
- errorState = SD_UNSUPPORTED_FEATURE;\r
- \r
- return errorState;\r
- }\r
- else if (WideMode == SDIO_BUS_WIDE_4B)\r
- {\r
- errorState = SD_WideBus_Enable(hsd);\r
- \r
- if (errorState == SD_OK)\r
- {\r
- /* Configure the SDIO peripheral */\r
- Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;\r
- Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;\r
- Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;\r
- Init.BusWide = SDIO_BUS_WIDE_4B;\r
- Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;\r
- Init.ClockDiv = SDIO_TRANSFER_CLK_DIV;\r
- \r
- /* Configure SDIO peripheral interface */\r
- SDIO_Init(hsd->Instance, Init);\r
- }\r
- }\r
- else\r
- {\r
- errorState = SD_WideBus_Disable(hsd);\r
- \r
- if (errorState == SD_OK)\r
- {\r
- /* Configure the SDIO peripheral */\r
- Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;\r
- Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;\r
- Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;\r
- Init.BusWide = SDIO_BUS_WIDE_1B;\r
- Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;\r
- Init.ClockDiv = SDIO_TRANSFER_CLK_DIV;\r
- \r
- /* Configure SDIO peripheral interface */\r
- SDIO_Init(hsd->Instance, Init);\r
- }\r
- }\r
- }\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Aborts an ongoing data transfer.\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_StopTransfer(SD_HandleTypeDef *hsd)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- \r
- /* Send CMD12 STOP_TRANSMISSION */\r
- SDIO_CmdInitStructure.Argument = 0;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_STOP_TRANSMISSION;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_STOP_TRANSMISSION);\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Switches the SD card to High Speed mode.\r
- * This API must be used after "Transfer State"\r
- * @note This operation should be followed by the configuration \r
- * of PLL to have SDIOCK clock between 67 and 75 MHz\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_HighSpeed (SD_HandleTypeDef *hsd)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- SDIO_DataInitTypeDef SDIO_DataInitStructure;\r
- \r
- uint8_t SD_hs[64] = {0};\r
- uint32_t SD_scr[2] = {0, 0};\r
- uint32_t SD_SPEC = 0 ;\r
- uint32_t count = 0, *tempbuff = (uint32_t *)SD_hs;\r
- \r
- /* Initialize the Data control register */\r
- hsd->Instance->DCTRL = 0;\r
- \r
- /* Get SCR Register */\r
- errorState = SD_FindSCR(hsd, SD_scr);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Test the Version supported by the card*/ \r
- SD_SPEC = (SD_scr[1] & 0x01000000) | (SD_scr[1] & 0x02000000);\r
- \r
- if (SD_SPEC != SD_ALLZERO)\r
- {\r
- /* Set Block Size for Card */\r
- SDIO_CmdInitStructure.Argument = (uint32_t)64;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SET_BLOCKLEN;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Configure the SD DPSM (Data Path State Machine) */\r
- SDIO_DataInitStructure.DataTimeOut = SD_DATATIMEOUT;\r
- SDIO_DataInitStructure.DataLength = 64;\r
- SDIO_DataInitStructure.DataBlockSize = SDIO_DATABLOCK_SIZE_64B ;\r
- SDIO_DataInitStructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;\r
- SDIO_DataInitStructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;\r
- SDIO_DataInitStructure.DPSM = SDIO_DPSM_ENABLE;\r
- SDIO_DataConfig(hsd->Instance, &SDIO_DataInitStructure);\r
- \r
- /* Send CMD6 switch mode */\r
- SDIO_CmdInitStructure.Argument = 0x80FFFF01;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_HS_SWITCH;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure); \r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_HS_SWITCH);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))\r
- {\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))\r
- {\r
- for (count = 0; count < 8; count++)\r
- {\r
- *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance);\r
- }\r
- \r
- tempbuff += 8;\r
- }\r
- }\r
- \r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);\r
- \r
- errorState = SD_DATA_TIMEOUT;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);\r
- \r
- errorState = SD_DATA_CRC_FAIL;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);\r
- \r
- errorState = SD_RX_OVERRUN;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);\r
- \r
- errorState = SD_START_BIT_ERR;\r
- \r
- return errorState;\r
- }\r
- \r
- count = SD_DATATIMEOUT;\r
- \r
- while ((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (count > 0))\r
- {\r
- *tempbuff = SDIO_ReadFIFO(hsd->Instance);\r
- tempbuff++;\r
- count--;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- /* Test if the switch mode HS is ok */\r
- if ((SD_hs[13]& 2) != 2)\r
- {\r
- errorState = SD_UNSUPPORTED_FEATURE;\r
- } \r
- }\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @}\r
- */\r
-\r
-/** @defgroup SD_Group4 Peripheral State functions \r
- * @brief Peripheral State functions \r
- *\r
-@verbatim \r
- ==============================================================================\r
- ##### Peripheral State functions #####\r
- ============================================================================== \r
- [..]\r
- This subsection permits to get in runtime the status of the peripheral \r
- and the data flow.\r
-\r
-@endverbatim\r
- * @{\r
- */\r
-\r
-/**\r
- * @brief Returns the current SD card's status.\r
- * @param hsd: SD handle\r
- * @param pSDstatus: Pointer to the buffer that will contain the SD card status \r
- * SD Status register)\r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- SDIO_DataInitTypeDef SDIO_DataInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t count = 0;\r
- \r
- /* Check SD response */\r
- if ((SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)\r
- {\r
- errorState = SD_LOCK_UNLOCK_FAILED;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Set block size for card if it is not equal to current block size for card */\r
- SDIO_CmdInitStructure.Argument = 64;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SET_BLOCKLEN;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Send CMD55 */\r
- SDIO_CmdInitStructure.Argument = (uint32_t)(hsd->RCA << 16);\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_APP_CMD;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Configure the SD DPSM (Data Path State Machine) */ \r
- SDIO_DataInitStructure.DataTimeOut = SD_DATATIMEOUT;\r
- SDIO_DataInitStructure.DataLength = 64;\r
- SDIO_DataInitStructure.DataBlockSize = SDIO_DATABLOCK_SIZE_64B;\r
- SDIO_DataInitStructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;\r
- SDIO_DataInitStructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;\r
- SDIO_DataInitStructure.DPSM = SDIO_DPSM_ENABLE;\r
- SDIO_DataConfig(hsd->Instance, &SDIO_DataInitStructure);\r
- \r
- /* Send ACMD13 (SD_APP_STAUS) with argument as card's RCA */\r
- SDIO_CmdInitStructure.Argument = 0;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SD_APP_STAUS;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SD_APP_STAUS);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Get status data */\r
- while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))\r
- {\r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))\r
- {\r
- for (count = 0; count < 8; count++)\r
- {\r
- *(pSDstatus + count) = SDIO_ReadFIFO(hsd->Instance);\r
- }\r
- \r
- pSDstatus += 8;\r
- }\r
- }\r
- \r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);\r
- \r
- errorState = SD_DATA_TIMEOUT;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);\r
- \r
- errorState = SD_DATA_CRC_FAIL;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);\r
- \r
- errorState = SD_RX_OVERRUN;\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);\r
- \r
- errorState = SD_START_BIT_ERR;\r
- \r
- return errorState;\r
- }\r
- \r
- count = SD_DATATIMEOUT;\r
- while ((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (count > 0))\r
- {\r
- *pSDstatus = SDIO_ReadFIFO(hsd->Instance);\r
- pSDstatus++;\r
- count--;\r
- }\r
- \r
- /* Clear all the static status flags*/\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Gets the current sd card data status.\r
- * @param hsd: SD handle\r
- * @retval Data Transfer state\r
- */\r
-HAL_SD_TransferStateTypedef HAL_SD_GetStatus(SD_HandleTypeDef *hsd)\r
-{\r
- HAL_SD_CardStateTypedef cardstate = SD_CARD_TRANSFER;\r
-\r
- /* Get SD card state */\r
- cardstate = SD_GetState(hsd);\r
- \r
- /* Find SD status according to card state*/\r
- if (cardstate == SD_CARD_TRANSFER)\r
- {\r
- return SD_TRANSFER_OK;\r
- }\r
- else if(cardstate == SD_CARD_ERROR)\r
- {\r
- return SD_TRANSFER_ERROR;\r
- }\r
- else\r
- {\r
- return SD_TRANSFER_BUSY;\r
- }\r
-}\r
-\r
-/**\r
- * @brief Gets the SD card status.\r
- * @param hsd: SD handle \r
- * @param pCardStatus: Pointer to the HAL_SD_CardStatusTypedef structure that \r
- * will contain the SD card status information \r
- * @retval SD Card error state\r
- */\r
-HAL_SD_ErrorTypedef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypedef *pCardStatus)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t tmp = 0;\r
- uint32_t SD_STATUS[16];\r
- \r
- errorState = HAL_SD_SendSDStatus(hsd, SD_STATUS);\r
- \r
- if (errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Byte 0 */\r
- tmp = (SD_STATUS[0] & 0xC0) >> 6;\r
- pCardStatus->DAT_BUS_WIDTH = (uint8_t)tmp;\r
- \r
- /* Byte 0 */\r
- tmp = (SD_STATUS[0] & 0x20) >> 5;\r
- pCardStatus->SECURED_MODE = (uint8_t)tmp;\r
- \r
- /* Byte 2 */\r
- tmp = (SD_STATUS[2] & 0xFF);\r
- pCardStatus->SD_CARD_TYPE = (uint8_t)(tmp << 8);\r
- \r
- /* Byte 3 */\r
- tmp = (SD_STATUS[3] & 0xFF);\r
- pCardStatus->SD_CARD_TYPE |= (uint8_t)tmp;\r
- \r
- /* Byte 4 */\r
- tmp = (SD_STATUS[4] & 0xFF);\r
- pCardStatus->SIZE_OF_PROTECTED_AREA = (uint8_t)(tmp << 24);\r
- \r
- /* Byte 5 */\r
- tmp = (SD_STATUS[5] & 0xFF);\r
- pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(tmp << 16);\r
- \r
- /* Byte 6 */\r
- tmp = (SD_STATUS[6] & 0xFF);\r
- pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(tmp << 8);\r
- \r
- /* Byte 7 */\r
- tmp = (SD_STATUS[7] & 0xFF);\r
- pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)tmp;\r
- \r
- /* Byte 8 */\r
- tmp = (SD_STATUS[8] & 0xFF);\r
- pCardStatus->SPEED_CLASS = (uint8_t)tmp;\r
- \r
- /* Byte 9 */\r
- tmp = (SD_STATUS[9] & 0xFF);\r
- pCardStatus->PERFORMANCE_MOVE = (uint8_t)tmp;\r
- \r
- /* Byte 10 */\r
- tmp = (SD_STATUS[10] & 0xF0) >> 4;\r
- pCardStatus->AU_SIZE = (uint8_t)tmp;\r
- \r
- /* Byte 11 */\r
- tmp = (SD_STATUS[11] & 0xFF);\r
- pCardStatus->ERASE_SIZE = (uint8_t)(tmp << 8);\r
- \r
- /* Byte 12 */\r
- tmp = (SD_STATUS[12] & 0xFF);\r
- pCardStatus->ERASE_SIZE |= (uint8_t)tmp;\r
- \r
- /* Byte 13 */\r
- tmp = (SD_STATUS[13] & 0xFC) >> 2;\r
- pCardStatus->ERASE_TIMEOUT = (uint8_t)tmp;\r
- \r
- /* Byte 13 */\r
- tmp = (SD_STATUS[13] & 0x3);\r
- pCardStatus->ERASE_OFFSET = (uint8_t)tmp;\r
- \r
- return errorState;\r
-}\r
- \r
-/**\r
- * @}\r
- */\r
-\r
-/**\r
- * @brief SD DMA transfer complete Rx callback.\r
- * @param hdma: DMA handle \r
- * @retval None\r
- */\r
-static void SD_DMA_RxCplt(DMA_HandleTypeDef *hdma)\r
-{\r
- SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;\r
- \r
- /* DMA transfer is complete */\r
- hsd->DmaTransferCplt = 1;\r
- \r
- /* Wait until SD transfer is complete */\r
- while(hsd->SdTransferCplt == 0)\r
- {\r
- }\r
- \r
- /* Transfer complete user callback */\r
- HAL_SD_DMA_RxCpltCallback(hsd->hdmarx); \r
-}\r
-\r
-/**\r
- * @brief SD DMA transfer Error Rx callback.\r
- * @param hdma: DMA handle \r
- * @retval None\r
- */\r
-static void SD_DMA_RxError(DMA_HandleTypeDef *hdma)\r
-{\r
- SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;\r
- \r
- /* Transfer complete user callback */\r
- HAL_SD_DMA_RxErrorCallback(hsd->hdmarx);\r
-}\r
-\r
-/**\r
- * @brief SD DMA transfer complete Tx callback.\r
- * @param hdma: DMA handle \r
- * @retval None\r
- */\r
-static void SD_DMA_TxCplt(DMA_HandleTypeDef *hdma)\r
-{\r
- SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;\r
- \r
- /* DMA transfer is complete */\r
- hsd->DmaTransferCplt = 1;\r
- \r
- /* Wait until SD transfer is complete */\r
- while(hsd->SdTransferCplt == 0)\r
- {\r
- }\r
- \r
- /* Transfer complete user callback */\r
- HAL_SD_DMA_TxCpltCallback(hsd->hdmatx); \r
-}\r
-\r
-/**\r
- * @brief SD DMA transfer Error Tx callback.\r
- * @param hdma: DMA handle \r
- * @retval None\r
- */\r
-static void SD_DMA_TxError(DMA_HandleTypeDef *hdma)\r
-{\r
- SD_HandleTypeDef *hsd = ( SD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
- \r
- /* Transfer complete user callback */\r
- HAL_SD_DMA_TxErrorCallback(hsd->hdmatx);\r
-}\r
-\r
-/**\r
- * @brief Returns the SD current state.\r
- * @param hsd: SD handle\r
- * @retval SD card current state\r
- */\r
-static HAL_SD_CardStateTypedef SD_GetState(SD_HandleTypeDef *hsd)\r
-{\r
- uint32_t resp1 = 0;\r
- \r
- if (SD_SendStatus(hsd, &resp1) != SD_OK)\r
- {\r
- return SD_CARD_ERROR;\r
- }\r
- else\r
- {\r
- return (HAL_SD_CardStateTypedef)((resp1 >> 9) & 0x0F);\r
- }\r
-}\r
-\r
-/**\r
- * @brief Initializes all cards or single card as the case may be Card(s) come \r
- * into standby state.\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_Initialize_Cards(SD_HandleTypeDef *hsd)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure; \r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint16_t sd_rca = 1;\r
- \r
- if(SDIO_GetPowerState(hsd->Instance) == 0) /* Power off */\r
- {\r
- errorState = SD_REQUEST_NOT_APPLICABLE;\r
- \r
- return errorState;\r
- }\r
- \r
- if(hsd->CardType != SECURE_DIGITAL_IO_CARD)\r
- {\r
- /* Send CMD2 ALL_SEND_CID */\r
- SDIO_CmdInitStructure.Argument = 0;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_ALL_SEND_CID;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_LONG;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp2Error(hsd);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Get Card identification number data */\r
- hsd->CID[0] = SDIO_GetResponse(SDIO_RESP1);\r
- hsd->CID[1] = SDIO_GetResponse(SDIO_RESP2);\r
- hsd->CID[2] = SDIO_GetResponse(SDIO_RESP3);\r
- hsd->CID[3] = SDIO_GetResponse(SDIO_RESP4);\r
- }\r
- \r
- if((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\\r
- (hsd->CardType == SECURE_DIGITAL_IO_COMBO_CARD) || (hsd->CardType == HIGH_CAPACITY_SD_CARD))\r
- {\r
- /* Send CMD3 SET_REL_ADDR with argument 0 */\r
- /* SD Card publishes its RCA. */\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SET_REL_ADDR;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp6Error(hsd, SD_CMD_SET_REL_ADDR, &sd_rca);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- }\r
- \r
- if (hsd->CardType != SECURE_DIGITAL_IO_CARD)\r
- {\r
- /* Get the SD card RCA */\r
- hsd->RCA = sd_rca;\r
- \r
- /* Send CMD9 SEND_CSD with argument as card's RCA */\r
- SDIO_CmdInitStructure.Argument = (uint32_t)(hsd->RCA << 16);\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SEND_CSD;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_LONG;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp2Error(hsd);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Get Card Specific Data */\r
- hsd->CSD[0] = SDIO_GetResponse(SDIO_RESP1);\r
- hsd->CSD[1] = SDIO_GetResponse(SDIO_RESP2);\r
- hsd->CSD[2] = SDIO_GetResponse(SDIO_RESP3);\r
- hsd->CSD[3] = SDIO_GetResponse(SDIO_RESP4);\r
- }\r
- \r
- /* All cards are initialized */\r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Selects od Deselects the corresponding card.\r
- * @param hsd: SD handle\r
- * @param addr: Address of the card to be selected \r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_Select_Deselect(SD_HandleTypeDef *hsd, uint64_t addr)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- \r
- /* Send CMD7 SDIO_SEL_DESEL_CARD */\r
- SDIO_CmdInitStructure.Argument = (uint32_t)addr;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SEL_DESEL_CARD;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SEL_DESEL_CARD);\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Enquires cards about their operating voltage and configures clock\r
- * controls and stores SD information that will be needed in future\r
- * in the SD handle.\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure; \r
- __IO HAL_SD_ErrorTypedef errorState = SD_OK; \r
- uint32_t response = 0, count = 0, validvoltage = 0;\r
- uint32_t SDType = SD_STD_CAPACITY;\r
- \r
- /* Power ON Sequence -------------------------------------------------------*/\r
- /* Disable SDIO Clock */\r
- __HAL_SD_SDIO_DISABLE(); \r
- \r
- /* Set Power State to ON */\r
- SDIO_PowerState_ON(hsd->Instance);\r
- \r
- /* Enable SDIO Clock */\r
- __HAL_SD_SDIO_ENABLE();\r
- \r
- /* CMD0: GO_IDLE_STATE -----------------------------------------------------*/\r
- /* No CMD response required */\r
- SDIO_CmdInitStructure.Argument = 0;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_GO_IDLE_STATE;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_NO;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdError(hsd);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- /* CMD Response TimeOut (wait for CMDSENT flag) */\r
- return errorState;\r
- }\r
- \r
- /* CMD8: SEND_IF_COND ------------------------------------------------------*/\r
- /* Send CMD8 to verify SD card interface operating condition */\r
- /* Argument: - [31:12]: Reserved (shall be set to '0')\r
- - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)\r
- - [7:0]: Check Pattern (recommended 0xAA) */\r
- /* CMD Response: R7 */\r
- SDIO_CmdInitStructure.Argument = SD_CHECK_PATTERN;\r
- SDIO_CmdInitStructure.CmdIndex = SD_SDIO_SEND_IF_COND;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */ \r
- errorState = SD_CmdResp7Error(hsd);\r
- \r
- if (errorState == SD_OK)\r
- {\r
- /* SD Card 2.0 */\r
- hsd->CardType = STD_CAPACITY_SD_CARD_V2_0; \r
- SDType = SD_HIGH_CAPACITY;\r
- }\r
- \r
- /* Send CMD55 */\r
- SDIO_CmdInitStructure.Argument = 0;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_APP_CMD;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
- \r
- /* If errorState is Command TimeOut, it is a MMC card */\r
- /* If errorState is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch)\r
- or SD card 1.x */\r
- if(errorState == SD_OK)\r
- {\r
- /* SD CARD */\r
- /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */\r
- while((!validvoltage) && (count < SD_MAX_VOLT_TRIAL))\r
- {\r
- \r
- /* SEND CMD55 APP_CMD with RCA as 0 */\r
- SDIO_CmdInitStructure.Argument = 0;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_APP_CMD;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Send CMD41 */\r
- SDIO_CmdInitStructure.Argument = SD_VOLTAGE_WINDOW_SD | SDType;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SD_APP_OP_COND;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp3Error(hsd);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Get command response */\r
- response = SDIO_GetResponse(SDIO_RESP1);\r
- \r
- /* Get operating voltage*/\r
- validvoltage = (((response >> 31) == 1) ? 1 : 0);\r
- \r
- count++;\r
- }\r
- \r
- if(count >= SD_MAX_VOLT_TRIAL)\r
- {\r
- errorState = SD_INVALID_VOLTRANGE;\r
- \r
- return errorState;\r
- }\r
- \r
- if((response & SD_HIGH_CAPACITY) == SD_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */\r
- {\r
- hsd->CardType = HIGH_CAPACITY_SD_CARD;\r
- }\r
- \r
- } /* else MMC Card */\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Turns the SDIO output signals off.\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_PowerOFF(SD_HandleTypeDef *hsd)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- \r
- /* Set Power State to OFF */\r
- SDIO_PowerState_OFF(hsd->Instance);\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Returns the current card's status.\r
- * @param hsd: SD handle\r
- * @param pCardStatus: pointer to the buffer that will contain the SD card \r
- * status (Card Status register) \r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- \r
- if(pCardStatus == NULL)\r
- {\r
- errorState = SD_INVALID_PARAMETER;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Send Status command */\r
- SDIO_CmdInitStructure.Argument = (uint32_t)(hsd->RCA << 16);\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SEND_STATUS;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SEND_STATUS);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Get SD card status */\r
- *pCardStatus = SDIO_GetResponse(SDIO_RESP1);\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Checks for error conditions for CMD0.\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_CmdError(SD_HandleTypeDef *hsd)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t timeout, tmp;\r
- \r
- timeout = SDIO_CMD0TIMEOUT;\r
- \r
- tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CMDSENT);\r
- \r
- while((timeout > 0) && (!tmp))\r
- {\r
- tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CMDSENT);\r
- timeout--;\r
- }\r
- \r
- if(timeout == 0)\r
- {\r
- errorState = SD_CMD_RSP_TIMEOUT;\r
- return errorState;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Checks for error conditions for R7 response.\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_CmdResp7Error(SD_HandleTypeDef *hsd)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_ERROR;\r
- uint32_t timeout = SDIO_CMD0TIMEOUT, tmp;\r
- \r
- tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT); \r
- \r
- while((!tmp) && (timeout > 0))\r
- {\r
- tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT);\r
- timeout--;\r
- }\r
- \r
- tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT); \r
- \r
- if((timeout == 0) || tmp)\r
- {\r
- /* Card is not V2.0 compliant or card does not support the set voltage range */\r
- errorState = SD_CMD_RSP_TIMEOUT;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);\r
- \r
- return errorState;\r
- }\r
- \r
- if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CMDREND))\r
- {\r
- /* Card is SD V2.0 compliant */\r
- errorState = SD_OK;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CMDREND);\r
- \r
- return errorState;\r
- }\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Checks for error conditions for R1 response.\r
- * @param hsd: SD handle\r
- * @param SD_CMD: The sent command index \r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_CmdResp1Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t response_R1;\r
- \r
- while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))\r
- {\r
- }\r
- \r
- if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT))\r
- {\r
- errorState = SD_CMD_RSP_TIMEOUT;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);\r
- \r
- return errorState;\r
- }\r
- else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL))\r
- {\r
- errorState = SD_CMD_CRC_FAIL;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL);\r
- \r
- return errorState;\r
- }\r
- \r
- /* Check response received is of desired command */\r
- if(SDIO_GetCommandResponse(hsd->Instance) != SD_CMD)\r
- {\r
- errorState = SD_ILLEGAL_CMD;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- /* We have received response, retrieve it for analysis */\r
- response_R1 = SDIO_GetResponse(SDIO_RESP1);\r
- \r
- if((response_R1 & SD_OCR_ERRORBITS) == SD_ALLZERO)\r
- {\r
- return errorState;\r
- }\r
- \r
- if((response_R1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE)\r
- {\r
- return(SD_ADDR_OUT_OF_RANGE);\r
- }\r
- \r
- if((response_R1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED)\r
- {\r
- return(SD_ADDR_MISALIGNED);\r
- }\r
- \r
- if((response_R1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR)\r
- {\r
- return(SD_BLOCK_LEN_ERR);\r
- }\r
- \r
- if((response_R1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR)\r
- {\r
- return(SD_ERASE_SEQ_ERR);\r
- }\r
- \r
- if((response_R1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM)\r
- {\r
- return(SD_BAD_ERASE_PARAM);\r
- }\r
- \r
- if((response_R1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION)\r
- {\r
- return(SD_WRITE_PROT_VIOLATION);\r
- }\r
- \r
- if((response_R1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED)\r
- {\r
- return(SD_LOCK_UNLOCK_FAILED);\r
- }\r
- \r
- if((response_R1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED)\r
- {\r
- return(SD_COM_CRC_FAILED);\r
- }\r
- \r
- if((response_R1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD)\r
- {\r
- return(SD_ILLEGAL_CMD);\r
- }\r
- \r
- if((response_R1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED)\r
- {\r
- return(SD_CARD_ECC_FAILED);\r
- }\r
- \r
- if((response_R1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR)\r
- {\r
- return(SD_CC_ERROR);\r
- }\r
- \r
- if((response_R1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR)\r
- {\r
- return(SD_GENERAL_UNKNOWN_ERROR);\r
- }\r
- \r
- if((response_R1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN)\r
- {\r
- return(SD_STREAM_READ_UNDERRUN);\r
- }\r
- \r
- if((response_R1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN)\r
- {\r
- return(SD_STREAM_WRITE_OVERRUN);\r
- }\r
- \r
- if((response_R1 & SD_OCR_CID_CSD_OVERWRIETE) == SD_OCR_CID_CSD_OVERWRIETE)\r
- {\r
- return(SD_CID_CSD_OVERWRITE);\r
- }\r
- \r
- if((response_R1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP)\r
- {\r
- return(SD_WP_ERASE_SKIP);\r
- }\r
- \r
- if((response_R1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED)\r
- {\r
- return(SD_CARD_ECC_DISABLED);\r
- }\r
- \r
- if((response_R1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET)\r
- {\r
- return(SD_ERASE_RESET);\r
- }\r
- \r
- if((response_R1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR)\r
- {\r
- return(SD_AKE_SEQ_ERROR);\r
- }\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Checks for error conditions for R3 (OCR) response.\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_CmdResp3Error(SD_HandleTypeDef *hsd)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- \r
- while (!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))\r
- {\r
- }\r
- \r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT))\r
- {\r
- errorState = SD_CMD_RSP_TIMEOUT;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);\r
- \r
- return errorState;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Checks for error conditions for R2 (CID or CSD) response.\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_CmdResp2Error(SD_HandleTypeDef *hsd)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- \r
- while (!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))\r
- {\r
- }\r
- \r
- if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT))\r
- {\r
- errorState = SD_CMD_RSP_TIMEOUT;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);\r
- \r
- return errorState;\r
- }\r
- else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL))\r
- {\r
- errorState = SD_CMD_CRC_FAIL;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL);\r
- \r
- return errorState;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Checks for error conditions for R6 (RCA) response.\r
- * @param hsd: SD handle\r
- * @param SD_CMD: The sent command index\r
- * @param pRCA: Pointer to the variable that will contain the SD card relative \r
- * address RCA \r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_CmdResp6Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD, uint16_t *pRCA)\r
-{\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t response_R1;\r
- \r
- while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))\r
- {\r
- }\r
- \r
- if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT))\r
- {\r
- errorState = SD_CMD_RSP_TIMEOUT;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);\r
- \r
- return errorState;\r
- }\r
- else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL))\r
- {\r
- errorState = SD_CMD_CRC_FAIL;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL);\r
- \r
- return errorState;\r
- }\r
- \r
- /* Check response received is of desired command */\r
- if(SDIO_GetCommandResponse(hsd->Instance) != SD_CMD)\r
- {\r
- errorState = SD_ILLEGAL_CMD;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- /* We have received response, retrieve it. */\r
- response_R1 = SDIO_GetResponse(SDIO_RESP1);\r
- \r
- if((response_R1 & (SD_R6_GENERAL_UNKNOWN_ERROR | SD_R6_ILLEGAL_CMD | SD_R6_COM_CRC_FAILED)) == SD_ALLZERO)\r
- {\r
- *pRCA = (uint16_t) (response_R1 >> 16);\r
- \r
- return errorState;\r
- }\r
- \r
- if((response_R1 & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR)\r
- {\r
- return(SD_GENERAL_UNKNOWN_ERROR);\r
- }\r
- \r
- if((response_R1 & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD)\r
- {\r
- return(SD_ILLEGAL_CMD);\r
- }\r
- \r
- if((response_R1 & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED)\r
- {\r
- return(SD_COM_CRC_FAILED);\r
- }\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Enables the SDIO wide bus mode.\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_WideBus_Enable(SD_HandleTypeDef *hsd)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- \r
- uint32_t scr[2] = {0, 0};\r
- \r
- if((SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)\r
- {\r
- errorState = SD_LOCK_UNLOCK_FAILED;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Get SCR Register */\r
- errorState = SD_FindSCR(hsd, scr);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* If requested card supports wide bus operation */\r
- if((scr[1] & SD_WIDE_BUS_SUPPORT) != SD_ALLZERO)\r
- {\r
- /* Send CMD55 APP_CMD with argument as card's RCA.*/\r
- SDIO_CmdInitStructure.Argument = (uint32_t)(hsd->RCA << 16);\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_APP_CMD;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */\r
- SDIO_CmdInitStructure.Argument = 2;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_APP_SD_SET_BUSWIDTH);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- return errorState;\r
- }\r
- else\r
- {\r
- errorState = SD_REQUEST_NOT_APPLICABLE;\r
- \r
- return errorState;\r
- }\r
-} \r
-\r
-/**\r
- * @brief Disables the SDIO wide bus mode.\r
- * @param hsd: SD handle\r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_WideBus_Disable(SD_HandleTypeDef *hsd)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- \r
- uint32_t scr[2] = {0, 0};\r
- \r
- if((SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)\r
- {\r
- errorState = SD_LOCK_UNLOCK_FAILED;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Get SCR Register */\r
- errorState = SD_FindSCR(hsd, scr);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* If requested card supports 1 bit mode operation */\r
- if((scr[1] & SD_SINGLE_BUS_SUPPORT) != SD_ALLZERO)\r
- {\r
- /* Send CMD55 APP_CMD with argument as card's RCA */\r
- SDIO_CmdInitStructure.Argument = (uint32_t)(hsd->RCA << 16);\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_APP_CMD;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */\r
- SDIO_CmdInitStructure.Argument = 0;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_APP_SD_SET_BUSWIDTH);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- return errorState;\r
- }\r
- else\r
- {\r
- errorState = SD_REQUEST_NOT_APPLICABLE;\r
- \r
- return errorState;\r
- }\r
-}\r
- \r
- \r
-/**\r
- * @brief Finds the SD card SCR register value.\r
- * @param hsd: SD handle\r
- * @param pSCR: pointer to the buffer that will contain the SCR value \r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- SDIO_DataInitTypeDef SDIO_DataInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- uint32_t index = 0;\r
- uint32_t tempscr[2] = {0, 0};\r
- \r
- /* Set Block Size To 8 Bytes */\r
- /* Send CMD55 APP_CMD with argument as card's RCA */\r
- SDIO_CmdInitStructure.Argument = (uint32_t)8;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SET_BLOCKLEN;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- /* Send CMD55 APP_CMD with argument as card's RCA */\r
- SDIO_CmdInitStructure.Argument = (uint32_t)((hsd->RCA) << 16);\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_APP_CMD;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- SDIO_DataInitStructure.DataTimeOut = SD_DATATIMEOUT;\r
- SDIO_DataInitStructure.DataLength = 8;\r
- SDIO_DataInitStructure.DataBlockSize = SDIO_DATABLOCK_SIZE_8B;\r
- SDIO_DataInitStructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;\r
- SDIO_DataInitStructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;\r
- SDIO_DataInitStructure.DPSM = SDIO_DPSM_ENABLE;\r
- SDIO_DataConfig(hsd->Instance, &SDIO_DataInitStructure);\r
- \r
- /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */\r
- SDIO_CmdInitStructure.Argument = 0;\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SD_APP_SEND_SCR;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- /* Check for error conditions */\r
- errorState = SD_CmdResp1Error(hsd, SD_CMD_SD_APP_SEND_SCR);\r
- \r
- if(errorState != SD_OK)\r
- {\r
- return errorState;\r
- }\r
- \r
- while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))\r
- {\r
- if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL))\r
- {\r
- *(tempscr + index) = SDIO_ReadFIFO(hsd->Instance);\r
- index++;\r
- }\r
- }\r
- \r
- if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);\r
- \r
- errorState = SD_DATA_TIMEOUT;\r
- \r
- return errorState;\r
- }\r
- else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);\r
- \r
- errorState = SD_DATA_CRC_FAIL;\r
- \r
- return errorState;\r
- }\r
- else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);\r
- \r
- errorState = SD_RX_OVERRUN;\r
- \r
- return errorState;\r
- }\r
- else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))\r
- {\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);\r
- \r
- errorState = SD_START_BIT_ERR;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- *(pSCR + 1) = ((tempscr[0] & SD_0TO7BITS) << 24) | ((tempscr[0] & SD_8TO15BITS) << 8) |\\r
- ((tempscr[0] & SD_16TO23BITS) >> 8) | ((tempscr[0] & SD_24TO31BITS) >> 24);\r
- \r
- *(pSCR) = ((tempscr[1] & SD_0TO7BITS) << 24) | ((tempscr[1] & SD_8TO15BITS) << 8) |\\r
- ((tempscr[1] & SD_16TO23BITS) >> 8) | ((tempscr[1] & SD_24TO31BITS) >> 24);\r
- \r
- return errorState;\r
-}\r
-\r
-/**\r
- * @brief Checks if the SD card is in programming state.\r
- * @param hsd: SD handle\r
- * @param pStatus: pointer to the variable that will contain the SD card state \r
- * @retval SD Card error state\r
- */\r
-static HAL_SD_ErrorTypedef SD_IsCardProgramming(SD_HandleTypeDef *hsd, uint8_t *pStatus)\r
-{\r
- SDIO_CmdInitTypeDef SDIO_CmdInitStructure;\r
- HAL_SD_ErrorTypedef errorState = SD_OK;\r
- __IO uint32_t responseR1 = 0;\r
- \r
- SDIO_CmdInitStructure.Argument = (uint32_t)(hsd->RCA << 16);\r
- SDIO_CmdInitStructure.CmdIndex = SD_CMD_SEND_STATUS;\r
- SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;\r
- SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;\r
- SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;\r
- SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);\r
- \r
- while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))\r
- {\r
- }\r
- \r
- if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT))\r
- {\r
- errorState = SD_CMD_RSP_TIMEOUT;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);\r
- \r
- return errorState;\r
- }\r
- else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL))\r
- {\r
- errorState = SD_CMD_CRC_FAIL;\r
- \r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL);\r
- \r
- return errorState;\r
- }\r
- \r
- /* Check response received is of desired command */\r
- if((uint32_t)SDIO_GetCommandResponse(hsd->Instance) != SD_CMD_SEND_STATUS)\r
- {\r
- errorState = SD_ILLEGAL_CMD;\r
- \r
- return errorState;\r
- }\r
- \r
- /* Clear all the static flags */\r
- __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);\r
- \r
- \r
- /* We have received response, retrieve it for analysis */\r
- responseR1 = SDIO_GetResponse(SDIO_RESP1);\r
- \r
- /* Find out card status */\r
- *pStatus = (uint8_t)((responseR1 >> 9) & 0x0000000F);\r
- \r
- if((responseR1 & SD_OCR_ERRORBITS) == SD_ALLZERO)\r
- {\r
- return errorState;\r
- }\r
- \r
- if((responseR1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE)\r
- {\r
- return(SD_ADDR_OUT_OF_RANGE);\r
- }\r
- \r
- if((responseR1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED)\r
- {\r
- return(SD_ADDR_MISALIGNED);\r
- }\r
- \r
- if((responseR1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR)\r
- {\r
- return(SD_BLOCK_LEN_ERR);\r
- }\r
- \r
- if((responseR1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR)\r
- {\r
- return(SD_ERASE_SEQ_ERR);\r
- }\r
- \r
- if((responseR1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM)\r
- {\r
- return(SD_BAD_ERASE_PARAM);\r
- }\r
- \r
- if((responseR1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION)\r
- {\r
- return(SD_WRITE_PROT_VIOLATION);\r
- }\r
- \r
- if((responseR1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED)\r
- {\r
- return(SD_LOCK_UNLOCK_FAILED);\r
- }\r
- \r
- if((responseR1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED)\r
- {\r
- return(SD_COM_CRC_FAILED);\r
- }\r
- \r
- if((responseR1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD)\r
- {\r
- return(SD_ILLEGAL_CMD);\r
- }\r
- \r
- if((responseR1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED)\r
- {\r
- return(SD_CARD_ECC_FAILED);\r
- }\r
- \r
- if((responseR1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR)\r
- {\r
- return(SD_CC_ERROR);\r
- }\r
- \r
- if((responseR1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR)\r
- {\r
- return(SD_GENERAL_UNKNOWN_ERROR);\r
- }\r
- \r
- if((responseR1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN)\r
- {\r
- return(SD_STREAM_READ_UNDERRUN);\r
- }\r
- \r
- if((responseR1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN)\r
- {\r
- return(SD_STREAM_WRITE_OVERRUN);\r
- }\r
- \r
- if((responseR1 & SD_OCR_CID_CSD_OVERWRIETE) == SD_OCR_CID_CSD_OVERWRIETE)\r
- {\r
- return(SD_CID_CSD_OVERWRITE);\r
- }\r
- \r
- if((responseR1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP)\r
- {\r
- return(SD_WP_ERASE_SKIP);\r
- }\r
- \r
- if((responseR1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED)\r
- {\r
- return(SD_CARD_ECC_DISABLED);\r
- }\r
- \r
- if((responseR1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET)\r
- {\r
- return(SD_ERASE_RESET);\r
- }\r
- \r
- if((responseR1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR)\r
- {\r
- return(SD_AKE_SEQ_ERROR);\r
- }\r
- \r
- return errorState;\r
-} \r
-\r
-/**\r
- * @}\r
- */\r
-\r
-#endif /* HAL_SD_MODULE_ENABLED */\r
-/**\r
- * @}\r
- */\r
-\r
-/**\r
- * @}\r
- */\r
-\r
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r