📄 sddevice.cpp
字号:
}
if ( 0 != ( m_sdSlot.Capabilities & SD_SLOT_USE_SOFT_BLOCK_CMD25 )) {
// The host controller needs to use Soft-Block for CMD25 write operations.
m_SDCardInfo.SDIOInformation.Flags = SFTBLK_USE_FOR_CMD25;
DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: The host controller needs to use Soft-Block for CMD25 write operations. \n")));
}
if ( 0 != ( m_sdSlot.Capabilities & SD_SLOT_USE_SOFT_BLOCK_CMD53_READ )) {
// The host controller needs to use Soft-Block for CMD53 multi-block read operations.
m_SDCardInfo.SDIOInformation.Flags = SFTBLK_USE_FOR_CMD53_READ;
DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: The host controller needs to use Soft-Block for CMD53 multi-block read operations. \n")));
}
if ( 0 != (m_sdSlot.Capabilities & SD_SLOT_USE_SOFT_BLOCK_CMD53_WRITE )) {
// The host controller needs to use Soft-Block for CMD53 multi-block write operations.
m_SDCardInfo.SDIOInformation.Flags = SFTBLK_USE_FOR_CMD53_WRITE;
DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: The host controller needs to use Soft-Block for CMD53 multi-block write operations. \n")));
}
// set the card interface
if (Device_SD_IO == m_DeviceType) {
CSDDevice * pDevice0 = m_sdSlot.GetFunctionDevice(0);
status = SD_API_STATUS_DEVICE_REMOVED;
if (pDevice0) {
// read the bus control register to keep its current bits
status = pDevice0->SDReadWriteRegistersDirect_I(SD_IO_READ, SD_IO_REG_BUS_CONTROL,FALSE,®Value,1);
if (SD_API_SUCCESS(status)) {
// write the bus control register to set for 4 bit mode
if (pInterfaceToUse->InterfaceModeEx.bit.sd4Bit) {
regValue |= SD_IO_BUS_CONTROL_BUS_WIDTH_4BIT;
status = pDevice0->SDReadWriteRegistersDirect_I( SD_IO_WRITE, SD_IO_REG_BUS_CONTROL,FALSE,®Value,1);
if (SD_API_SUCCESS(status)) {
if (m_sdSlot.Capabilities & SD_SLOT_SDIO_INT_DETECT_4BIT_MULTI_BLOCK) {
// get the card capabilities register
status = pDevice0->SDReadWriteRegistersDirect_I(SD_IO_READ,SD_IO_REG_CARD_CAPABILITY,FALSE,®Value,1);
if (SD_API_SUCCESS(status)) {
// check the bit
if (regValue & SD_IO_CARD_CAP_SUPPORTS_INTS_4_BIT_MB_MODE) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Host and Card supports interrupts in 4bit Multi-block mode\n")));
// set the bit, it's in the same register
regValue |= SD_IO_CARD_CAP_ENABLE_INTS_4_BIT_MB_MODE;
// write out the card capabilities register
status = pDevice0->SDReadWriteRegistersDirect_I( SD_IO_WRITE,SD_IO_REG_CARD_CAPABILITY,FALSE,®Value,1);
DEBUGMSG(SDBUS_ZONE_DEVICE && SD_API_SUCCESS(status),
(TEXT("SDBusDriver: 4 Bit multi-block interrupts capability enabled \n")));
}
}
}
}
}
else {
regValue &= ~SD_IO_BUS_CONTROL_BUS_WIDTH_4BIT;
status = pDevice0->SDReadWriteRegistersDirect_I(SD_IO_WRITE,SD_IO_REG_BUS_CONTROL,FALSE,®Value,1);
DEBUGMSG(SDCARD_ZONE_ERROR && !SD_API_SUCCESS(status), (TEXT("SDBusDriver: Failed to set I/O Card Bus Width \n")));
}
}
pDevice0->DeRef();
}
}
else if (Device_SD_Memory == m_DeviceType || Device_SD_Combo == m_DeviceType ) {
// bus width commands are only allowed if the card is unlocked
if (!m_SDCardInfo.SDMMCInformation.CardIsLocked) {
// send the SET_BUS_WIDTH command to the device if 4 bit mode is used
if (pInterfaceToUse->InterfaceModeEx.bit.sd4Bit) {
// send command
status = SendSDAppCommand(SD_ACMD_SET_BUS_WIDTH, SD_ACMD_ARG_SET_BUS_4BIT, ResponseR1, &response);
DEBUGMSG(SDCARD_ZONE_ERROR && !SD_API_SUCCESS(status), (TEXT("SDBusDriver: Failed to set Memory Card Bus Width in Slot \n")));
} else {
// send command
status = SendSDAppCommand(SD_ACMD_SET_BUS_WIDTH,0x00,ResponseR1,&response);
DEBUGMSG(SDCARD_ZONE_ERROR && !SD_API_SUCCESS(status), (TEXT("SDBusDriver: Failed to set Memory Card Bus Width in Slot \n")));
}
}
}
else if (Device_MMC == m_DeviceType) {
// nothing to do for MMC cards
#ifdef _MMC_SPEC_42_
/*************************************************************************/
/****** Date : 07.05.14 ******/
/****** Developer : HS.JANG ******/
/****** Description : Send Switch CMD to the HSMMC card to enable ******/
/****** HS-TIMING and 8/4 Bit Data Bus ******/
/*************************************************************************/
if ( m_dwMMCSpecVer == Device_HSMMC40 )
{
SD_CARD_STATUS cardStatus; // 08.05.19 by KYS, added for reading card status as a kind of delay
if((m_sdSlot.Capabilities & SD_SLOT_HIGH_SPEED_CAPABLE)!=0) {
status = GetCardStatus(&cardStatus); // 08.05.19 by KYS, added for reading card status as a kind of delay
status = SendSDCommand( SD_ACMD_SET_BUS_WIDTH,
(3<<24) | (185<<16) | (1<<8) , // High-Speed Mode
ResponseR1b,
&response);
if (!SD_API_SUCCESS(status))
{
RETAILMSG(1,(TEXT("[SDBUS-ERR] SetCardInterface:Switch Command is failed %x\n"),status));
return status;
}
// 08.04.04 by KYS
// Because HSMMC Ch0 support only 4 data bus width,
// In order to distinguish the bus width, Read the capabilities of HostController!
if ((m_sdSlot.Capabilities & SD_SLOT_SD_8BIT_CAPABLE)!=0) {
status = GetCardStatus(&cardStatus); // 08.05.19 by KYS, added for reading card status as a kind of delay
status = SendSDCommand( SD_ACMD_SET_BUS_WIDTH,
(3<<24) | (183<<16) | (2<<8) , // DAT 8-bit Bus
ResponseR1b,
&response);
if (!SD_API_SUCCESS(status))
{
RETAILMSG(1,(TEXT("[SDBUS-ERR] SetCardInterface:Switch Command is failed %x\n"),status));
return status;
}
} else {
status = GetCardStatus(&cardStatus); // 08.05.19 by KYS, added for reading card status as a kind of delay
status = SendSDCommand( SD_ACMD_SET_BUS_WIDTH,
(3<<24) | (183<<16) | (1<<8), // DAT 4-bit mode
ResponseR1b,
&response);
if (!SD_API_SUCCESS(status))
{
RETAILMSG(1,(TEXT("[SDBUS-ERR] SetCardInterface:Switch Command is failed %x\n"),status));
return status;
}
}
}
else
{
status = GetCardStatus(&cardStatus); // 08.05.19 by KYS, added for reading card status as a kind of delay
// send command
status = SendSDCommand( SD_ACMD_SET_BUS_WIDTH,
(3<<24) | (183<<16) | (1<<8), // DAT 4-bit mode
ResponseR1b,
&response);
if (!SD_API_SUCCESS(status))
{
RETAILMSG(1,(TEXT("[SDBUS-ERR] SetCardInterface:Switch Command is failed %x\n"),status));
return status;
}
}
}
/*************************************************************************/
#endif
}
else {
//DEBUGCHK(FALSE);
}
if (SD_API_SUCCESS(status) && (m_CardInterfaceEx.InterfaceModeEx.bit.sdHighSpeed != pInterfaceToUse->InterfaceModeEx.bit.sdHighSpeed) &&
pInterfaceToUse->InterfaceModeEx.bit.sdHighSpeed!=0) { // We need switch to Hight speed.
if (Device_SD_Memory == m_DeviceType && (m_sdSlot.Capabilities &SD_SLOT_HIGH_SPEED_CAPABLE)!=0 ) {
// We are going to try to swich swith card to high speed.
SD_CARD_SWITCH_FUNCTION switchData = {
0x00000001, // Group 1 set to function 1 High Speed Table 4.7, SD Spec 2.0
MAXDWORD,
2*1000, // let use try 2 second maximun.
};
status = SwitchFunction(&switchData,FALSE);
if (SD_API_SUCCESS(status)) {
m_CardInterfaceEx.InterfaceModeEx.bit.sdHighSpeed = 1;
}
}
else {
status = SD_API_STATUS_DEVICE_UNSUPPORTED;
}
}
if (SD_API_SUCCESS(status)) {
m_CardInterfaceEx = *pInterfaceToUse;
}
ASSERT(SD_API_SUCCESS(status));
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SelectCardInterface - select card interface based on information from the card,
// the host controller.
//
// Output: pDevice->CardInterface contains ideal interface for this function
// Return: SD_API_STATUS code
// Notes: This function sets the card's default interface in the device structure
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::SelectCardInterface()
{
DWORD bitSlice; // bit slice
SD_API_STATUS status; // intermediate status
status = SD_API_STATUS_SUCCESS;
SD_PARSED_REGISTER_CSD CSDRegister ;
// for MMC and SD cards allocate storage for the parsed CSD
if ( (Device_SD_Memory == m_DeviceType) || (Device_MMC == m_DeviceType)) {
// get the parsed CSD registers
status = SDCardInfoQuery_I(SD_INFO_REGISTER_CSD,&CSDRegister,sizeof(SD_PARSED_REGISTER_CSD));
if (!SD_API_SUCCESS(status)) {
return status;
}
}
// Set default interface for the current device. SelectSlotInterface()
// will be used to select one interface which fits for all devices
if (Device_MMC != m_DeviceType) {
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = ((m_sdSlot.Capabilities & SD_SLOT_SD_4BIT_CAPABLE)!=0 ? 1 : 0);
// deal with special cases
// 1 bit SD memory + 4 bit SDIO
// SD_SLOT_SD_1BIT_CAPABLE | SD_SLOT_SDIO_CAPABLE | SD_SLOT_SDIO_4BIT_CAPABLE
if (Device_SD_IO == m_DeviceType && (m_sdSlot.Capabilities & SD_SLOT_SDIO_4BIT_CAPABLE)!=0) {
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 1 ;
}
// 1 bit SDIO + 4 bit SD Memory
// SD_SLOT_SD_1BIT_CAPABLE | SD_SLOT_SDIO_CAPABLE | SD_SLOT_SDMEM_4BIT_CAPABLE
if ((Device_SD_Memory == m_DeviceType || Device_SD_Combo == m_DeviceType ) && (m_sdSlot.Capabilities & SD_SLOT_SDMEM_4BIT_CAPABLE)!=0) {
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 1;
}
#ifdef _MMC_SPEC_42_
/*************************************************************************/
/****** Date : 07.05.14 ******/
/****** Developer : HS.JANG ******/
/****** Description : If SD Spec 1.x or 2.x card in HSMMC slot, ******/
/****** set the card to enable the high speed ******/
/*************************************************************************/
//if(wcscmp(m_sdSlot.m_SdHost.HostControllerName,TEXT("HSMMC"))==0 && m_fValid20Card)
if( (Device_SD_Memory == m_DeviceType) && (m_sdSlot.Capabilities & SD_SLOT_HIGH_SPEED_CAPABLE)!=0 )
{
UCHAR uSCRRegister[SD_SCR_REGISTER_SIZE]; // SCR
PSD_REGISTER_SCR pSCRRegsiter;
memcpy(uSCRRegister, &(m_CachedRegisters.SCR),SD_SCR_REGISTER_SIZE );
SD_COMMAND_RESPONSE response;
pSCRRegsiter = (PSD_REGISTER_SCR)uSCRRegister;
if ( pSCRRegsiter->SD_SPEC !=0 ) // CMD6 (Switch function) is supported from SD Spec 1.1
{
unsigned int uBuffer[16]= {0,};
status = SendSDCommand(SD_CMD_SET_BLOCKLEN,
64,
ResponseR1,
&response);
if (!SD_API_SUCCESS(status))
{
RETAILMSG(1,(TEXT("[SDBUS-ERR] Setting Block length failed. %x\r\n"),status));
return status;
}
status = SDSynchronousBusRequest_I( SD_ACMD_SET_BUS_WIDTH,
((0x1<<31)|(0xFFFF<<8)|(1<<0)),
SD_READ,
ResponseR1,
&response,
1,
64,
(PUCHAR)uBuffer,
0);
//2007.10.05 D.Baek
if(!SD_API_SUCCESS(status))
{
RETAILMSG(1,(TEXT("[SDBUS-ERR] SelectCardInterface:CMD6 Switch function failed.\r\n")));
}else
{
if(uBuffer[3] & (1<<9))
{
RETAILMSG(1,(TEXT("[SDBUS] SD/SDHC supports the high-speed mode.\r\n")));
#if (BSP_TYPE == BSP_SMDK2443)
m_CardInterfaceEx.ClockRate = HSMMC_FULL_SPEED_RATE;
#elif (BSP_TYPE == BSP_SMDK2450)
m_CardInterfaceEx.ClockRate = SDHC_FULL_SPEED_RATE;
#endif
}else
{
RETAILMSG(1,(TEXT("[SDBUS] SD/SDHC doesn't support the high-speed mode.\r\n")));
m_CardInterfaceEx.ClockRate = SD_FULL_SPEED_RATE;
}
// CMD16 - set the block length to the 512
// If you don't set the block length to 512 in the card register,
// it cause an error when the next command issues.
status = SendSDCommand( SD_CMD_SET_BLOCKLEN,
512,
ResponseR1,
&response);
if (!SD_API_SUCCESS(status))
{
RETAILMSG(1,(TEXT("[SDBUS-ERR] Setting Block Length failed. %x\r\n"),status));
return status;
}
}
}
else
{
RETAILMSG(1,(TEXT("[SDBUS] This SD card is SPEC 1.0\r\n")));
m_CardInterfaceEx.ClockRate = SD_FULL_SPEED_RATE;
}
}
else
/*************************************************************************/
#endif
{
// try all cards at full speed
m_CardInterfaceEx.ClockRate = SD_FULL_SPEED_RATE;
}
} else {
// MMC cards are always 1 bit, set the clock rate to the default MMC rate
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -