📄 host.c
字号:
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER | BIT_IF_USB_SUSPEND | BIT_IF_WAKE_UP ); // 清中断标志
}
}
void SetHostUsbAddr( UINT8 addr ) // 设置USB主机当前操作的USB设备地址
{
Write374Byte( REG_USB_ADDR, addr );
}
void HostSetBusFree( void ) // USB总线空闲
{
// Write374Byte( REG_USB_SETUP, M_SET_USB_BUS_FREE( Read374Byte( REG_USB_SETUP ) ) ); // USB总线空闲
Write374Byte( REG_USB_SETUP, BIT_SETP_HOST_MODE ); // USB总线复位
Write374Byte( REG_USB_SETUP, BIT_SETP_HOST_MODE | BIT_SETP_AUTO_SOF ); // USB总线复位,允许SOF
}
void HostSetBusReset( void ) // USB总线复位
{
UsbDevEndpSize = DEFAULT_ENDP0_SIZE; /* USB设备的端点0的最大包尺寸 */
SetHostUsbAddr( 0x00 );
Write374Byte( REG_USB_H_CTRL, 0x00 );
// Write374Byte( REG_USB_SETUP, M_SET_USB_BUS_RESET( Read374Byte( REG_USB_SETUP ) & ~ BIT_SETP_AUTO_SOF ) ); // USB总线复位
Write374Byte( REG_USB_SETUP, M_SET_USB_BUS_RESET( BIT_SETP_HOST_MODE ) ); // USB总线复位
mDelaymS( 20 ); // USB总线复位期间
// Write374Byte( REG_USB_SETUP, M_SET_USB_BUS_FREE( Read374Byte( REG_USB_SETUP ) ) ); // USB总线空闲
HostSetBusFree( ); // USB总线空闲
mDelaymS( 1 );
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_DEV_DETECT | BIT_IF_USB_SUSPEND ); // 清中断标志
}
void HostSetFullSpeed( void ) // 设定全速USB设备运行环境
{
Write374Byte( REG_USB_SETUP, Read374Byte( REG_USB_SETUP ) & ~ BIT_SETP_USB_SPEED | BIT_SETP_AUTO_SOF ); // 全速且发SOF
mDelaymS( 1 );
}
void HostSetLowSpeed( void ) // 设定低速USB设备运行环境
{
Write374Byte( REG_USB_SETUP, Read374Byte( REG_USB_SETUP ) | BIT_SETP_USB_SPEED | BIT_SETP_AUTO_SOF ); // 低速且发SOF
mDelaymS( 1 );
}
void Init374Host( void ) // 初始化USB主机
{
Write374Byte( REG_USB_SETUP, 0x00 );
SetHostUsbAddr( 0x00 );
Write374Byte( REG_USB_H_CTRL, 0x00 );
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清所有中断标志
// Write374Byte( REG_INTER_EN, BIT_IE_TRANSFER ); // 允许传输完成中断,因为本程序使用查询方式检测USB设备插拔,所以无需USB设备检测中断
Write374Byte( REG_INTER_EN, BIT_IE_TRANSFER | BIT_IE_DEV_DETECT ); // 允许传输完成中断和USB设备检测中断
Write374Byte( REG_SYS_CTRL, BIT_CTRL_OE_POLAR ); // 对于CH374T或者UEN引脚悬空的CH374S必须置BIT_CTRL_OE_POLAR为1
HostSetBusFree( ); // USB总线空闲
}
UINT8 GetDeviceDescr( PUINT8 buf ) // 获取设备描述符
{
UINT8 s, len;
s = HostCtrlTransfer374( SetupGetDevDescr, buf, &len ); // 执行控制传输
if ( s == USB_INT_SUCCESS ) {
UsbDevEndpSize = ( (PUSB_DEV_DESCR)buf ) -> bMaxPacketSize0; // 端点0最大包长度,这是简化处理,正常应该先获取前8字节后立即更新UsbDevEndpSize再继续
if ( len < ( (PUSB_SETUP_REQ)SetupGetDevDescr ) -> wLengthL ) s = USB_INT_BUF_OVER; // 描述符长度错误
}
return( s );
}
UINT8 GetConfigDescr( PUINT8 buf ) // 获取配置描述符
{
UINT8 s, len;
UINT8 BufLogDescr[ sizeof( SetupGetCfgDescr ) ] ;
s = HostCtrlTransfer374( SetupGetCfgDescr, buf, &len ); // 执行控制传输
if ( s == USB_INT_SUCCESS ) {
if ( len < ( (PUSB_SETUP_REQ)SetupGetCfgDescr ) -> wLengthL ) s = USB_INT_BUF_OVER; // 返回长度错误
else {
memcpy ( BufLogDescr, SetupGetCfgDescr, sizeof( SetupGetCfgDescr ) );
( (PUSB_SETUP_REQ)BufLogDescr ) -> wLengthL = ( (PUSB_CFG_DESCR)buf ) -> wTotalLengthL; // 完整配置描述符的总长度
s = HostCtrlTransfer374( BufLogDescr, buf, &len ); // 执行控制传输
if ( s == USB_INT_SUCCESS ) {
if ( len < ( (PUSB_CFG_DESCR)buf ) -> wTotalLengthL ) s = USB_INT_BUF_OVER; // 描述符长度错误
}
}
}
return( s );
}
UINT8 SetUsbAddress( UINT8 addr ) // 设置USB设备地址
{
UINT8 s;
UINT8 BufSetAddr[ sizeof( SetupSetUsbAddr ) ] ;
memcpy ( BufSetAddr, SetupSetUsbAddr, sizeof( SetupSetUsbAddr ) );
( (PUSB_SETUP_REQ)BufSetAddr ) -> wValueL = addr; // USB设备地址
s = HostCtrlTransfer374( BufSetAddr, NULL, NULL ); // 执行控制传输
if ( s == USB_INT_SUCCESS ) {
SetHostUsbAddr( addr ); // 设置USB主机当前操作的USB设备地址
}
mDelaymS( 3 ); // 等待USB设备完成操作
return( s );
}
UINT8 SetUsbConfig( UINT8 cfg ) // 设置USB设备配置
{
UINT8 BufSetCfg[ sizeof( SetupSetUsbConfig ) ] ;
memcpy ( BufSetCfg, SetupSetUsbConfig, sizeof( SetupSetUsbConfig ) );
( (PUSB_SETUP_REQ)BufSetCfg ) -> wValueL = cfg; // USB设备配置
return( HostCtrlTransfer374( BufSetCfg, NULL, NULL ) ); // 执行控制传输
}
/* 为printf和getkey输入输出初始化串口 */
void mInitSTDIO( )
{
SCON = 0x50;
PCON = 0x80;
TL2 = RCAP2L = 0 - 13; /* 24MHz晶振, 57600bps */
TH2 = RCAP2H = 0xFF;
T2CON = 0x34; /* 定时器2用于串口的波特率发生器 */
TI = 1;
}
int main( void ) // USB host
{
UINT8 i, s;
UINT8 idata buf[64];
// 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( 50 );
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( "%02X ", (UINT16)( buf[i] ) );
printf( "\n" );
printf( "SetUsbAddress: " );
s = SetUsbAddress( 0x02 ); // 设置USB设备地址
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 终止操作,等待USB设备拔出
}
printf( "\n" );
printf( "GetConfigDescr: " );
s = GetConfigDescr( buf ); // 获取配置描述符
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 终止操作,等待USB设备拔出
}
for ( i = 0; i < ( (PUSB_CFG_DESCR)buf ) -> wTotalLengthL; i ++ ) printf( "%02X ", (UINT16)( buf[i] ) );
printf( "\n" );
/* 分析配置描述符,获取端点数据/各端点地址/各端点大小等,更新变量endp_addr和endp_size等 */
printf( "SetUsbConfig: " );
s = SetUsbConfig( ( (PUSB_CFG_DESCR)buf ) -> bConfigurationValue ); // 设置USB设备配置
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 终止操作,等待USB设备拔出
}
printf( "\n" );
printf( "USB device ready now\n" );
/* do something, read/write ...
len = out_endp_size;
Write374Block( RAM_HOST_TRAN, len, buf );
Write374Byte( REG_USB_LENGTH, len );
s = WaitHostTransact374( out_endp_addr, DEF_USB_PID_OUT, FALSE, 1000 );
s = WaitHostTransact374( in_endp_addr, DEF_USB_PID_IN, FALSE, 1000 );
len = Read374Byte( REG_USB_LENGTH );
Read374Block( RAM_HOST_RECV, len, buf );
len = out_endp_size;
Write374Block( RAM_HOST_TRAN, len, buf );
Write374Byte( REG_USB_LENGTH, len );
s = WaitHostTransact374( out_endp_addr, DEF_USB_PID_OUT, TRUE, 1000 );
s = WaitHostTransact374( in_endp_addr, DEF_USB_PID_IN, TRUE, 1000 );
len = Read374Byte( REG_USB_LENGTH );
Read374Block( RAM_HOST_RECV, len, buf );
*/
printf( "do something, read / write ......\n" );
WaitDeviceOut: // 等待USB设备拔出
printf( "Wait Device Out\n" );
while ( 1 ) {
if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主机中断则处理
if ( Query374DeviceIn( ) == FALSE ) break; // 没有USB设备
}
mDelaymS( 100 ); // 等待设备完全断开,消除插拔抖动
if ( Query374DeviceIn( ) ) goto WaitDeviceOut; // 没有完全断开
// HostSetBusFree( ); // 设定USB主机空闲,主要目的是关闭SOF
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -