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