📄 hub.c
字号:
if( buf[1] & 0x02 ) // 判断是低速还是全速设备
{
printf("Low speed device\n");
bMine = LOW_SPEED; // 表示低速设备连接上来
}
else
{
printf("Full speed device\n");
bMine = FULL_SPEED;
}
mDelaymS(200);
//printf("Reset HUB at %02x port%02x\n",(UINT16)bAddr,(UINT16)bPORTchange);
s = SetPortFeature( bPORTchange, PORT_RESET ); // 对有设备连接的端口复位
if ( s != USB_INT_SUCCESS ) return s;
do // 查询复位端口,直到复位完成,把完成后的状态显示出来
{
s = GetPortStatus( bPORTchange );
if ( s != USB_INT_SUCCESS ) return s;
}
while( ( buf[2] & 0x10 ) != 0x10 ); // 端口复位完成标志为1就跳出
//printf("HUB at %02x port%02x's current status:",(UINT16)bAddr,(UINT16)bPORTchange );
//printf(" %02x %02x %02x %02x\n",(UINT16)buf[0],(UINT16)buf[1],(UINT16)buf[2],(UINT16)buf[3]);
mDelaymS(20);
}
else if( ( ( buf[0] & 0x01 ) == 0 ) && ( buf[2] & 0x01 ) ) // 端口发现设备移除事件
{
bPORTchange = i; // 有设备移除的端口
i = FIND_REMOVE; // 有设备移除
//printf("HUB at %02x Port%02x's current status:",(UINT16)bAddr,(UINT16)bPORTchange);
s = GetPortStatus( bPORTchange );
if ( s != USB_INT_SUCCESS ) return s;
//printf(" %02x %02x %02x %02x\n",(UINT16)buf[0],(UINT16)buf[1],(UINT16)buf[2],(UINT16)buf[3]);
}
//printf("Port%02x's current status: %02x %02x %02x %02x\n",(UINT16)i,(UINT16)buf[0],(UINT16)buf[1],(UINT16)buf[2],(UINT16)buf[3]);
// 发现有连接或移除后清除部分标志
if( buf[2] & 0x11 ) // 如果清除复位完成,后状态连接或移除标志
{
s = ClearPortFeature( bPORTchange, C_PORT_RESET ); // 清除复位完成标志
if ( s != USB_INT_SUCCESS ) return s;
s = ClearPortFeature( bPORTchange, C_PORT_CONNECTION ); // 清除连接或移除变化标志
if ( s != USB_INT_SUCCESS ) return s;
s = GetPortStatus( bPORTchange ); // 在读取状态,确认清除完毕
if ( s != USB_INT_SUCCESS ) return s;
//printf("HUB at %02x Port%02x's current status: %02x %02x %02x %02x\n",(UINT16)bAddr,(UINT16)bPORTchange,(UINT16)buf[0],(UINT16)buf[1],(UINT16)buf[2],(UINT16)buf[3]);
}
if( i == FIND_ATTACH || i == FIND_REMOVE ) break; // 发现一个端口有设备连接或移除事件就结束查询
}
bChange = i;
mDelaymS( 200 );
return s; // 返回操作成功
}
/* 为printf和getkey输入输出初始化串口 */
void mInitSTDIO( )
{
SCON = 0x50;
PCON = 0x80;
// TL2 = RCAP2L = 0 - 10; /* 18.432MHz晶振, 57600bps */
TL2 = RCAP2L = 0 - 13; /* 24MHz晶振, 57600bps */
TH2 = RCAP2H = 0xFF;
T2CON = 0x34; /* 定时器2用于串口的波特率发生器 */
TI = 1;
}
int main( void ) // USB host
{
UINT8 i, s , n , count ;
UINT8 m, m1, m2, m3;
UINT8 k, k1, k2;
// P1&=0xF8; // 如果在U盘文件读写模块上试用本程序必须加上本行
mDelaymS( 50 ); // 等待CH374复位完成
CH374_PORT_INIT( ); /* CH374接口初始化 */
mInitSTDIO( ); /* 为了让计算机通过串口监控演示过程 */
printf( "Start CH374 Host\n" );
Init374Host( ); // 初始化USB主机
while ( 1 ) {
HostSetBusFree( ); // 设定USB主机空闲
printf( "Wait Device In\n" );
while ( 1 ) {
if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主机中断则处理
if ( Query374DeviceIn( ) ) break; // 有USB设备
}
mDelaymS( 250 ); // 由于USB设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动
if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主机中断则处理
printf( "Reset Device\n" );
HostSetBusReset( ); // USB总线复位
for ( i = 0; i < 100; i ++ ) { // 等待USB设备复位后重新连接
if ( Query374DeviceIn( ) ) break; // 有USB设备
mDelaymS( 1 );
}
if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主机中断则处理
if ( Query374DeviceIn( ) ) { // 有USB设备
if ( Query374DevFullSpeed( ) ) {
printf( "Start Full-Speed Device\n" );
HostSetFullSpeed( ); // 检测到全速USB设备
}
else {
printf( "Start Low-Speed Device\n" );
HostSetLowSpeed( ); // 检测到低速USB设备
}
}
else {
printf( "Device gone !\n" );
continue; // 设备已经断开,继续等待
}
mDelaymS( 200 );
if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主机中断则处理
bHubNum = 0; // 集线器数量
bDevNum = 0; // 功能设备数量
printf( "GetDeviceDescr: " );
s = GetDeviceDescr( buf ); // 获取设备描述符
if ( s != USB_INT_SUCCESS )
{
//printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 终止操作,等待USB设备拔出
}
for ( i = 0; i < ( (PUSB_SETUP_REQ)SetupGetDevDescr ) -> wLengthL; i ++ ) printf( "0x%02X ", (UINT16)( buf[i] ) );
printf( "\n" ); // 显示出描述符
if( ((PUSB_DEV_DESCR)buf ) -> bDeviceClass == 0x09 ) // 第一层连接上来的设备是集线器
{
bHubNum++; // 集线器数量加一
count = 0;
while(1)
{
if( p_Dev_Addr->Num[count].bAddr == 0 ) break;// 表中有空项就跳出
count++;
//if( count > 127 ) break; // 超过表容量了
}
//if( count > 127 )
//{
// printf("You have used all usb addresses.\n");
// goto WaitDeviceOut; // 终止操作,等待USB设备拔出
//}
//else
//{
bAddr = count + 1; // 找到没有用过的地址
//}
printf( "******** Appoint address %d to attached Root Hub ********\n",(UINT16)bAddr );
kk = 1;
s = HubEnum( bAddr ); // 集线器枚举
if ( s != USB_INT_SUCCESS )
{
//printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 终止操作,等待USB设备拔出
}
printf("OK\n");
p_Dev_Addr->Num[count].bAddr = bAddr;
p_Dev_Addr->Num[count].bDevType = HUB_TYPE;
p_Dev_Addr->Num[count].bUpPort = 0xff; // 主集线器
p_Dev_Addr->Num[count].bEndpSize = UsbDevEndpSize;
p_Dev_Addr->Num[count].KUNO.HUB.bNumPort = bNumPort;
p_Dev_Addr->Num[count].KUNO.HUB.bHUBendp = bHUBendp;
p_Dev_Addr->Num[count].KUNO.HUB.bInterval = bInterval;
p_Dev_Addr->Num[count].KUNO.HUB.bSlavePort[0] = 0;
p_Dev_Addr->Num[count].KUNO.HUB.bSlavePort[1] = 0;
p_Dev_Addr->Num[count].KUNO.HUB.bSlavePort[2] = 0;
p_Dev_Addr->Num[count].KUNO.HUB.bSlavePort[3] = 0;
p_Dev_Addr->Num[count].KUNO.HUB.bSlavePort[4] = 0;
p_Dev_Addr->Num[count].KUNO.HUB.bSlavePort[5] = 0;
p_Dev_Addr->Num[count].KUNO.HUB.bSlavePort[6] = 0;
/////主集线器信息录入
while(1)
{
bPORTchange = 0;
bChange = 0;
bMine = 0;
count = 0;
n = 0;
while( n < bHubNum ) // 对所有集线器操作
{
bPORTchange = 0;
bMine = 0;
bChange = 0;
while( 1 )
{
if( p_Dev_Addr->Num[count].bDevType == HUB_TYPE && p_Dev_Addr->Num[count].bAddr != 0 ) break;// 集线器类型,地址非0,可用
count++;
if( count > 50 )
{
count = 0;
n = 0;
}
}
////// 调出该集线器的信息
bAddr = p_Dev_Addr->Num[count].bAddr;
UsbDevEndpSize = p_Dev_Addr->Num[count].bEndpSize;
bNumPort = p_Dev_Addr->Num[count].KUNO.HUB.bNumPort;
bHUBendp = p_Dev_Addr->Num[count].KUNO.HUB.bHUBendp;
bInterval = p_Dev_Addr->Num[count].KUNO.HUB.bInterval;
s = PortEnum( );
if ( s == 0x20 ) // 无响应,集线器已经拔除
{
//printf("Find removed.\n");
if( bAddr == 1 )
{
goto WaitDeviceOut; // 终止操作,等待USB设备拔出
//printf("Root hub removed.\n");
}
printf("######## The removed hub's address is %d ########\n",(UINT16)bAddr);
p_Dev_Addr->Num[(bAddr-1)].bAddr = 0; // 取消被移除的最上层集线器的表项
bHubNum--; // 集线器数量减一
for( k = 0; k< 7; k++ ) // 判断该移除的最上层集线器的端口上有没连接设备
{
if( p_Dev_Addr->Num[(bAddr-1)].KUNO.HUB.bSlavePort[k] != 0 ) // 移除的最上层集线器的端口上找到连接的次级设备
{
m1 = p_Dev_Addr->Num[(bAddr-1)].KUNO.HUB.bSlavePort[k]; // 取出下一级地址
if( p_Dev_Addr->Num[(m1-1)].bDevType == FUNCTION_DEV && p_Dev_Addr->Num[(m1-1)].bAddr != 0 ) // 移除的是设备
{
printf("######## The removed device's address is %d ########\n",(UINT16)m1);
p_Dev_Addr->Num[(m1-1)].bAddr = 0; // 取消被移除的次最上层功能设备的表项
bDevNum--; // 功能设备数量减1
}
else if( p_Dev_Addr->Num[(m1-1)].bDevType == HUB_TYPE && p_Dev_Addr->Num[(m1-1)].bAddr != 0 ) // 移除的是集线器
{
printf("######## The removed hub's address is %d ########\n",(UINT16)m1);
p_Dev_Addr->Num[(m1-1)].bAddr = 0; // 取消被移除的次最上层集线器的表项
bHubNum--; // 集线器数量减一
for( k1 = 0; k1 < 7; k1 ++ )
{
if( p_Dev_Addr->Num[(m1-1)].KUNO.HUB.bSlavePort[k1] != 0 ) // 次级集线器端口上找到次次级设备
{
m2 = p_Dev_Addr->Num[(m1-1)].KUNO.HUB.bSlavePort[k1]; // 保留次次级设备地址
if( p_Dev_Addr->Num[(m2-1)].bDevType == FUNCTION_DEV && p_Dev_Addr->Num[(m2-1)].bAddr != 0 ) // 移除的是设备
{
printf("######## The removed device's address is %d ########\n",(UINT16)m2);
p_Dev_Addr->Num[(m2-1)].bAddr = 0; // 取消被移除的次次最上层功能设备的表项
bDevNum--; // 功能设备数量减1
}
else if( p_Dev_Addr->Num[(m2-1)].bDevType == HUB_TYPE && p_Dev_Addr->Num[(m2-1)].bAddr != 0 ) // 移除的是集线器
{
printf("######## The remove hub's address is %d ########\n",(UINT16)m2);
p_Dev_Addr->Num[(m2-1)].bAddr = 0; // 取消被移除的次次最上层集线器的表项
bHubNum--; // 集线器数量减一
for( k2 = 0; k2 < 7; k2++ )
{
if( p_Dev_Addr->Num[(m2-1)].KUNO.HUB.bSlavePort[k2] != 0 ) // 次次级集线器端口上找到次次次级设备
{
m3 = p_Dev_Addr->Num[(m2-1)].KUNO.HUB.bSlavePort[k2]; //// 保留次次次级设备地址
if( p_Dev_Addr->Num[(m3-1)].bDevType == FUNCTION_DEV && p_Dev_Addr->Num[(m3-1)].bAddr != 0 ) // 移除的是设备
{
printf("######## The removed device's address is %d ########\n",(UINT16)m3);
p_Dev_Addr->Num[(m3-1)].bAddr = 0; // 取消被移除的次次次最上层功能设备的表项
bDevNum--; // 功能设备数量减1
}
else if( p_Dev_Addr->Num[(m3-1)].bDevType == HUB_TYPE && p_Dev_Addr->Num[(m3-1)].bAddr!= 0 ) // 移除的是集线器
{
printf("######## The removed hub's address is %d ########\n",(UINT16)m3);
p_Dev_Addr->Num[(m3-1)].bAddr = 0; // 取消被移除的次次次最上层集线器的表项
bHubNum--; // 集线器数量减一
/////到此,只支持最多纵向5级集线器连接
}
}
} // 找不到次次次级设备就退出
}
}
} // 找不到次次级设备就退出
}
}
} // 找不到次级设备就退出
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -