📄 usbhost.c.c
字号:
#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 + -