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

📄 usbhost.c.c

📁 主机端控制C程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif
	UsbDevice -> PciAddr = PciAddr;
	UsbDevice -> IoBaseAddr = IoBaseAddr;
	UsbDevice -> PortIndex = Index;  /* 设备占的HUB端口号,排序所有UHCI控制器,值从1开始 */
	return( ERR_SUCCESS );
}

UCHAR	USB_StartUHCI(  /* 开始运行UHCI */
	mPUSB_DEVICE	UsbDevice )  /* 指向USB设备信息 */
{
	mPUHCI_IO_REG	IoBaseAddr;
#ifdef	DEBUG
	printf( "Start1: Frame=%08lXH, Base=%04XH\n", UsbDevice -> FrameBaseAddr, UsbDevice -> IoBaseAddr );
#endif
	if ( UsbDevice -> FrameBaseAddr == 0 ) return( ERR_MEM_ADDR );
	if ( ( UsbDevice -> FrameBaseAddr & 0x0FFF ) ) return( ERR_MEM_ADDR );
	IoBaseAddr = UsbDevice -> IoBaseAddr;
	if ( IoBaseAddr == (mPUHCI_IO_REG)0 ) return( ERR_IO_PORT );
	UsbDevice -> OldFrameBase = PortInWord( & ( IoBaseAddr -> mFRBASEADD1) ) << 16 | PortInWord( & ( IoBaseAddr -> mFRBASEADD0 ) ) & 0xF000;
#ifdef	DEBUG
	printf( "Start2: OldFrame=%08lXH\n", UsbDevice -> OldFrameBase );
	printf( "Start2: INTR=%04XH, CMD=%04XH, STS=%04XH, Hub1=%04XH, Hub2=%04XH\n", PortInWord( & ( IoBaseAddr -> mUSBINTR ) ), \
	PortInWord( & ( IoBaseAddr -> mUSBCMD ) ), PortInWord( & ( IoBaseAddr -> mUSBSTS ) ), \
	PortInWord( & ( IoBaseAddr -> mPORTSC1 ) ), PortInWord( & ( IoBaseAddr -> mPORTSC2 ) ) );
#endif
	PortOutWord( & ( IoBaseAddr -> mUSBINTR ), 0x0000);  /* 清中断允许寄存器 */
	PortOutWord( & ( IoBaseAddr -> mUSBCMD ), USBCMD_CF | USBCMD_MAXP );  /* 命令寄存器,设置64字节最大包 */
	PortOutWord( & ( IoBaseAddr -> mUSBSTS ), 0xFFFF );  /* 清状态寄存器 */
	PortOutWord( & ( IoBaseAddr -> mPORTSC1 ), USBPORTSC_PEC | USBPORTSC_CSC );  /* 清HUB端口 */
	PortOutWord( & ( IoBaseAddr -> mPORTSC2 ), USBPORTSC_PEC | USBPORTSC_CSC );
	PortOutWord( & ( IoBaseAddr -> mFRBASEADD1 ), (USHORT)( UsbDevice -> FrameBaseAddr >> 16 ) );  /* 设置帧列表基址 */
	PortOutWord( & ( IoBaseAddr -> mFRBASEADD0 ), (USHORT)( UsbDevice -> FrameBaseAddr ) );
	USB_SetupQH( UsbDevice );
	PortOutWord( & ( IoBaseAddr -> mUSBCMD ), USBCMD_CF | USBCMD_MAXP | USBCMD_RS );  /* 命令寄存器,设置64字节最大包,运行 */
#ifdef	DEBUG
	printf( "Start3: INTR=%04XH, CMD=%04XH, STS=%04XH, Hub1=%04XH, Hub2=%04XH\n", PortInWord( & ( IoBaseAddr -> mUSBINTR ) ), \
	PortInWord( & ( IoBaseAddr -> mUSBCMD ) ), PortInWord( & ( IoBaseAddr -> mUSBSTS ) ), \
	PortInWord( & ( IoBaseAddr -> mPORTSC1 ) ), PortInWord( & ( IoBaseAddr -> mPORTSC2 ) ) );
#endif
	return( ERR_SUCCESS );
}

void	USB_StopUHCI(  /* 停止运行UHCI */
	mPUSB_DEVICE	UsbDevice )  /* 指向USB设备信息 */
{
	mPUHCI_IO_REG	IoBaseAddr;
	IoBaseAddr = UsbDevice -> IoBaseAddr;
#ifdef	DEBUG
	printf( "Stop1: INTR=%04XH, CMD=%04XH, STS=%04XH, Hub1=%04XH, Hub2=%04XH\n", PortInWord( & ( IoBaseAddr -> mUSBINTR ) ), \
	PortInWord( & ( IoBaseAddr -> mUSBCMD ) ), PortInWord( & ( IoBaseAddr -> mUSBSTS ) ), \
	PortInWord( & ( IoBaseAddr -> mPORTSC1 ) ), PortInWord( & ( IoBaseAddr -> mPORTSC2 ) ) );
#endif
	PortOutWord( & ( IoBaseAddr -> mUSBCMD ), USBCMD_MAXP );  /* 命令寄存器,设置64字节最大包 */
	PortOutWord( & ( IoBaseAddr -> mUSBSTS ), 0xFFFF );  /* 清状态寄存器 */
	PortOutWord( & ( IoBaseAddr -> mFRBASEADD1 ), (USHORT)( UsbDevice -> OldFrameBase >> 16 ) );  /* 设置帧列表基址 */
	PortOutWord( & ( IoBaseAddr -> mFRBASEADD0 ), (USHORT)( UsbDevice -> OldFrameBase ) );
	PortOutWord( & ( IoBaseAddr -> mPORTSC1 ), USBPORTSC_PEC | USBPORTSC_CSC );  /* 禁止USB端口 */
	PortOutWord( & ( IoBaseAddr -> mPORTSC2 ), USBPORTSC_PEC | USBPORTSC_CSC );  /* 禁止USB端口 */
#ifdef	DEBUG
	printf( "Stop2: INTR=%04XH, CMD=%04XH, STS=%04XH, Hub1=%04XH, Hub2=%04XH\n", PortInWord( & ( IoBaseAddr -> mUSBINTR ) ), \
	PortInWord( & ( IoBaseAddr -> mUSBCMD ) ), PortInWord( & ( IoBaseAddr -> mUSBSTS ) ), \
	PortInWord( & ( IoBaseAddr -> mPORTSC1 ) ), PortInWord( & ( IoBaseAddr -> mPORTSC2 ) ) );
#endif
}

void	USB_ResetPort(  /* 复位并使能指定的HUB端口 */
	mPUSB_DEVICE	UsbDevice )  /* 指向USB设备信息 */
{
	USHORT			i;
	mPUHCI_IO_REG	IoBaseAddr;
	USHORT			HubPortAddr;
	IoBaseAddr = UsbDevice -> IoBaseAddr;
#ifdef	DEBUG
	printf( "Hub1: FRNUM=%04XH, CMD=%04XH, STS=%04XH, Hub1=%04XH, Hub2=%04XH\n", PortInWord( & ( IoBaseAddr -> mFRNUM ) ), \
	PortInWord( & ( IoBaseAddr -> mUSBCMD ) ), PortInWord( & ( IoBaseAddr -> mUSBSTS ) ), \
	PortInWord( & ( IoBaseAddr -> mPORTSC1 ) ), PortInWord( & ( IoBaseAddr -> mPORTSC2 ) ) );
#endif
	HubPortAddr = ( UsbDevice -> PortIndex & 1 ) ? (USHORT)&( IoBaseAddr -> mPORTSC2 ) : (USHORT)&( IoBaseAddr -> mPORTSC1 );
	PortOutWord( HubPortAddr, USBPORTSC_PE | USBPORTSC_PR );  /* 复位USB端口 */
	USB_DelaymS( 16 );
	PortOutWord( HubPortAddr, USBPORTSC_PEC | USBPORTSC_CSC );  /* 结束复位 */
	USB_DelaymS( 1 );
	PortOutWord( HubPortAddr, USBPORTSC_PE | USBPORTSC_PEC | USBPORTSC_CSC );  /* 使能USB端口 */
	USB_DelaymS( 16 );
	UsbDevice -> DevAddr = 0;
	UsbDevice -> EndpNum = 0;
	UsbDevice -> EndpInfo[ 0 ].EndpAddr = 0;
	UsbDevice -> EndpInfo[ 0 ].MaxSize = 8;
#ifdef	DEBUG
	printf( "Hub2: FRNUM=%04XH, CMD=%04XH, STS=%04XH, Hub1=%04XH, Hub2=%04XH\n", PortInWord( & ( IoBaseAddr -> mFRNUM ) ), \
	PortInWord( & ( IoBaseAddr -> mUSBCMD ) ), PortInWord( & ( IoBaseAddr -> mUSBSTS ) ), \
	PortInWord( & ( IoBaseAddr -> mPORTSC1 ) ), PortInWord( & ( IoBaseAddr -> mPORTSC2 ) ) );
#endif
}

UCHAR	USB_SubmitTrans(  /* 执行一个USB事务传输,返回状态 */
	mPUSB_DEVICE	UsbDevice,  /* 指向USB设备信息 */
	mPUSB_TRANS		UsbTrans )  /* 指向USB传输信息 */
{
	UCHAR			mStatus;
	mPUHCI_IO_REG	IoBaseAddr;
	USB_DisableTD( UsbDevice );
	IoBaseAddr = UsbDevice -> IoBaseAddr;
	if ( UsbDevice -> PortIndex & 1 ) PortOutWord( & ( IoBaseAddr -> mPORTSC2 ), USBPORTSC_PE | USBPORTSC_PEC );  /* 重新设置HUB2的使能标志位 */
	else PortOutWord( & ( IoBaseAddr -> mPORTSC1 ), USBPORTSC_PE | USBPORTSC_PEC );  /* 重新设置HUB1的使能标志位 */
	PortOutWord( & ( IoBaseAddr -> mUSBSTS ), 0xFFFF );  /* 清状态位 */
	USB_SetupTD( UsbDevice, UsbTrans );
#ifdef	DEBUG
	printf( "Trans1: FRNUM=%04XH, CMD=%04XH, STS=%04XH, Hub1=%04XH, Hub2=%04XH\n", PortInWord( & ( IoBaseAddr -> mFRNUM ) ), \
	PortInWord( & ( IoBaseAddr -> mUSBCMD ) ), PortInWord( & ( IoBaseAddr -> mUSBSTS ) ), \
	PortInWord( & ( IoBaseAddr -> mPORTSC1 ) ), PortInWord( & ( IoBaseAddr -> mPORTSC2 ) ) );
#endif
	USB_EnableTD( UsbDevice );
	mStatus = USB_WaitTrans( UsbDevice, UsbTrans );
	USB_DisableTD( UsbDevice );
#ifdef	DEBUG
	printf( "Trans2: FRNUM=%04XH, CMD=%04XH, STS=%04XH, Hub1=%04XH, Hub2=%04XH, status=%02XH\n", PortInWord( & ( IoBaseAddr -> mFRNUM ) ), \
	PortInWord( & ( IoBaseAddr -> mUSBCMD ) ), PortInWord( & ( IoBaseAddr -> mUSBSTS ) ), \
	PortInWord( & ( IoBaseAddr -> mPORTSC1 ) ), PortInWord( & ( IoBaseAddr -> mPORTSC2 ) ), (USHORT)mStatus );
#endif
	return( mStatus );  /* 返回状态 */
}

UCHAR	USB_SubmitCtrl(  /* 执行一个USB控制传输,返回状态 */
	mPUSB_DEVICE	UsbDevice,  /* 指向USB设备信息 */
	mPUSB_TRANS		UsbTrans )  /* 指向USB传输信息,SETUP请求在缓冲区中,返回数据在缓冲区中 */
{
	UCHAR			i, mCount, mTotalLen, mStatus;
	UCHAR			mBuffer[ sizeof( UsbTrans -> Buffer ) * 2 ];
	mPUSB_SETUP_PKT	mCtrlSetup;
	mCtrlSetup = (mPUSB_SETUP_PKT) & UsbTrans -> Buffer;
	if ( mCtrlSetup -> mLength > sizeof( UsbTrans -> Buffer ) ) mCtrlSetup -> mLength = sizeof( UsbTrans -> Buffer );
	mTotalLen = (UCHAR)( mCtrlSetup -> mLength );
	if ( mTotalLen && ( mCtrlSetup -> mUspReqType & USB_ENDP_DIR_MASK ) == USB_ENDP_DIR_OUT ) return( ERR_CTRL_OUT_LEN );
	UsbDevice -> EndpInfo[ 0 ].DataTog = 0;
	UsbTrans -> EndpIndex = 0;
	UsbTrans -> PID = DEF_USB_PID_SETUP;
	UsbTrans -> Len = 8;
	UsbTrans -> Timeout = 5000;
	mStatus = USB_SubmitTrans( UsbDevice, UsbTrans );  /* 执行一个USB事务传输 */
#ifdef	DEBUG
	printf( "CtrlReq: Setup status=%02XH, req=%02XH, len=%d\n", (USHORT)mStatus, (USHORT)( mCtrlSetup -> mUspRequest ), (USHORT)mTotalLen );
#endif
	if ( mStatus == ERR_SUCCESS ) {
		if ( mTotalLen ) {  /* 数据阶段 */
			for ( mCount = 0; mCount < mTotalLen; ) {
				UsbDevice -> EndpInfo[ 0 ].DataTog ^= 1;
				UsbTrans -> PID = DEF_USB_PID_IN;
				UsbTrans -> Len = USB_ENDP_MAX_SIZE;
				mStatus = USB_SubmitTrans( UsbDevice, UsbTrans );  /* 执行一个USB事务传输 */
#ifdef	DEBUG
				printf( "CtrlReq: DataIn status=%02XH, len=%d\n", (USHORT)mStatus, (USHORT)( UsbTrans -> Len ) );
#endif
				if ( mStatus == ERR_SUCCESS ) {
					for ( i = 0; i < UsbTrans -> Len; i++ ) mBuffer[ mCount + i ] = UsbTrans -> Buffer[ i ];
					mCount += UsbTrans -> Len;
					if ( UsbTrans -> Len == 0 || ( UsbTrans -> Len & ( UsbDevice -> EndpInfo[ 0 ].MaxSize - 1 ) ) ) break;  /* 提前结束 */
				}
				else break;
			}
			UsbDevice -> EndpInfo[ 0 ].DataTog = 1;
			UsbTrans -> PID = DEF_USB_PID_OUT;
			UsbTrans -> Len = 0;
			mStatus = USB_SubmitTrans( UsbDevice, UsbTrans );  /* 执行一个USB事务传输 */
#ifdef	DEBUG
			printf( "CtrlReq: Status status=%02XH\n", (USHORT)mStatus );
#endif
			for ( i = 0; i != mCount; i++ ) UsbTrans -> Buffer[ i ] = mBuffer[ i ];
			UsbTrans -> Len = mCount;
		}
		else {
			UsbDevice -> EndpInfo[ 0 ].DataTog = 1;
			UsbTrans -> PID = DEF_USB_PID_IN;
			UsbTrans -> Len = USB_ENDP_MAX_SIZE;
			mStatus = USB_SubmitTrans( UsbDevice, UsbTrans );  /* 执行一个USB事务传输 */
#ifdef	DEBUG
			printf( "CtrlReq: Status status=%02XH, len=%d\n", (USHORT)mStatus, (USHORT)( UsbTrans -> Len ) );
#endif
			if ( mStatus == ERR_SUCCESS && UsbTrans -> Len ) mStatus = ERR_CTRL_OUT_STS;
		}
	}
	return( mStatus );
}

UCHAR	USB_GetDevDescr(  /* 获取设备描述符,返回状态 */
	mPUSB_DEVICE	UsbDevice,  /* 指向USB设备信息 */
	mPUSB_TRANS		UsbTrans )  /* 指向USB传输信息, 返回数据在缓冲区中 */
{
	UCHAR			mStatus;
	mPUSB_SETUP_PKT	mCtrlSetup;
	mPUSB_DEV_DESCR	DevDescr;
	mCtrlSetup = (mPUSB_SETUP_PKT) & UsbTrans -> Buffer;
	mCtrlSetup -> mUspReqType = DEF_USB_REQ_READ | DEF_USB_REQ_STAND;
	mCtrlSetup -> mUspRequest = DEF_USB_GET_DESCR;
	mCtrlSetup -> mUspValue = 0x0100;
	mCtrlSetup -> mUspIndex = 0x0000;
	mCtrlSetup -> mLength = 0x0012;
	mStatus = USB_SubmitCtrl( UsbDevice, UsbTrans );  /* 执行一个USB控制传输 */
	if ( mStatus == ERR_SUCCESS ) {
		if ( UsbTrans -> Len >= sizeof( mUSB_DEV_DESCR ) ) {
			DevDescr = (mPUSB_DEV_DESCR) & ( UsbTrans -> Buffer );
			UsbDevice -> EndpInfo[ 0 ].MaxSize = DevDescr -> bMaxPacketSize0;
			UsbDevice -> idVendor = DevDescr -> idVendor;
			UsbDevice -> idProduct = DevDescr -> idProduct;
			UsbDevice -> bcdDevice = DevDescr -> bcdDevice;
			UsbDevice -> bDeviceClass = DevDescr -> bDeviceClass;
			UsbDevice -> bDeviceSubClass = DevDescr -> bDeviceSubClass;
			UsbDevice -> bDeviceProtocol = DevDescr -> bDeviceProtocol;
#ifdef	DEBUG
			printf( "DevDescr: VenID=%04XH, ProdID=%04XH, MaxSize=%02XH, DevCls=%02XH\n", \
			UsbDevice -> idVendor, UsbDevice -> idProduct, (USHORT)( UsbDevice -> EndpInfo[ 0 ].MaxSize ), (USHORT)( UsbDevice -> bDeviceClass ) );
#endif
		}
	}
	return( mStatus );
}

UCHAR	USB_SetUsbAddr(  /* 设置USB地址,返回状态 */
	mPUSB_DEVICE	UsbDevice,  /* 指向USB设备信息 */
	UCHAR			UsbAddr )  /* 指定USB地址 */
{
	UCHAR			mStatus;
	mUSB_TRANS		mUsbTrans;
	mPUSB_SETUP_PKT	mCtrlSetup;
	mCtrlSetup = (mPUSB_SETUP_PKT) & mUsbTrans.Buffer;
	mCtrlSetup -> mUspReqType = DEF_USB_REQ_WRITE | DEF_USB_REQ_STAND;
	mCtrlSetup -> mUspRequest = DEF_USB_SET_ADDRESS;
	mCtrlSetup -> mUspValue = UsbAddr;
	mCtrlSetup -> mUspIndex = 0x0000;
	mCtrlSetup -> mLength = 0x0000;
	mStatus = USB_SubmitCtrl( UsbDevice, &mUsbTrans );  /* 执行一个USB控制传输 */
	if ( mStatus == ERR_SUCCESS ) UsbDevice -> DevAddr = UsbAddr;
	USB_DelaymS( 5 );
	return( mStatus );
}

UCHAR	USB_GetCfgDescr(  /* 获取配置描述符,返回状态 */
	mPUSB_DEVICE	UsbDevice,  /* 指向USB设备信息 */
	mPUSB_TRANS		UsbTrans )  /* 指向USB传输信息, 返回数据在缓冲区中 */
{
	UCHAR					mStatus, i;
	mPUSB_SETUP_PKT			mCtrlSetup;
	mPUSB_CFG_DESCR_LONG	CfgDescr;
	mCtrlSetup = (mPUSB_SETUP_PKT) & UsbTrans -> Buffer;
	mCtrlSetup -> mUspReqType = DEF_USB_REQ_READ | DEF_USB_REQ_STAND;
	mCtrlSetup -> mUspRequest = DEF_USB_GET_DESCR;
	mCtrlSetup -> mUspValue = 0x0200;
	mCtrlSetup -> mUspIndex = 0x0000;
	mCtrlSetup -> mLength = sizeof( mUSB_CFG_DESCR_LONG );
	mStatus = USB_SubmitCtrl( UsbDevice, UsbTrans );  /* 执行一个USB控制传输 */
	if ( mStatus == ERR_SUCCESS ) {
		if ( UsbTrans -> Len >= mOFFSET( mUSB_CFG_DESCR_LONG, endp_descr ) ) {
			CfgDescr = (mPUSB_CFG_DESCR_LONG) & UsbTrans -> Buffer;
			UsbDevice -> EndpNum = min( CfgDescr -> itf_descr.bNumEndpoints, USB_ENDP_MAX_NUM ) + 1;  /* 含端点0 */
			for ( i = 1; i < UsbDevice -> EndpNum; i++ ) {
				UsbDevice -> EndpInfo[ i ].EndpAddr = CfgDescr -> endp_descr[ i - 1 ].bEndpointAddress;
				UsbDevice -> EndpInfo[ i ].MaxSize = CfgDescr -> endp_descr[ i - 1 ].wMaxPacketSizeL;
#ifdef	DEBUG
				printf( "CfgDescr: EndpAddr=%02XH, EndpSize=%02XH\n", (USHORT)( UsbDevice -> EndpInfo[ i ].EndpAddr ), (USHORT)( UsbDevice -> EndpInfo[ i ].MaxSize ) );
#endif
			}
		}
	}
	return( mStatus );
}

UCHAR	USB_SetUsbConfig(  /* 设置USB配置值,返回状态 */
	mPUSB_DEVICE	UsbDevice,  /* 指向USB设备信息 */
	UCHAR			CfgValue )  /* 指定配置值 */
{
	UCHAR			mStatus, i;
	mUSB_TRANS		mUsbTrans;
	mPUSB_SETUP_PKT	mCtrlSetup;
	mCtrlSetup = (mPUSB_SETUP_PKT) & mUsbTrans.Buffer;
	mCtrlSetup -> mUspReqType = DEF_USB_REQ_WRITE | DEF_USB_REQ_STAND;
	mCtrlSetup -> mUspRequest = DEF_USB_SET_CONFIG;
	mCtrlSetup -> mUspValue = CfgValue;
	mCtrlSetup -> mUspIndex = 0x0000;
	mCtrlSetup -> mLength = 0x0000;
	mStatus = USB_SubmitCtrl( UsbDevice, &mUsbTrans );  /* 执行一个USB控制传输 */
	if ( mStatus == ERR_SUCCESS ) {
		for ( i = 1; i < UsbDevice -> EndpNum; i++ ) UsbDevice -> EndpInfo[ i ].DataTog = 0;
	}
	return( mStatus );
}

UCHAR	USB_ClearStall(  /* 清除端点停止特性,返回状态 */
	mPUSB_DEVICE	UsbDevice,  /* 指向USB设备信息 */
	UCHAR			EndpIndex )  /* 被操作的端点序号 */
{
	UCHAR			mStatus, i;
	mUSB_TRANS		mUsbTrans;
	mPUSB_SETUP_PKT	mCtrlSetup;
	mCtrlSetup = (mPUSB_SETUP_PKT) & mUsbTrans.Buffer;
	mCtrlSetup -> mUspReqType = DEF_USB_REQ_WRITE | DEF_USB_REQ_STAND | 2;  /* 指向端点 */
	mCtrlSetup -> mUspRequest = DEF_USB_CLR_FEATURE;
	mCtrlSetup -> mUspValue = 0x0000;
	mCtrlSetup -> mUspIndex = UsbDevice -> EndpInfo[ EndpIndex ].EndpAddr;
	mCtrlSetup -> mLength = 0x0000;
	mStatus = USB_SubmitCtrl( UsbDevice, &mUsbTrans );  /* 执行一个USB控制传输 */
	if ( mStatus == ERR_SUCCESS ) {
		UsbDevice -> EndpInfo[ EndpIndex ].DataTog = 0;
	}
	return( mStatus );
}

⌨️ 快捷键说明

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