Esempio n. 1
0
/*************************************************************************
 * Function Name: _SdInitMedia
 * Parameters: none
 *
 * Return: SdState_t
 *
 * Description: SD/MMC detect and initialize
 *
 *************************************************************************/
static
SdState_t _SdInitMedia (void)
{
    Int32U i,res;
    volatile Int32U Dly;
    Int8U MmcSdCid[16];

    _Tnac = 1;
    if(!_SdPresent())
    {
        if(SDIO_PowerState_OFF != SDIO_GetPowerState())
        {
            // Set to power down state
            _SdPowerDown();
        }
        return(SdNoPresent);
    }

    _SdPowerDown();
    SdDly_1ms(100);

    // Set Power State to ON
    SDIO_SetPowerState(SDIO_PowerState_ON);
    SdDly_1ms(100);

    // Enable SDIO Clock
    SDIO_ClockCmd(ENABLE);

    if(_SdSendCmd(CMD0,NULL) != SdOk)
    {
        return(SdNoResponse);
    }

    // Determinate Card type SD or MMC
    _SdDskCtrlBlk.DiskType = DiskSD_Spec2_0;
    res = Cmd8Reg;
    if(SdOk == _SdSendCmd(CMD8,&res))
    {
        _bHC = TRUE;
    }
    else
    {
        _SdDskCtrlBlk.DiskType = DiskSD_Spec1_x;
    }
    for(i=100; i; --i)
    {
        res = 0;
        if((_SdSendCmd(CMD55,&res) == SdOk) &&
                (res & 0x100))
        {
            res = _bHC?OcrReg | OcrReg_HC:OcrReg;
            if((_SdSendCmd(ACMD41,&res) == SdOk) &&
                    (res & 0x80000000))
            {
                // SD card is find
                _bHC = 0 != (res & OcrReg_HC);
                break;
            }
        }
        else
        {
            _SdDskCtrlBlk.DiskType = DiskMMC;
            // CMD1 for MMC Init sequence
            // will be complete within 500ms
            res = OcrReg;
            if(_SdSendCmd(CMD1,&res) ==  SdOk && (res & 0x80000000))
            {
                // MMC card is find
                _bHC = FALSE;
                break;
            }
        }

        SdDly_1ms(10);
    }


    if(i == 0)
    {
        return(SdNoResponse);
    }

    // Read CID
    if(_SdSendCmd(CMD2,(pInt32U)MmcSdCid) != SdOk)
    {
        return(SdNoResponse);
    }

    // Set address
    _CardRCA = (_SdDskCtrlBlk.DiskType == DiskMMC)?0x00010000:0x00000000;
    if(_SdSendCmd(CMD3,&_CardRCA) != SdOk)
    {
        return(SdNoResponse);
    }
    if(DiskMMC != _SdDskCtrlBlk.DiskType)
    {
        _CardRCA &= 0xFFFF0000;
    }
    else
    {
        _CardRCA  = 0x00010000;
    }

    // Read CSD
    _MmcSdCsd[0] = 0;
    _MmcSdCsd[1] = 0;
    _MmcSdCsd[2] = _CardRCA >> 16;
    _MmcSdCsd[3] = _CardRCA >> 24;
    if(_SdSendCmd(CMD9,(pInt32U)_MmcSdCsd) != SdOk)
    {
        return(SdNoResponse);
    }

    // Implement CSD data
    _SdCsdImplemet();

    // Enter in TRAN state
    res = _CardRCA;
    if(_SdSendCmd(CMD7,&res) != SdOk)
    {
        return(SdNoResponse);
    }
    res = _CardRCA;
    if(SdOk != _SdSendCmd(CMD13,&res))
    {
        return(SdNoResponse);
    }
    else if(!(res & READY_FOR_DATA) ||
            ((res & CURRENT_STATE) != CARD_TRAN))
    {
        return(SdCardError);
    }

    // Set Block size
    res = _SdDskCtrlBlk.BlockSize;
    if(_SdSendCmd(CMD16,&res))
    {
        return(SdNoResponse);
    }

    if(DiskMMC != _SdDskCtrlBlk.DiskType)
    {
        // Use wide bus for SD
        res = _CardRCA;
        if((_SdSendCmd(CMD55,&res) != SdOk) ||
                !(res & 0x100))
        {
            return(SdCardError);
        }
        // Set bus width 4bits
        res = 2;
        if(_SdSendCmd(ACMD6,&res) != SdOk)
        {
            return(SdCardError);
        }
        SDIO->CLKCR |= 1UL << 11;
    }
    return(SdOk);
}
Esempio n. 2
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);
  }