static void stm32f4xx_sdio_send_command(struct stm32f4xx_sdio *sdio, struct rt_mmcsd_cmd *cmd)
{
    struct rt_mmcsd_data *data = cmd->data;

    sdio->cmd = cmd;

    if (resp_type(cmd) == RESP_NONE)
        SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_No;
    else
    {
        /* set 136 bit response for R2, 48 bit response otherwise */
        if (resp_type(cmd) == RESP_R2)
            SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long;
        else
            SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    }

    SDIO_CmdInitStructure.SDIO_Argument = cmd->arg;
    SDIO_CmdInitStructure.SDIO_CmdIndex = cmd->cmd_code;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;

    if (cmd->cmd_code == GO_IDLE_STATE)
        SDIO_ITConfig(SDIO_IT_CMDSENT, ENABLE);
    else
        SDIO_ITConfig(SDIO_IT_CCRCFAIL | SDIO_IT_CMDREND | SDIO_IT_CTIMEOUT, ENABLE);
    SDIO_SendCommand(&SDIO_CmdInitStructure);

    if (data)
    {
        SDIO->DCTRL = 0x0;
        SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
        SDIO_DataInitStructure.SDIO_DataLength = data->blksize * data->blks;
        SDIO_DataInitStructure.SDIO_DataBlockSize = get_order(data->blksize) << 4;
        if (data->flags & DATA_DIR_WRITE)
            SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
        else if (data->flags & DATA_DIR_READ)
            SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
        SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
        SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
        SDIO_DataConfig(&SDIO_DataInitStructure);

        if (data->flags & DATA_DIR_WRITE)
        {
            SD_LowLevel_DMA_TxConfig((uint32_t *)data->buf, data->blksize * data->blks);
        }
        else if (data->flags & DATA_DIR_READ)
        {
            SD_LowLevel_DMA_RxConfig((uint32_t *)data->buf, data->blksize * data->blks);
        }
        SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
        SDIO_DMACmd(ENABLE);
    }

}
Exemplo n.º 2
0
/*************************************************************************
 * Function Name: _SdSendCmd
 * Parameters: SdCmdInd_t ComdInd,Int32U Arg
 *
 * Return: SdState_t
 *
 * Description: SD/MMC commands implement
 *
 *************************************************************************/
static
SdState_t _SdSendCmd(SdCmdInd_t ComdInd,pInt32U pArg)
{
    SDIO_CmdInitTypeDef SDIO_CmdInitStructure;
    Int32U Status;
    Int32U timeout;
    // Send Command
    SDIO_CmdInitStructure.SDIO_CmdIndex = _SdCmd[ComdInd].TxData;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_No;
    SDIO_CmdInitStructure.SDIO_Wait     = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM     = SDIO_CPSM_Enable;

    if(pArg != NULL)
    {
        switch(_SdCmd[ComdInd].Resp)
        {
        case SdR2:
            SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long;
            break;
        case SdR1:
        case SdR1b:
        case SdR3:
        case SdR7:
            SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
        }
    }

    // Send command's arguments
    if(_SdCmd[ComdInd].Arg != SdNoArg)
    {
        SDIO_CmdInitStructure.SDIO_Argument = *pArg;
    }
    else
    {
        SDIO_CmdInitStructure.SDIO_Argument = 0;
    }

    // Clear all the static flags
    SDIO_ClearFlag(SDIO_STATIC_FLAGS);

    SDIO_SendCommand(&SDIO_CmdInitStructure);

    // Wait command respond
    if(CMD0 == ComdInd)
    {
        timeout = SDIO_CMD0TIMEOUT;
        do
        {
            if(0 == --timeout)
            {
                // Clear all the static flags
                return(SdNoResponse);
            }
            Status = SDIO->STA;
        }
        while (0 == (Status & SDIO_FLAG_CMDSENT));
    }
    else
    {
        do
        {
            Status = SDIO->STA;
        }
        while(!(Status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)));
    }

    SDIO_ClearFlag(SDIO_FLAG_CMDSENT);

    if (Status & SDIO_FLAG_CTIMEOUT)
    {
        SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);
        return(SdNoResponse);
    }

    if (Status & SDIO_FLAG_CCRCFAIL)
    {
        SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);
        switch(_SdCmd[ComdInd].TxData)
        {
        // Ignore CRC Error
        case  1: // CMD1
        case 41: // ACMD42
        case 12: // CMD12
            break;
        default:
            return(SdCardError);
        }
    }

    if(pArg != NULL)
    {
        switch (_SdCmd[ComdInd].Resp)
        {
        case SdNoResp:
            break;
        case SdR3:
        case SdR7:
            *pArg = SDIO_GetResponse(SDIO_RESP1);
            break;
        case SdR2:
            *pArg++ = SDIO_GetResponse(SDIO_RESP1);
            *pArg++ = SDIO_GetResponse(SDIO_RESP2);
            *pArg++ = SDIO_GetResponse(SDIO_RESP3);
            *pArg++ = SDIO_GetResponse(SDIO_RESP4);
            break;
        default:
            // Check response received is of desired command
            if (SDIO_GetCommandResponse() != _SdCmd[ComdInd].TxData)
            {
                return(SdCardError);
            }
            *pArg = SDIO_GetResponse(SDIO_RESP1);
        }
    }
    SDIO_ClearFlag(SDIO_FLAG_CMDREND);
    return(SdOk);
}
Exemplo n.º 3
0
  bool SdCardSdioFeature::powerOn() {

    SD_Error errorstatus=SD_OK;
    uint32_t response=0,count=0,validvoltage=0;
    uint32_t SDType=SD_STD_CAPACITY;
    SDIO_InitTypeDef sdioInit;
    SDIO_CmdInitTypeDef cmdInit;

    /*!< Power ON Sequence -----------------------------------------------------*/

    sdioInit.SDIO_ClockDiv=_initDivider;
    sdioInit.SDIO_ClockEdge=SDIO_ClockEdge_Rising;
    sdioInit.SDIO_ClockBypass=SDIO_ClockBypass_Disable;
    sdioInit.SDIO_ClockPowerSave=SDIO_ClockPowerSave_Disable;
    sdioInit.SDIO_BusWide=SDIO_BusWide_1b;
    sdioInit.SDIO_HardwareFlowControl=SDIO_HardwareFlowControl_Disable;
    SDIO_Init(&sdioInit);

    /*!< Set Power State to ON */
    SDIO_SetPowerState(SDIO_PowerState_ON);

    /*!< Enable SDIO Clock */
    SDIO_ClockCmd(ENABLE);

    /*!< CMD0: GO_IDLE_STATE ---------------------------------------------------*/
    /*!< No CMD response required */
    cmdInit.SDIO_Argument=0x0;
    cmdInit.SDIO_CmdIndex=SD_CMD_GO_IDLE_STATE;
    cmdInit.SDIO_Response=SDIO_Response_No;
    cmdInit.SDIO_Wait=SDIO_Wait_No;
    cmdInit.SDIO_CPSM=SDIO_CPSM_Enable;
    SDIO_SendCommand(&cmdInit);

    errorstatus=cmdError();

    if(errorstatus != SD_OK)
      return errorProvider.set(ErrorProvider::ERROR_PROVIDER_SD_SDIO,E_SDIO_ERROR,errorstatus);

    /*!< 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 */

    cmdInit.SDIO_Argument=SD_CHECK_PATTERN;
    cmdInit.SDIO_CmdIndex=SDIO_SEND_IF_COND;
    cmdInit.SDIO_Response=SDIO_Response_Short;
    cmdInit.SDIO_Wait=SDIO_Wait_No;
    cmdInit.SDIO_CPSM=SDIO_CPSM_Enable;
    SDIO_SendCommand(&cmdInit);

    errorstatus=cmdResp7Error();

    if(errorstatus == SD_OK) {
      _cardType=SDIO_STD_CAPACITY_SD_CARD_V2_0; /*!< SD Card 2.0 */
      SDType=SD_HIGH_CAPACITY;
    } else {
      /*!< CMD55 */
      cmdInit.SDIO_Argument=0x00;
      cmdInit.SDIO_CmdIndex=SD_CMD_APP_CMD;
      cmdInit.SDIO_Response=SDIO_Response_Short;
      cmdInit.SDIO_Wait=SDIO_Wait_No;
      cmdInit.SDIO_CPSM=SDIO_CPSM_Enable;
      SDIO_SendCommand(&cmdInit);
      errorstatus=cmdResp1Error(SD_CMD_APP_CMD);
    }
    /*!< CMD55 */
    cmdInit.SDIO_Argument=0x00;
    cmdInit.SDIO_CmdIndex=SD_CMD_APP_CMD;
    cmdInit.SDIO_Response=SDIO_Response_Short;
    cmdInit.SDIO_Wait=SDIO_Wait_No;
    cmdInit.SDIO_CPSM=SDIO_CPSM_Enable;
    SDIO_SendCommand(&cmdInit);
    errorstatus=cmdResp1Error(SD_CMD_APP_CMD);

    /*!< If errorstatus is Command TimeOut, it is a MMC card */
    /*!< If errorstatus is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch)
     or SD card 1.x */
    if(errorstatus == 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 */
        cmdInit.SDIO_Argument=0x00;
        cmdInit.SDIO_CmdIndex=SD_CMD_APP_CMD;
        cmdInit.SDIO_Response=SDIO_Response_Short;
        cmdInit.SDIO_Wait=SDIO_Wait_No;
        cmdInit.SDIO_CPSM=SDIO_CPSM_Enable;
        SDIO_SendCommand(&cmdInit);

        errorstatus=cmdResp1Error(SD_CMD_APP_CMD);

        if(errorstatus != SD_OK)
          return errorstatus;

        cmdInit.SDIO_Argument=SD_VOLTAGE_WINDOW_SD | SDType;
        cmdInit.SDIO_CmdIndex=SD_CMD_SD_APP_OP_COND;
        cmdInit.SDIO_Response=SDIO_Response_Short;
        cmdInit.SDIO_Wait=SDIO_Wait_No;
        cmdInit.SDIO_CPSM=SDIO_CPSM_Enable;
        SDIO_SendCommand(&cmdInit);

        errorstatus=cmdResp3Error();
        if(errorstatus != SD_OK)
          return errorstatus;

        response=SDIO_GetResponse(SDIO_RESP1);
        validvoltage=(((response >> 31) == 1) ? 1 : 0);
        count++;
      }
      if(count >= SD_MAX_VOLT_TRIAL) {
        errorstatus=SD_INVALID_VOLTRANGE;
        return errorstatus;
      }

      if(response&=SD_HIGH_CAPACITY)
        _cardType=SDIO_HIGH_CAPACITY_SD_CARD;

    }/*!< else MMC Card */

    if(errorstatus != SD_OK)
      return errorProvider.set(ErrorProvider::ERROR_PROVIDER_SD_SDIO,E_SDIO_ERROR,errorstatus);

    return true;
  }
