⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sddevice.cpp

📁 SMDK2416_BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					 m_sdSlot.GetSlotIndex()));
		}
		else {
			bSDIORevision >>= 4; // SDIO revision is in the upper four bits.
			if (bSDIORevision != 0x0) {
				fDisableSDIO = FALSE;
			}
		}
	}
	else {
		DEBUGCHK(Device_SD_Memory == m_DeviceType || 
				Device_MMC == m_DeviceType);
		fDisableSDIO = FALSE;
	}

	// for SD memory or combo, send ACMD42 to turn off card detect resistor
	if ( (Device_SD_Memory == m_DeviceType) || 
			(Device_SD_Combo == m_DeviceType) ) {
		// send ACMD42
		status = SendSDAppCommand(SD_ACMD_SET_CLR_CARD_DETECT,
				0x00000000,  // bit 0 - cleared to disconnect pullup resistor
				ResponseR1,
				&response);

		if (!SD_API_SUCCESS(status)){
			DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to turn off CD resistor in slot %d \n"), m_sdSlot.GetSlotIndex())); 
			return status;
		}
	}

	// for SD I/O or SD Combo cards, write to the Bus Interface control register and clear the CD bit
	if (fDisableSDIO) {
		regValue = SD_IO_BUS_CONTROL_CD_DETECT_DISABLE; 

		status = SDReadWriteRegistersDirect_I(SD_IO_WRITE,
				SD_IO_REG_BUS_CONTROL,
				TRUE,        // read after write
				&regValue,
				1);

		if (!SD_API_SUCCESS(status)){
			DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to turn off CD resistor for SDIO Device in slot %d \n"), m_sdSlot.GetSlotIndex())); 
			return status;
		}
	}

	return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
//  UpdateCachedRegisterFromResponse - update the device shadow registers from the
//                                     information in the response buffer
//  Input:  pDevice - the device who's shadowed register should be updated
//          Register - the information to update
//          pResponse - the response containing the register data
//  Output: 
//  Return
//  Notes:  
//         
///////////////////////////////////////////////////////////////////////////////
VOID CSDDevice::UpdateCachedRegisterFromResponse(SD_INFO_TYPE  Register,PSD_COMMAND_RESPONSE     pResponse) 
{

	switch (Register) { 

		case SD_INFO_REGISTER_CID:
			memcpy(m_CachedRegisters.CID, pResponse->ResponseBuffer, SD_CID_REGISTER_SIZE);
			break;
		case SD_INFO_REGISTER_RCA:
			// RCA is in bytes 3,4
			m_RelativeAddress = (SD_CARD_RCA)pResponse->ResponseBuffer[3];
			m_RelativeAddress |= ((SD_CARD_RCA)pResponse->ResponseBuffer[4]) << 8;
			break;
		case SD_INFO_REGISTER_OCR: 
			m_CachedRegisters.OCR[3] = pResponse->ResponseBuffer[4];
			m_CachedRegisters.OCR[2] = pResponse->ResponseBuffer[3];
			m_CachedRegisters.OCR[1] = pResponse->ResponseBuffer[2];
			m_CachedRegisters.OCR[0] = pResponse->ResponseBuffer[1];
			break;
		case SD_INFO_REGISTER_CSD:
			memcpy(m_CachedRegisters.CSD, pResponse->ResponseBuffer, SD_CSD_REGISTER_SIZE);
			break;
		case SD_INFO_REGISTER_IO_OCR:
			m_CachedRegisters.IO_OCR[2] = pResponse->ResponseBuffer[3];
			m_CachedRegisters.IO_OCR[1] = pResponse->ResponseBuffer[2];
			m_CachedRegisters.IO_OCR[0] = pResponse->ResponseBuffer[1];
			break;
		default:
			DEBUGCHK(FALSE);
	}

}
SD_API_STATUS  CSDDevice::SetOperationVoltage(SDCARD_DEVICE_TYPE DeviceType,BOOL SetHCPower)
{
	SD_API_STATUS status = SD_API_STATUS_DEVICE_UNSUPPORTED;
	if (SetHCPower) {
		DWORD ocrValue;
		ASSERT(m_FuncionIndex == 0 );
		if (m_DeviceType == Device_SD_Memory || m_DeviceType == Device_MMC) {
			ocrValue = (DWORD)m_CachedRegisters.OCR[0] & ~0xF;
			ocrValue |= ((DWORD)m_CachedRegisters.OCR[1]) << 8;  
			ocrValue |= ((DWORD)m_CachedRegisters.OCR[2]) << 16; 
		}
		else if (m_DeviceType == Device_SD_IO || m_DeviceType == Device_SD_Combo) {
			ocrValue = (DWORD)m_CachedRegisters.IO_OCR[0] & ~0xF;
			ocrValue |= ((DWORD)m_CachedRegisters.IO_OCR[1]) << 8; 
			ocrValue |= ((DWORD)m_CachedRegisters.IO_OCR[2]) << 16;
		}
		else 
			ASSERT(FALSE);
		m_OperatingVoltage = m_sdSlot.SDGetOperationalVoltageRange(ocrValue);
	}
	// check to see if the voltages can be supported
	if (0 != m_OperatingVoltage ) {

		// power up the card
		status = SetCardPower(DeviceType, m_OperatingVoltage, SetHCPower);
	}
	return status;

}
///////////////////////////////////////////////////////////////////////////////
//  SetCardPower - Set the card power
//  Input:  DeviceType - the device type 
//          OperatingVoltageMask - operating voltage mask
//          pSlot - the slot
//          SetHCPower - flag to indicate whether the power should be set in the HC
//                       (combo cards do not need to reset power if the I/O portion
//                        was already powered).     
//              
//  Output: 
//  Return: SD_API_STATUS code
//  Notes:  
//          This function sets the card power and polls the card until it is
//          not busy
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::SetCardPower(SDCARD_DEVICE_TYPE DeviceType,DWORD OperatingVoltageMask,BOOL SetHCPower)
{
	SD_API_STATUS       status = SD_API_STATUS_SUCCESS;  // intermediate status 
	SD_COMMAND_RESPONSE response;                        // response
	UCHAR               command;                         // command
	SD_RESPONSE_TYPE    responseType;                    // response type
	ULONG               powerUpRetries;                  // power up retries
	BOOL                appcmd = FALSE;                  // command is an app cmd
	ULONG               powerUpInterval;                 // powerup interval
	ULONG               totalPowerUpTime;                // total powerup time
	ULONG               powerUpIntervalByDevice;         // powerup interval by device

	switch (DeviceType) {

		case Device_MMC:
			command = SD_CMD_MMC_SEND_OPCOND;
			responseType = ResponseR3;
			powerUpIntervalByDevice = DEFAULT_POWER_UP_MMC_POLL_INTERVAL;
			break;
		case Device_SD_IO:
			command = SD_CMD_IO_OP_COND;
			responseType = ResponseR4;
			powerUpIntervalByDevice = DEFAULT_POWER_UP_SDIO_POLL_INTERVAL;
			break;
		case Device_SD_Memory:
			command = SD_ACMD_SD_SEND_OP_COND;
			responseType = ResponseR3;
			appcmd = TRUE;
			powerUpIntervalByDevice = DEFAULT_POWER_UP_SD_POLL_INTERVAL;
			break;
		default:
			DEBUGCHK(FALSE);
			return SD_API_STATUS_INVALID_PARAMETER;
	}

	// check to see if we need to apply power
	if (SetHCPower) {
		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Setting slot %d power to 0x%08X \n"), 
					m_sdSlot.GetSlotIndex(), OperatingVoltageMask)); 
		// set slot power           
		status = m_sdSlot.SDSetSlotPower(OperatingVoltageMask);    

		if (!SD_API_SUCCESS(status)) {
			DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Host failed to set slot power 0x%08X on slot:%d \n"),
						status, m_sdSlot.GetSlotIndex()));
			return status;
		}

		m_sdSlot.DelayForPowerUp();
	}

	if (Device_SD_IO != DeviceType) {
		// put the card into idle again
		status = SendSDCommand(SD_CMD_GO_IDLE_STATE, 0x00000000, NoResponse, NULL);
		if (!SD_API_SUCCESS(status)){
			DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Go Idle Failed during powerup: Status: 0x%08X on slot:%d \n"),status,
						m_sdSlot.GetSlotIndex()));
			return status;
		}
		if ((Device_SD_Memory == DeviceType || Device_MMC==DeviceType) && IsValid20Card()) {
			OperatingVoltageMask |= 0x40000000; // HCS
		}
	}

	totalPowerUpTime = CSDHostContainer::RegValueDWORD(POWER_UP_POLL_TIME_KEY, DEFAULT_POWER_UP_TOTAL_WAIT_TIME);
	powerUpInterval = CSDHostContainer::RegValueDWORD(POWER_UP_POLL_TIME_INTERVAL_KEY, powerUpIntervalByDevice);

	powerUpRetries = totalPowerUpTime/powerUpInterval;

	DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Power Set, checking card in slot %d, MaxRetries: %d, Time: %d MS, Interval: %d MS \n"), 
				m_sdSlot.GetSlotIndex(), powerUpRetries, totalPowerUpTime , powerUpInterval)); 

	while (powerUpRetries != 0) {

		if (appcmd) {
			// send it as an APP cmd
			status = SendSDAppCommand(command,
					OperatingVoltageMask,
					responseType,
					&response);
		} else {
#ifdef _MMC_SPEC_42_
			/*************************************************************************/
			/****** Date : 07.05.04                                         	******/
			/****** Developer : HS.JANG											******/
			/****** Description : To support MMC Spec 4.2						******/
			/*************************************************************************/

			OperatingVoltageMask |= (1<<30);
			/*************************************************************************/
#endif
			// send the command to get the ready bit
			status = SendSDCommand(command,
					OperatingVoltageMask,
					responseType,
					&response);
		}

		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")));  
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -