📄 sddevice.cpp
字号:
if (!SD_API_SUCCESS(status)){
break;
}
if (Device_SD_IO == DeviceType) {
// check to see if the I/O is ready
if (SD_IS_IO_READY(&response)) {
UpdateCachedRegisterFromResponse(SD_INFO_REGISTER_IO_OCR, &response);
// we're done
break;
}
} else {
// check to see if the MMC or Memory card is ready
if (SD_IS_MEM_READY(&response)) {
// card is ready
UpdateCachedRegisterFromResponse(SD_INFO_REGISTER_OCR, &response);
break;
}
}
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Card in slot %d not ready, countdown: %d \n"),m_sdSlot.GetSlotIndex(), powerUpRetries));
powerUpRetries--;
// sleep the powerup interval
Sleep(powerUpInterval);
}
if (0 == powerUpRetries) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Device failed to powerup after voltage setting \n")));
status = SD_API_STATUS_DEVICE_NOT_RESPONDING;
}
if (SD_API_SUCCESS(status)) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Card in slot %d ready \n"),m_sdSlot.GetSlotIndex()));
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SetCardInterface - sets the interface for the card
// Input: pDevice - the device
// pInterface - alternate interface, can be NULL
// Output:
// Return: SD_API_STATUS code
// Notes: This function sets the card's interface by issuing appropriate SD commands
// to the card.
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::SetCardInterface(PSD_CARD_INTERFACE_EX pInterfaceEx)
{
UCHAR regValue; // register value
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status
SD_COMMAND_RESPONSE response; // response
PSD_CARD_INTERFACE_EX pInterfaceToUse; // interface to use
if (NULL != pInterfaceEx) {
pInterfaceToUse = pInterfaceEx;
} else {
// otherwise use the one set in the device
pInterfaceToUse = &m_CardInterfaceEx;
}
// Determine if Soft-Block should be used.
if (( NULL != m_SDCardInfo.SDIOInformation.pCommonInformation )
&& ( 0 == ( m_SDCardInfo.SDIOInformation.pCommonInformation->CardCapability
& SD_IO_CARD_CAP_SUPPORTS_MULTI_BLOCK_TRANS )))
{
// The SDIO card does not support block mode. Use Soft-Block instead.
m_SDCardInfo.SDIOInformation.Flags = SFTBLK_USE_FOR_CMD53_READ | SFTBLK_USE_FOR_CMD53_WRITE;
DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: The SDIO card does not support block mode. Use Soft-Block instead. \n")));
}
// Some host controllers can not properly support multi-block operations.
// Enable Soft-Block for these operations.
if ( 0 != (m_sdSlot.Capabilities & SD_SLOT_USE_SOFT_BLOCK_CMD18 ))
{
if ( 0 != ( m_sdSlot.Capabilities & SD_SLOT_USE_SOFT_BLOCK_CMD18 )) {
// The host controller needs to use Soft-Block for CMD18 read operations.
m_SDCardInfo.SDIOInformation.Flags |= SFTBLK_USE_FOR_CMD18;
DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: The host controller needs to use Soft-Block for CMD18 read operations. \n")));
}
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")));
}
}
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) {
#ifdef _MMC_SPEC_42_
/**
* Description : Send Switch CMD to the HSMMC card to enable HS-TIMING and 8/4 Bit Data Bus
*/
if ( m_dwMMCSpecVer == Device_HSMMC40 ) {
if ((m_sdSlot.Capabilities & SD_SLOT_HIGH_SPEED_CAPABLE)!=0) {
CheckCardStatusForDelay();
status = SendSDCommand( SD_ACMD_SET_BUS_WIDTH, MMC_ACMD_ARG_SET_HIGHSPEED, ResponseR1b, &response); // High-Speed Mode
if (!SD_API_SUCCESS(status)) {
RETAILMSG(TRUE,(TEXT("[SDBUS]Switch Command is failed %x\n"), status));
return status;
}
// 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) {
CheckCardStatusForDelay();
status = SendSDCommand( SD_ACMD_SET_BUS_WIDTH, MMC_ACMD_ARG_SET_BUS_8BIT, ResponseR1, &response); // 8Bit Bus
if (!SD_API_SUCCESS(status)) {
RETAILMSG(TRUE,(TEXT("[SDBUS]Switch Command is failed %x\n"), status));
return status;
}
} else {
CheckCardStatusForDelay();
status = SendSDCommand( SD_ACMD_SET_BUS_WIDTH, MMC_ACMD_ARG_SET_BUS_4BIT, ResponseR1b, &response); // 4Bit Bus
if (!SD_API_SUCCESS(status)) {
return status;
}
}
} else {
CheckCardStatusForDelay();
status = SendSDCommand( SD_ACMD_SET_BUS_WIDTH, MMC_ACMD_ARG_SET_BUS_4BIT, ResponseR1b, &response); // 4Bit Bus
if (!SD_API_SUCCESS(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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -