?? 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 + -