Exemplo n.º 4
0
  bool SdCardSdioFeature::initialiseCard() {

    SD_Error errorstatus=SD_OK;
    uint16_t rca=0x01;
    SDIO_CmdInitTypeDef cmdInit;
    SDIO_InitTypeDef sdioInit;

    if(SDIO_GetPowerState() == SDIO_PowerState_OFF)
      return errorProvider.set(ErrorProvider::ERROR_PROVIDER_SD_SDIO,E_SDIO_ERROR,SD_REQUEST_NOT_APPLICABLE);

    if(SDIO_SECURE_DIGITAL_IO_CARD != _cardType) {

      /*!< Send CMD2 ALL_SEND_CID */
      cmdInit.SDIO_Argument=0x0;
      cmdInit.SDIO_CmdIndex=SD_CMD_ALL_SEND_CID;
      cmdInit.SDIO_Response=SDIO_Response_Long;
      cmdInit.SDIO_Wait=SDIO_Wait_No;
      cmdInit.SDIO_CPSM=SDIO_CPSM_Enable;
      SDIO_SendCommand(&cmdInit);

      errorstatus=cmdResp2Error();

      if(SD_OK != errorstatus)
        return errorProvider.set(ErrorProvider::ERROR_PROVIDER_SD_SDIO,E_SDIO_ERROR,errorstatus);

      _cidTab[0]=SDIO_GetResponse(SDIO_RESP1);
      _cidTab[1]=SDIO_GetResponse(SDIO_RESP2);
      _cidTab[2]=SDIO_GetResponse(SDIO_RESP3);
      _cidTab[3]=SDIO_GetResponse(SDIO_RESP4);
    }
    if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == _cardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == _cardType) || (SDIO_SECURE_DIGITAL_IO_COMBO_CARD == _cardType) || (SDIO_HIGH_CAPACITY_SD_CARD == _cardType)) {
      /*!< Send CMD3 SET_REL_ADDR with argument 0 */
      /*!< SD Card publishes its RCA. */
      cmdInit.SDIO_Argument=0x00;
      cmdInit.SDIO_CmdIndex=SD_CMD_SET_REL_ADDR;
      cmdInit.SDIO_Response=SDIO_Response_Short;
      cmdInit.SDIO_Wait=SDIO_Wait_No;
      cmdInit.SDIO_CPSM=SDIO_CPSM_Enable;
      SDIO_SendCommand(&cmdInit);

      errorstatus=cmdResp6Error(SD_CMD_SET_REL_ADDR,&rca);

      if(SD_OK != errorstatus)
        return errorProvider.set(ErrorProvider::ERROR_PROVIDER_SD_SDIO,E_SDIO_ERROR,errorstatus);
    }

    if(SDIO_SECURE_DIGITAL_IO_CARD != _cardType) {

      _rca=rca;

      /*!< Send CMD9 SEND_CSD with argument as card's RCA */
      cmdInit.SDIO_Argument=(uint32_t)(rca << 16);
      cmdInit.SDIO_CmdIndex=SD_CMD_SEND_CSD;
      cmdInit.SDIO_Response=SDIO_Response_Long;
      cmdInit.SDIO_Wait=SDIO_Wait_No;
      cmdInit.SDIO_CPSM=SDIO_CPSM_Enable;
      SDIO_SendCommand(&cmdInit);

      errorstatus=cmdResp2Error();

      if(SD_OK != errorstatus)
        return errorProvider.set(ErrorProvider::ERROR_PROVIDER_SD_SDIO,E_SDIO_ERROR,errorstatus);

      _csdTab[0]=SDIO_GetResponse(SDIO_RESP1);
      _csdTab[1]=SDIO_GetResponse(SDIO_RESP2);
      _csdTab[2]=SDIO_GetResponse(SDIO_RESP3);
      _csdTab[3]=SDIO_GetResponse(SDIO_RESP4);
    }

    /*!< Configure the SDIO peripheral */

    sdioInit.SDIO_ClockDiv = _transferDivider;
    sdioInit.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
    sdioInit.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
    sdioInit.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;
    sdioInit.SDIO_BusWide = SDIO_BusWide_1b;
    sdioInit.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
    SDIO_Init(&sdioInit);

    return detectCardInfo() &&
           selectDeselect((uint32_t) (_cardInfo.RCA << 16)) &&
           enableWideBusOperation(SDIO_BusWide_4b);
  }