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

📄 sddevice.cpp

📁 SMDK2416_BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	}
	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,&regValue,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,&regValue,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,&regValue,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,&regValue,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,&regValue,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 + -