📄 ch375_host_int_para.c
字号:
issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();
if(status==USB_INT_SUCCESS)/* SETUP阶段操作成功 */
{ toggle_send();
Request.Req_buf[0]=0x01;
wr_usb_data(1,Request.Req_buf);
issue_token(( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
if(status==USB_INT_SUCCESS) /* DATA阶段操作成功 */
{ endp6_mode=0xc0;
toggle_recv();
issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
if(status==USB_INT_SUCCESS)/* 状态阶段操作成功 */
{ if(rd_usb_data(data_buf)!=0)
return(0);
}
else return(0);
}
else return(0);
}
else return(0);
return(1);
}
unsigned char get_descr_ex()
{ unsigned char descr_len;
unsigned char *p=data_buf;
endp7_mode=0x80;
toggle_send();
wr_usb_data(8,Request.Req_buf);
issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();
if(status==USB_INT_SUCCESS)/* SETUP阶段操作成功 */
{ endp6_mode=0xc0;
toggle_recv();
}
else return(0);
issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
if(status==USB_INT_SUCCESS)/* DATA阶段操作成功 */
{ if(flag_config_2)descr_len=data_buf[2]-rd_usb_data(data_buf);
else descr_len=data_buf[0]-rd_usb_data(data_buf);
while(descr_len>0)
{ toggle_recv();
p+=0x08;
issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
if(status==USB_INT_SUCCESS) /* DATA阶段操作成功 */
descr_len-=rd_usb_data(p);
else return(0);
}
}
else return(0);
endp7_mode=0xc0;
toggle_send();
wr_usb_data(0,Request.Req_buf);
issue_token(( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
if(status==USB_INT_SUCCESS)/* 状态阶段操作成功 */
return(1);
else return(0);
}
unsigned char get_report_descr_ex()
{ unsigned char descr_len;
unsigned char *p=data_buf;
unsigned char report_cou_temp=0;
report_cou=0;
endp7_mode=0x80;
toggle_send();
wr_usb_data(8,Request.Req_buf);
issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();
if(status==USB_INT_SUCCESS)/* SETUP阶段操作成功 */
{ endp6_mode=0xc0;
toggle_recv();
}
else return(0);
issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
if(status==USB_INT_SUCCESS)/* DATA阶段操作成功 */
{ rd_usb_data(data_buf);
report_cou+=8;
descr_len=Request.Req_buf[6]-0x08;/*剩余描述符长度计算*/
while(descr_len>0)
{ toggle_recv();
p+=0x08;
issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
if(status==USB_INT_SUCCESS) /* DATA阶段操作成功 */
{ report_cou_temp=rd_usb_data(p);
if(report_cou_temp!=0x08){report_cou+=report_cou_temp;break;}
else {descr_len-=0x08;report_cou+=8;}
}
else return(0);
}
}
else return(0);
endp7_mode=0xc0;
toggle_send();
wr_usb_data(0,Request.Req_buf);
issue_token(( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
if(status==USB_INT_SUCCESS)/* 状态阶段操作成功 */
return(1);
else return(0);
}
void get_int_in()
{ endp6_mode=0x80;
toggle_recv();
issue_token(( endp_int << 4 ) | DEF_USB_PID_IN);//status=wait_interrupt();
}
void reset_device()
{
/* USB规范中未要求在USB设备插入后必须复位该设备,但是计算机的WINDOWS总是这样做,所以有些USB设备也要求在插入后必须先复位才能工作 */
set_usb_mode( 7 ); /* 复位USB设备,CH375向USB信号线的D+和D-输出低电平 */
delayms(10);
set_usb_mode( 6 ); /* 结束复位 */
while ( wait_interrupt()!=USB_INT_CONNECT ); /* 等待复位之后的设备端再次连接上来 */
}
unsigned char get_descr( unsigned char type ) { /* 从设备端获取描述符 */
status=0xff;
CH375_WR_CMD_PORT( CMD_GET_DESCR );
CH375_WR_DAT_PORT( type ); /* 描述符类型, 只支持1(设备)或者2(配置) */
status=wait_interrupt(); /* 等待CH375操作完成 */
if ( status==USB_INT_SUCCESS ) { /* 操作成功 */
unsigned char i, len;
len=rd_usb_data( data_buf );
printf( "%s描述符是:", type==1?"设备":"配置" );
for ( i=0; i!=len; i++ ) printf( "%02x ", (unsigned int)data_buf[i] );
printf( "\n" );
}
return( status );
}
unsigned char set_addr( unsigned char addr ) { /* 设置设备端的USB地址 */
unsigned char status;
CH375_WR_CMD_PORT( CMD_SET_ADDRESS ); /* 设置USB设备端的USB地址 */
CH375_WR_DAT_PORT( addr ); /* 地址, 从1到127之间的任意值, 常用2到20 */
status=wait_interrupt(); /* 等待CH375操作完成 */
if ( status==USB_INT_SUCCESS ) { /* 操作成功 */
CH375_WR_CMD_PORT( CMD_SET_USB_ADDR ); /* 设置USB主机端的USB地址 */
CH375_WR_DAT_PORT( addr ); /* 当目标USB设备的地址成功修改后,应该同步修改主机端的USB地址 */
}
return( status );
}
unsigned char set_config( unsigned char cfg ) { /* 设置设备端的USB配置 */
CH375_WR_CMD_PORT( CMD_SET_CONFIG ); /* 设置USB设备端的配置值 */
CH375_WR_DAT_PORT( cfg ); /* 此值取自USB设备的配置描述符中 */
return( wait_interrupt() ); /* 等待CH375操作完成 */
}
void parse_config_descr()
{ unsigned char i;
num_interfaces=data_buf[4]; //保存接口数
config_value=data_buf[5]; //保存配置值
for(i=0;i!=data_buf[2];i++)
{ if((data_buf[i]==0x09)&&(data_buf[i+1]==0x04))//接口描述符
{ }
if((data_buf[i]==0x09)&&(data_buf[i+1]==0x21))//HID描述符
{ report_descr_len=data_buf[i+7];} //REPORT描述符长度
if((data_buf[i]==0x07)&&(data_buf[i+1]==0x05))//端点描述符
{ endp_int=data_buf[i+2]&0x0f;} //中断端点号
}
}
void main() {
unsigned char i;
mInitSTDIO( );
delayms(250);
set_usb_mode( 6 ); /* 设置USB主机模式, 如果设备端是CH37X, 那么5和6均可 */
#ifdef TEST_LOW_SPEED
set_freq( ); //使375B进入低速模式
#endif
while(1)
{ while ( wait_interrupt()!=USB_INT_CONNECT ); /* 等待设备端连接上来 */
delayms(5);
reset_device();
delayms(5);
set_freq( ); //使375B进入低速模式
// get_descr(0x01);//获取设备描述符
// printf("device\n");
Request.Req.bmRequestType=0x80;
Request.Req.bRequest=0x06;
Request.Req.wValue=0x0001;
Request.Req.wIndex=0x0000;
Request.Req.wLength=0x1200;
if(get_descr_ex()==1)
{ for(i=0;i!=data_buf[0];i++)
printf("%02x ",(unsigned int)data_buf[i]);
printf("\n");
}
else printf("get device descr failed\n");
set_addr(5);//设置地址
// get_descr(0x02);//获取配置描述符
printf("config\n");
Request.Req.bmRequestType=0x80;
Request.Req.bRequest=0x06;
Request.Req.wValue=0x0002;
Request.Req.wIndex=0x0000;
Request.Req.wLength=0x0900;
if(get_descr_ex()==1)
{ for(i=0;i!=data_buf[0];i++)
printf("%02x ",(unsigned int)data_buf[i]);
printf("\n");
if(data_buf[4]!=0x01)flag_interface_2=1;//有多个接口
}
else printf("get config descr failed\n");
printf("config 2\n");
if(data_buf[2]>0x09)
{ flag_config_2=1;
Request.Req.bmRequestType=0x80;
Request.Req.bRequest=0x06;
Request.Req.wValue=0x0002;
Request.Req.wIndex=0x0000;
Request.Req.wLength=0x0000|((unsigned int)data_buf[2]<<8);
if(get_descr_ex()==1)
{ for(i=0;i!=data_buf[2];i++)
printf("%02x ",(unsigned int)data_buf[i]);
printf("\n");
flag_config_2=0;
}
else printf("get device descr again failed\n");
}
parse_config_descr();//保存描述符中一些值
set_config(config_value);//设置配置
// printf("set config\n");
// if(set_config_ex()!=1)printf("set config failed\n");
printf("set idle\n");
if(set_idle()!=1)printf("set idle failed\n");
printf("report\n");
Request.Req.bmRequestType=0x81;
Request.Req.bRequest=0x06;
Request.Req.wValue=0x0022;
Request.Req.wIndex=0x0000;
Request.Req.wLength=0x0000|((unsigned int)(report_descr_len+0x40)<<8);
if(get_report_descr_ex()==1)
{ for(i=0;i!=report_cou;i++)
printf("%02x ",(unsigned int)data_buf[i]);
printf("\n");
}
else printf("get report descr failed\n");
printf("set report\n"); //对于键盘这一步,是点亮指示灯
if(set_report()!=1)printf("set report failed\n");
delayms(250);
EA=1; //打开中断,从中断端点接收数据
get_int_in(); //发送从中断端点读数据的令牌
do{
if(flag_output==1)
{ for(i=0;i!=8;i++)printf("%02x ",(unsigned int)data_in[i]);
printf("\n");
flag_output=0;
}
}while(1);
while ( wait_interrupt()!=USB_INT_DISCONNECT ); /* 等待设备端连接上来 */
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -