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

📄 sddevice.cpp

📁 SMDK2416_BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		return pReturn;
	}
	else
	{
		return NULL;
	}
}
///////////////////////////////////////////////////////////////////////////////
//  GetCardRegisters - Get card registers
//  Input:  pBaseDevice - the base device
//          BaseDeviceType - base device type
//          pSlot - the slot
//  Output: 
//  Return:  SD_API_STATUS code
//  Notes:  This function retreives important card registers for the device type
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::GetCardRegisters()
{
	if (m_FuncionIndex!=0) {
		ASSERT(FALSE);
		return SD_API_STATUS_DEVICE_UNSUPPORTED;
	}
	SD_API_STATUS               status = SD_API_STATUS_DEVICE_UNSUPPORTED;    // status
	SD_COMMAND_RESPONSE         response;  // response
	UCHAR                       scrReg[SD_SCR_REGISTER_SIZE]; // temporary buffer
	USHORT                      oidValue;  // oid value
	SD_CARD_STATUS              cardStatus; // card status

	// must get CID first in order to get the cards into the IDENT state.
	// Check for SD I/O - only cards; will not have  CID.
	if (Device_SD_IO != m_DeviceType) {
		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice:  Getting registers from slot %d \n"), m_sdSlot.GetSlotIndex())); 

		// for MMC, SD Memory and SD Combo cards, retreive the CID
		status = SendSDCommand(SD_CMD_ALL_SEND_CID,0x00000000,ResponseR2,&response);

		if (!SD_API_SUCCESS(status)){
			return status;
		}

		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Got CID from device in slot %d \n"), m_sdSlot.GetSlotIndex())); 
		// update shadow registers
		UpdateCachedRegisterFromResponse( SD_INFO_REGISTER_CID, &response);
	}

	// fetch/set the RCA
	if (Device_MMC != m_DeviceType) {
		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Getting RCA from SD card in  slot %d .... \n"),m_sdSlot.GetSlotIndex())); 
		// get the RCA
		status = SendSDCommand(SD_CMD_SEND_RELATIVE_ADDR, 0x00000000,ResponseR6,&response);

		if (!SD_API_SUCCESS(status)){
			return status;
		}
		// update shadow registers
		UpdateCachedRegisterFromResponse(SD_INFO_REGISTER_RCA, &response);

		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Got RCA (0x%04X) from SD card in slot %d \n"), 
					m_RelativeAddress, m_sdSlot.GetSlotIndex())); 
	} else {
		// get OEM ID from the CID
		oidValue = m_CachedRegisters.CID[SD_CID_OID_OFFSET];
		oidValue |= (((USHORT)m_CachedRegisters.CID[SD_CID_OID_OFFSET + 1]) << 8);

		// for MMC cards set the RCA
		// take the unique OEM ID and add the slot number to it to form a system unique address
		m_RelativeAddress = (SD_CARD_RCA)(oidValue + m_sdSlot.GetSlotIndex());

		// add 1 if this is zero
		if (m_RelativeAddress == 0) {
			m_RelativeAddress++;
		}
		// for MMC cards, we must set the RCA
		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Setting MMC RCA to 0x%04X .... \n"), m_RelativeAddress)); 

		// set the RCA
		status = SendSDCommand(SD_CMD_MMC_SET_RCA,((DWORD)m_RelativeAddress) << 16, ResponseR1,&response);

		if (!SD_API_SUCCESS(status)){
			return status;
		}

		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: RCA set for MMC device in slot %d \n"), m_sdSlot.GetSlotIndex())); 
	}

	// now that the RCA has been fetched/set, we can move on to do other things.........

	// check for SD I/O - Only cards. They will not have a CSD or card status
	if (Device_SD_IO != m_DeviceType) {
		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Getting CSD in slot %d .... \n"), m_sdSlot.GetSlotIndex())); 

		// get the CSD
		status = SendSDCommand(SD_CMD_SEND_CSD,
				((DWORD)m_RelativeAddress) << 16,
				ResponseR2,
				&response);

		if (!SD_API_SUCCESS(status)){
			return status;
		}

		// update shadow registers
		UpdateCachedRegisterFromResponse(SD_INFO_REGISTER_CSD, &response);
		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Got CSD from device in slot %d \n"), m_sdSlot.GetSlotIndex())); 
		// get the card status
		status = SendSDCommand( SD_CMD_SEND_STATUS,((DWORD)m_RelativeAddress) << 16,ResponseR1, &response);
		if (!SD_API_SUCCESS(status)){
			return status;
		}


		SDGetCardStatusFromResponse(&response, &cardStatus);

		if (cardStatus & SD_STATUS_CARD_IS_LOCKED) {
			DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: card in slot %d is locked\n"), m_sdSlot.GetSlotIndex())); 
			m_SDCardInfo.SDMMCInformation.CardIsLocked = TRUE;
		}

	}

	// now in order to get the SCR register we must be in the trans state
	// also in order to do a few other things, so lets select the card now and leave it
	// selected
	// send CMD 7 to select the card and keep it selected, this is required  for SDIO cards
	// too as mentioned in I/O working group newsgroup
	status = SendSDCommand( SD_CMD_SELECT_DESELECT_CARD,((DWORD)m_RelativeAddress) << 16, ResponseR1b, &response);

	if (!SD_API_SUCCESS(status)){
		DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("CSDDevice: Failed to select card in slot %d \n"), m_sdSlot.GetSlotIndex()));     
		return status;
	}

	DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice:Card in slot %d is now selected \n"), m_sdSlot.GetSlotIndex())); 

	// only SD Memory and Combo cards have an SCR
	if ((Device_SD_Memory == m_DeviceType) || (Device_SD_Combo == m_DeviceType)) {
		// if the card is unlocked, get the SCR
		if (!m_SDCardInfo.SDMMCInformation.CardIsLocked) {
			// get the SD Configuration register
			status = SendSDAppCmd(SD_ACMD_SEND_SCR, 0, SD_READ,  ResponseR1,&response,
					1,                    // 1 block
					SD_SCR_REGISTER_SIZE, // 64 bits
					scrReg);

			// If the memory card is locked then the SCR becomes inaccessable. If we fail
			// to read the SCR then just set up the cached SCR register to default to
			// a 1bit access mode.

			if (!SD_API_SUCCESS(status)){
				DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("CSDDevice: Failed to get SCR from device in slot %d \n"), m_sdSlot.GetSlotIndex()));
				memset(m_CachedRegisters.SCR, 0, sizeof(m_CachedRegisters.SCR));
			} else {            
				// this is a spec discrepency, since the SCR register is not associated with 
				// an address, the byte order it ambiguous.  All the cards we have seen store the data 
				// most significant byte first as it arrives.  
				for (ULONG ii = 0 ; ii < sizeof(m_CachedRegisters.SCR); ii++) {
					m_CachedRegisters.SCR[ii] = scrReg[(SD_SCR_REGISTER_SIZE - 1) - ii];
				}

				DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Got SCR from device in slot %d \n"), m_sdSlot.GetSlotIndex()));     
			}
		}
	}

	return SD_API_STATUS_SUCCESS;
}
SD_API_STATUS CSDDevice::HandleDeviceSelectDeselect(SD_SLOT_EVENT SlotEvent,BOOL fSelect)
{
	SD_API_STATUS          status = SD_API_STATUS_SUCCESS;
	UCHAR                  regValue;
	SD_COMMAND_RESPONSE    response;
	DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: HandleSlotSelectDeselect++: %d \n"),SlotEvent));
	BOOL fSDIO = FALSE;
	BOOL fSDMemory = FALSE;

	if (m_DeviceType ==Device_SD_IO ||  m_DeviceType == Device_SD_Combo ) {
		fSDIO = TRUE;
	}
	if ((m_DeviceType == Device_MMC) || (m_DeviceType == Device_SD_Memory) ||(m_DeviceType == Device_SD_Combo)) { 
		fSDMemory = TRUE;
	}

	if (fSelect) {
		if (m_FuncionIndex == 0 ) {
			// Select I/O controller first
			if (fSDIO) {
				if ( m_sdSlot.GetSlotState()!= SlotDeselected ) {
					// reset I/O controller 
					regValue = SD_IO_REG_IO_ABORT_RES;
					status = SDSynchronousBusRequest_I(SD_IO_RW_DIRECT,
							BUILD_IO_RW_DIRECT_ARG((UCHAR)SD_IO_WRITE,FALSE,0,(SD_IO_REG_IO_ABORT),SD_IO_REG_IO_ABORT_RES),
							SD_COMMAND,ResponseR5,&response,0,0,NULL,(DWORD)SD_SLOTRESET_REQUEST); 
					m_RelativeAddress = 0;
				}

				// Query OCR
				if (SD_API_SUCCESS(status)) {
					status = SendSDCommand(SD_CMD_IO_OP_COND,0,ResponseR4,&response);
				}

				// Re-init I/O controller by powering it up
				if (SD_API_SUCCESS(status)) {
					status = SetCardPower(Device_SD_IO,m_OperatingVoltage,FALSE);
				}

				if (SD_API_SUCCESS(status)) {
					status = GetCardRegisters();
				}
				else {
					DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("CSDSlot: Failed to power up SDIO card \n")));  
				}
			}
			if (fSDMemory) {

				status = SDSynchronousBusRequest_I(SD_CMD_GO_IDLE_STATE,0x00000000,SD_COMMAND,NoResponse,
						NULL,0,0,NULL,(DWORD)SD_SLOTRESET_REQUEST);

				if (SD_API_SUCCESS(status)) {
					m_RelativeAddress = 0;
				}
				else{
					DbgPrintZo(SDCARD_ZONE_ERROR,
							(TEXT("CSDSlot: Go Idle Failed during selection: Status: 0x%08X on slot:%d \n"),status,m_sdSlot.GetSlotIndex()));
				}
				if (SD_API_SUCCESS(status)) { 
					if ((m_DeviceType == Device_SD_Memory) || (m_DeviceType == Device_SD_Combo)) {
						status = SendSDAppCommand(SD_ACMD_SD_SEND_OP_COND,0,ResponseR3,&response);
					}
				}
				// Should I send CMD1 for MMC card here????  TODO!!!

				// Now it is ready to re-initialize memory controller.
				// Re-initialize memory controller by powering it up
				// SetCardPower will send CMD0 first before issuing ACMD41
				if (SD_API_SUCCESS(status)) { 
					status = SetCardPower(m_DeviceType, m_OperatingVoltage,FALSE);
				}
				// For SD Memory, GetCardRegisters will do the following things:
				//  Issue CMD2 to make memory state trans to IDENT
				//  Issue CMD3 to get or set RCA
				//  Issue CMD7 to select the card again
				//  For SD Memory card, additional ACMD51 would be issued too, but
				//  should not have impact for init process.
				if (SD_API_SUCCESS(status)) { 
					status = GetCardRegisters();
				}
			}
		}
		else {
			CSDDevice * pDevice0 = m_sdSlot.GetFunctionDevice(0);
			if (pDevice0) {
				CopyContentFromParent(*pDevice0);
				pDevice0->DeRef();
			}
		}
	}
	else {// De select Card.
		if ((SlotEvent == SlotResetRequest) || (SlotEvent == SlotDeselectRequest)) {
			DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT("CSDSlot: Deselect the card\n")));

			if (m_FuncionIndex == 0 ) {
				// deselect I/O controller first, see SDIO Spec v1.1 Section 3.4.4
				if (fSDIO) {
					regValue = SD_IO_REG_IO_ABORT_RES;
					status = SDReadWriteRegistersDirect_I(SD_IO_WRITE,SD_IO_REG_IO_ABORT,FALSE,&regValue,1);
					if (SD_API_SUCCESS(status))  {
						// TODO, should CCCRShadowIntEnable to be updated???
						m_SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIOEnable = 0;
					}
					else {
						DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to deselect SDIO card \n")));  
					}
				}
				if (fSDMemory && SD_API_SUCCESS(status)) {
					status = SDSynchronousBusRequest_I(SD_CMD_GO_IDLE_STATE,
							0x00000000,SD_COMMAND,NoResponse,NULL,0,0,NULL,(DWORD)SD_SLOTRESET_REQUEST);
					if (SD_API_SUCCESS(status))  {
						DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("CSDSlot: Go Idle Failed during deselection: Status: 0x%08X \n"),
									status));
					}

				}
			}
			m_RelativeAddress = 0;
			m_bCardDeselectRequest = FALSE;
		}
	}
	return status;
}

///////////////////////////////////////////////////////////////////////////////
//  DeactivateCardDetect - Deativate Card Detect resistors on SD devices
//  Input:  pBaseDevice - the base device
//          BaseDeviceType - the base device type
//          pSlot - the slot
//  Output: 
//  Return : SD_API_STATUS code
//  Notes:  This function deactivates the card detect resistor for SDIO,
//          SD and or Combo cards
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::DeactivateCardDetect()
{
	UCHAR                   regValue;       // intermediate value
	SD_API_STATUS           status;         // status
	SD_COMMAND_RESPONSE     response;       // response
	BOOL                    fDisableSDIO;   // disable SDIO portion?

	ASSERT(m_FuncionIndex == 0);
	if (Device_SD_IO == m_DeviceType ) {
		fDisableSDIO = TRUE;
	}
	else if (Device_SD_Combo == m_DeviceType) {
		fDisableSDIO = TRUE;

		// *** Combo Card Issue ***
		// SDIO 1.00 requires that both memory and SDIO portions of combo
		// cards be deactivated.
		// SDIO 1.10 only requires one of memory or SDIO combo to be disabled. (4.6)
		// Some 1.10 cards have a problem where only one can be disabled--disabling 
		// both simultaneously will fail.
		//
		// Our solution is to disable both for < 1.10 and only disable memory 
		// for >= 1.10.

		BYTE bSDIORevision; // SDIO spec version
		status = SDReadWriteRegistersDirect_I(SD_IO_READ, SD_IO_REG_CCCR, FALSE, &bSDIORevision, sizeof(bSDIORevision));
		if (!SD_API_SUCCESS(status)) {
			DEBUGMSG(SDCARD_ZONE_ERROR, 
					(TEXT("SDBusDriver: Failed to read SDIO revision in slot %d. We will treat it as a 1.0 combo card \n"),

⌨️ 快捷键说明

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