Iftikhar Aziz / mbed-dev

Dependents:   LSS_Rev_1

Fork of mbed-dev by Umar Naeem

Revision:
161:2cc1468da177
Parent:
157:ff67d9f36b67
--- a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_ll_sdmmc.c	Tue Mar 14 16:40:56 2017 +0000
+++ b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_ll_sdmmc.c	Thu Mar 30 13:45:57 2017 +0100
@@ -2,8 +2,8 @@
   ******************************************************************************
   * @file    stm32f7xx_ll_sdmmc.c
   * @author  MCD Application Team
-  * @version V1.1.2
-  * @date    23-September-2016 
+  * @version V1.2.0
+  * @date    30-December-2016
   * @brief   SDMMC Low Layer HAL module driver.
   *    
   *          This file provides firmware functions to manage the following 
@@ -92,7 +92,7 @@
   
       (+) To control the DPSM (Data Path State Machine) and send/receive 
            data to/from the card use the SDMMC_DataConfig(), SDMMC_GetDataCounter(), 
-          SDMMC_ReadFIFO(), DIO_WriteFIFO() and SDMMC_GetFIFOCount() functions.
+          SDMMC_ReadFIFO(), SDMMC_WriteFIFO() and SDMMC_GetFIFOCount() functions.
   
     *** Read Operations ***
     =======================
@@ -133,6 +133,15 @@
      (#) Send the selected Write command.
                     
      (#) Use the SDMMC flags/interrupts to check the transfer status.
+       
+    *** Command management operations ***
+    =====================================
+    [..]
+     (#) The commands used for Read/Write//Erase operations are managed in 
+         separate functions. 
+         Each function allows to send the needed command with the related argument,
+         then check the response.
+         By the same approach, you could implement a command and check the response.
   
   @endverbatim
   ******************************************************************************
@@ -184,6 +193,13 @@
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 /* Private function prototypes -----------------------------------------------*/
+static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx);
+static uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout);
+static uint32_t SDMMC_GetCmdResp2(SDMMC_TypeDef *SDMMCx);
+static uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx);
+static uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx);
+static uint32_t SDMMC_GetCmdResp6(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint16_t *pRCA);
+
 /* Exported functions --------------------------------------------------------*/
 
 /** @defgroup SDMMC_LL_Exported_Functions SDMMC Low Layer Exported Functions
@@ -312,6 +328,10 @@
   /* Set power state to ON */ 
   SDMMCx->POWER = SDMMC_POWER_PWRCTRL;
   
+  /* 1ms: required power up waiting time before starting the SD initialization 
+  sequence */
+  HAL_Delay(1);
+  
   return HAL_OK; 
 }
 
@@ -418,7 +438,7 @@
   *         that contains the configuration information for the SDMMC data.
   * @retval HAL status
   */
-HAL_StatusTypeDef SDMMC_DataConfig(SDMMC_TypeDef *SDMMCx, SDMMC_DataInitTypeDef* Data)
+HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, SDMMC_DataInitTypeDef* Data)
 {
   uint32_t tmpreg = 0;
   
@@ -468,7 +488,6 @@
   return (SDMMCx->FIFO);
 }
 
-
 /**
   * @brief  Sets one of the two options of inserting read wait interval.
   * @param  SDMMCx: Pointer to SDMMC register base   
@@ -493,11 +512,987 @@
   * @}
   */
 
+
+/** @defgroup HAL_SDMMC_LL_Group4 Command management functions 
+ *  @brief   Data transfers functions 
+ *
+@verbatim   
+ ===============================================================================
+                   ##### Commands management functions #####
+ ===============================================================================  
+    [..]
+    This subsection provides a set of functions allowing to manage the needed commands.
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Send the Data Block Lenght command and check the response
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdBlockLength(SDMMC_TypeDef *SDMMCx, uint32_t BlockSize)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Set Block Size for Card */ 
+  sdmmc_cmdinit.Argument         = (uint32_t)BlockSize;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SET_BLOCKLEN;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_BLOCKLEN, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Read Single Block command and check the response
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdReadSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Set Block Size for Card */ 
+  sdmmc_cmdinit.Argument         = (uint32_t)ReadAdd;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_READ_SINGLE_BLOCK;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_SINGLE_BLOCK, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Read Multi Block command and check the response
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdReadMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Set Block Size for Card */ 
+  sdmmc_cmdinit.Argument         = (uint32_t)ReadAdd;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_READ_MULT_BLOCK;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_MULT_BLOCK, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Write Single Block command and check the response
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdWriteSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Set Block Size for Card */ 
+  sdmmc_cmdinit.Argument         = (uint32_t)WriteAdd;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_WRITE_SINGLE_BLOCK;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Write Multi Block command and check the response
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdWriteMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Set Block Size for Card */ 
+  sdmmc_cmdinit.Argument         = (uint32_t)WriteAdd;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_WRITE_MULT_BLOCK;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_MULT_BLOCK, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Start Address Erase command for SD and check the response
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdSDEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Set Block Size for Card */ 
+  sdmmc_cmdinit.Argument         = (uint32_t)StartAdd;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_ERASE_GRP_START;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_START, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the End Address Erase command for SD and check the response
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdSDEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Set Block Size for Card */ 
+  sdmmc_cmdinit.Argument         = (uint32_t)EndAdd;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_ERASE_GRP_END;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_END, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Start Address Erase command and check the response
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Set Block Size for Card */ 
+  sdmmc_cmdinit.Argument         = (uint32_t)StartAdd;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ERASE_GRP_START;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_START, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the End Address Erase command and check the response
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Set Block Size for Card */ 
+  sdmmc_cmdinit.Argument         = (uint32_t)EndAdd;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ERASE_GRP_END;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_END, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Erase command and check the response
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdErase(SDMMC_TypeDef *SDMMCx)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Set Block Size for Card */ 
+  sdmmc_cmdinit.Argument         = 0;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ERASE;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE, SDMMC_MAXERASETIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Stop Transfer command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdStopTransfer(SDMMC_TypeDef *SDMMCx)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Send CMD12 STOP_TRANSMISSION  */
+  sdmmc_cmdinit.Argument         = 0;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_STOP_TRANSMISSION;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_STOP_TRANSMISSION, 100000000/*SDMMC_CMDTIMEOUT*/);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Select Deselect command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @param  addr: Address of the card to be selected  
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdSelDesel(SDMMC_TypeDef *SDMMCx, uint64_t Addr)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Send CMD7 SDMMC_SEL_DESEL_CARD */
+  sdmmc_cmdinit.Argument         = (uint32_t)Addr;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEL_DESEL_CARD;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEL_DESEL_CARD, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Go Idle State command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdGoIdleState(SDMMC_TypeDef *SDMMCx)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  sdmmc_cmdinit.Argument         = 0;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_GO_IDLE_STATE;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_NO;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdError(SDMMCx);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Operating Condition command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdOperCond(SDMMC_TypeDef *SDMMCx)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Send CMD8 to verify SD card interface operating condition */
+  /* Argument: - [31:12]: Reserved (shall be set to '0')
+  - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
+  - [7:0]: Check Pattern (recommended 0xAA) */
+  /* CMD Response: R7 */
+  sdmmc_cmdinit.Argument         = SDMMC_CHECK_PATTERN;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_HS_SEND_EXT_CSD;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp7(SDMMCx);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Application command to verify that that the next command 
+  *         is an application specific com-mand rather than a standard command
+  *         and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdAppCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  sdmmc_cmdinit.Argument         = (uint32_t)Argument;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_APP_CMD;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  /* If there is a HAL_ERROR, it is a MMC card, else
+  it is a SD card: SD card 2.0 (voltage range mismatch)
+     or SD card 1.x */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_CMD, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the command asking the accessed card to send its operating 
+  *         condition register (OCR)
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdAppOperCommand(SDMMC_TypeDef *SDMMCx, uint32_t SdType)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  sdmmc_cmdinit.Argument         = SDMMC_VOLTAGE_WINDOW_SD | SdType;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_APP_OP_COND;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp3(SDMMCx);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Bus Width command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdBusWidth(SDMMC_TypeDef *SDMMCx, uint32_t BusWidth)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  sdmmc_cmdinit.Argument         = (uint32_t)BusWidth;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_APP_SD_SET_BUSWIDTH;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Send SCR command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdSendSCR(SDMMC_TypeDef *SDMMCx)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Send CMD51 SD_APP_SEND_SCR */
+  sdmmc_cmdinit.Argument         = 0;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_APP_SEND_SCR;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_SEND_SCR, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Send CID command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdSendCID(SDMMC_TypeDef *SDMMCx)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Send CMD2 ALL_SEND_CID */
+  sdmmc_cmdinit.Argument         = 0;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_ALL_SEND_CID;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_LONG;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp2(SDMMCx);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Send CSD command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdSendCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Send CMD9 SEND_CSD */
+  sdmmc_cmdinit.Argument         = (uint32_t)Argument;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEND_CSD;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_LONG;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp2(SDMMCx);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Send CSD command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdSetRelAdd(SDMMC_TypeDef *SDMMCx, uint16_t *pRCA)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  /* Send CMD3 SD_CMD_SET_REL_ADDR */
+  sdmmc_cmdinit.Argument         = 0;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SET_REL_ADDR;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp6(SDMMCx, SDMMC_CMD_SET_REL_ADDR, pRCA);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Status command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdSendStatus(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  sdmmc_cmdinit.Argument         = (uint32_t)Argument;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEND_STATUS;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEND_STATUS, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Send the Status register command and check the response.
+  * @param  SDMMCx: Pointer to SDMMC register base 
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdStatusRegister(SDMMC_TypeDef *SDMMCx)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  sdmmc_cmdinit.Argument         = 0;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SD_APP_STATUS;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_STATUS, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Sends host capacity support information and activates the card's 
+  *         initialization process. Send SDMMC_CMD_SEND_OP_COND command
+  * @param  SDIOx: Pointer to SDIO register base 
+  * @parame Argument: Argument used for the command
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdOpCondition(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  sdmmc_cmdinit.Argument         = Argument;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_SEND_OP_COND;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp3(SDMMCx);
+
+  return errorstate;
+}
+
+/**
+  * @brief  Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH comand
+  * @param  SDIOx: Pointer to SDIO register base 
+  * @parame Argument: Argument used for the command
+  * @retval HAL status
+  */
+uint32_t SDMMC_CmdSwitch(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
+{
+  SDMMC_CmdInitTypeDef  sdmmc_cmdinit;
+  uint32_t errorstate = SDMMC_ERROR_NONE;
+  
+  sdmmc_cmdinit.Argument         = Argument;
+  sdmmc_cmdinit.CmdIndex         = SDMMC_CMD_HS_SWITCH;
+  sdmmc_cmdinit.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinit.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+  
+  /* Check for error conditions */
+  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_HS_SWITCH, SDMMC_CMDTIMEOUT);
+
+  return errorstate;
+}
+
 /**
   * @}
   */
 
-#endif /* (HAL_SD_MODULE_ENABLED) || (HAL_MMC_MODULE_ENABLED) */
+/* Private function ----------------------------------------------------------*/  
+/** @addtogroup SD_Private_Functions
+  * @{
+  */
+    
+/**
+  * @brief  Checks for error conditions for CMD0.
+  * @param  hsd: SD handle
+  * @retval SD Card error state
+  */
+static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx)
+{
+  /* 8 is the number of required instructions cycles for the below loop statement.
+  The SDMMC_CMDTIMEOUT is expressed in ms */
+  register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8 /1000);
+  
+  do
+  {
+    if (count-- == 0)
+    {
+      return SDMMC_ERROR_TIMEOUT;
+    }
+    
+  }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDSENT));
+  
+  /* Clear all the static flags */
+  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_FLAGS);
+  
+  return SDMMC_ERROR_NONE;
+}
+
+/**
+  * @brief  Checks for error conditions for R1 response.
+  * @param  hsd: SD handle
+  * @param  SD_CMD: The sent command index  
+  * @retval SD Card error state
+  */
+static uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout)
+{
+  uint32_t response_r1;
+  
+  /* 8 is the number of required instructions cycles for the below loop statement.
+  The Timeout is expressed in ms */
+  register uint32_t count = Timeout * (SystemCoreClock / 8 /1000);
+  
+  do
+  {
+    if (count-- == 0)
+    {
+      return SDMMC_ERROR_TIMEOUT;
+    }
+    
+  }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
+  
+  if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
+  {
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
+    
+    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+  }
+  else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
+  {
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
+    
+    return SDMMC_ERROR_CMD_CRC_FAIL;
+  }
+  
+  /* Check response received is of desired command */
+  if(SDMMC_GetCommandResponse(SDMMCx) != SD_CMD)
+  {
+    return SDMMC_ERROR_CMD_CRC_FAIL;
+  }
+  
+  /* Clear all the static flags */
+  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_FLAGS);
+  
+  /* We have received response, retrieve it for analysis  */
+  response_r1 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
+  
+  if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO)
+  {
+    return SDMMC_ERROR_NONE;
+  }
+  else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE)
+  {
+    return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
+  }
+  else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED)
+  {
+    return SDMMC_ERROR_ADDR_MISALIGNED;
+  }
+  else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR)
+  {
+    return SDMMC_ERROR_BLOCK_LEN_ERR;
+  }
+  else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR)
+  {
+    return SDMMC_ERROR_ERASE_SEQ_ERR;
+  }
+  else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM)
+  {
+    return SDMMC_ERROR_BAD_ERASE_PARAM;
+  }
+  else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION)
+  {
+    return SDMMC_ERROR_WRITE_PROT_VIOLATION;
+  }
+  else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED)
+  {
+    return SDMMC_ERROR_LOCK_UNLOCK_FAILED;
+  }
+  else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED)
+  {
+    return SDMMC_ERROR_COM_CRC_FAILED;
+  }
+  else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD)
+  {
+    return SDMMC_ERROR_ILLEGAL_CMD;
+  }
+  else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED)
+  {
+    return SDMMC_ERROR_CARD_ECC_FAILED;
+  }
+  else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR)
+  {
+    return SDMMC_ERROR_CC_ERR;
+  }
+  else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN)
+  {
+    return SDMMC_ERROR_STREAM_READ_UNDERRUN;
+  }
+  else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN)
+  {
+    return SDMMC_ERROR_STREAM_WRITE_OVERRUN;
+  }
+  else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE)
+  {
+    return SDMMC_ERROR_CID_CSD_OVERWRITE;
+  }
+  else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP)
+  {
+    return SDMMC_ERROR_WP_ERASE_SKIP;
+  }
+  else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED)
+  {
+    return SDMMC_ERROR_CARD_ECC_DISABLED;
+  }
+  else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET)
+  {
+    return SDMMC_ERROR_ERASE_RESET;
+  }
+  else if((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR)
+  {
+    return SDMMC_ERROR_AKE_SEQ_ERR;
+  }
+  else
+  {
+    return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
+  }
+}
+
+/**
+  * @brief  Checks for error conditions for R2 (CID or CSD) response.
+  * @param  hsd: SD handle
+  * @retval SD Card error state
+  */
+static uint32_t SDMMC_GetCmdResp2(SDMMC_TypeDef *SDMMCx)
+{
+  /* 8 is the number of required instructions cycles for the below loop statement.
+  The SDMMC_CMDTIMEOUT is expressed in ms */
+  register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8 /1000);
+  
+  do
+  {
+    if (count-- == 0)
+    {
+      return SDMMC_ERROR_TIMEOUT;
+    }
+    
+  }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
+    
+  if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
+  {
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
+    
+    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+  }
+  else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
+  {
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
+    
+    return SDMMC_ERROR_CMD_CRC_FAIL;
+  }
+  else
+  {
+    /* No error flag set */
+    /* Clear all the static flags */
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_FLAGS);
+  }
+
+  return SDMMC_ERROR_NONE;
+}
+
+/**
+  * @brief  Checks for error conditions for R3 (OCR) response.
+  * @param  hsd: SD handle
+  * @retval SD Card error state
+  */
+static uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx)
+{
+  /* 8 is the number of required instructions cycles for the below loop statement.
+  The SDMMC_CMDTIMEOUT is expressed in ms */
+  register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8 /1000);
+  
+  do
+  {
+    if (count-- == 0)
+    {
+      return SDMMC_ERROR_TIMEOUT;
+    }
+    
+  }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
+  
+  if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
+  {
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
+    
+    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+  }
+  else
+ 
+  {  
+    /* Clear all the static flags */
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_FLAGS);
+  }
+  
+  return SDMMC_ERROR_NONE;
+}
+
+/**
+  * @brief  Checks for error conditions for R6 (RCA) response.
+  * @param  hsd: SD handle
+  * @param  SD_CMD: The sent command index
+  * @param  pRCA: Pointer to the variable that will contain the SD card relative 
+  *         address RCA   
+  * @retval SD Card error state
+  */
+static uint32_t SDMMC_GetCmdResp6(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint16_t *pRCA)
+{
+  uint32_t response_r1;
+
+  /* 8 is the number of required instructions cycles for the below loop statement.
+  The SDMMC_CMDTIMEOUT is expressed in ms */
+  register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8 /1000);
+  
+  do
+  {
+    if (count-- == 0)
+    {
+      return SDMMC_ERROR_TIMEOUT;
+    }
+    
+  }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
+  
+  if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
+  {
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
+    
+    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+  }
+  else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
+  {
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
+    
+    return SDMMC_ERROR_CMD_CRC_FAIL;
+  }
+  
+  /* Check response received is of desired command */
+  if(SDMMC_GetCommandResponse(SDMMCx) != SD_CMD)
+  {
+    return SDMMC_ERROR_CMD_CRC_FAIL;
+  }
+  
+  /* Clear all the static flags */
+  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_FLAGS);
+  
+  /* We have received response, retrieve it.  */
+  response_r1 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
+  
+  if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO)
+  {
+    *pRCA = (uint16_t) (response_r1 >> 16);
+    
+    return SDMMC_ERROR_NONE;
+  }
+  else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD)
+  {
+    return SDMMC_ERROR_ILLEGAL_CMD;
+  }
+  else if((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED)
+  {
+    return SDMMC_ERROR_COM_CRC_FAILED;
+  }
+  else
+  {
+    return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
+  }
+}
+
+/**
+  * @brief  Checks for error conditions for R7 response.
+  * @param  hsd: SD handle
+  * @retval SD Card error state
+  */
+static uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx)
+{
+  /* 8 is the number of required instructions cycles for the below loop statement.
+  The SDMMC_CMDTIMEOUT is expressed in ms */
+  register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8 /1000);
+  
+  do
+  {
+    if (count-- == 0)
+    {
+      return SDMMC_ERROR_TIMEOUT;
+    }
+    
+  }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
+
+  if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
+  {
+    /* Card is SD V2.0 compliant */
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND);
+    
+    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+  }
+  
+  if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDREND))
+  {
+    /* Card is SD V2.0 compliant */
+    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND);
+  }
+  
+  return SDMMC_ERROR_NONE;
+  
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#endif /* (HAL_SD_MODULE_ENABLED) */
 /**
   * @}
   */