/************************************************************************* * 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); }
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); }