[求助]CH375B外置固件设备模式下应该如何驱动?

CH375B外置固件模式下的中断如下: //*********************************************************

/* CH375初始化子程序 */ void CH375_Init( ) { unsigned char data; uint RD_Data,k; putstring("CH375_Init"); /* 设置USB工作模式, 必要操作 */

CH375_WriteCMD( CMD_SET_USB_MODE );

CH375_WriteDAT(0x01); /* 设置为使用外置固件的USB设备方式 */ for ( ; ; ) { /* 等待操作成功,通常需要等待10uS-20uS */ data=CH375_ReadDAT( ); USART_putchar(data); USART_putchar(0x0d); USART_putchar(0x0a); if (CH375_ReadDAT( )==CMD_RET_SUCCESS )

{ //USART_putchar(CH375_ReadDAT( )); putstring("mode ok"); break; } else {} putstring("mode error1"); data=CH375_ReadDAT( ); USART_putchar(data); putstring("mode error"); } for( k=100; k!=0; k-- ) { CH375_WriteCMD( CMD_CHECK_EXIST ); /* 测试CH375是否正常工作 */ CH375_WriteDAT( 0xAA ); /* 写入测试数据 */ RD_Data = CH375_ReadDAT(); if ( RD_Data == 0x55 ) { putstring("test ok"); break; } else { putstring("test error"); } } }

//*********************************************************

//********************************************************* //端点0数据上传 void mCh375Ep0Up() { uint i,len; putstring("mCh375Ep0Up"); USART_putchar(mVarSetupLength); USART_putchar(0x0d); USART_putchar(0x0a); if(mVarSetupLength) { //长度不为0传输具体长度的数据 if(mVarSetupLength<=8) { len=mVarSetupLength; mVarSetupLength=0; } //长度小于8则按实际要求的长度输出 else { len=8; mVarSetupLength-=8; } //长度大于8则传输8个,切总长度减8 CH375_WriteCMD(CMD_WR_USB_DATA3); //发出写端点0的命令 CH375_WriteDAT(len); //写入长度 for(i=0;i!=len;i++) { //LED_1S(1); CH375_WriteDAT(request.buffer[i]); USART_putchar(request.buffer[i]); } //循环写入数据 USART_putchar(0x0d); USART_putchar(0x0a); //putstring("shangchuan"); } else { CH375_WriteCMD(CMD_WR_USB_DATA3); //发出写端点0的命令 CH375_WriteDAT(0); //上传0长度数据,这是一个状态阶段 } }

//*********************************************************

//复制描述符以便上传 void mCh375DesUp() { uchar k; for (k=0; k!=8; k++ ) { //LED_1S(1); request.buffer[k]=*VarSetupDescr; //依次复制8个描述符, VarSetupDescr++; USART_putchar(request.buffer[k]); } USART_putchar(0x0d); USART_putchar(0x0a); putstring("mCh375DesUp"); }

//*********************************************************

/* CH375中断服务程序INT7 */ SIGNAL(SIG_INTERRUPT7) //否则用查询,修改熔丝位去掉103模式,对引脚设置成上拉电阻否则进中断就出不来了 { uchar InterruptStatus; uchar length, c1, len; uchar i; //uint a[16]; //uchar *pBuf; //uchar mBuf[64]; putstring("INT"); CH375_WriteCMD(CMD_GET_STATUS); InterruptStatus =CH375_ReadDAT(); USART_putchar(InterruptStatus); USART_putchar(0x0d); USART_putchar(0x0a); switch(InterruptStatus) { // 分析中断状态 case USB_INT_EP2_OUT: // 批量端点下传成功 CH375_WriteCMD(CMD_UNLOCK_USB); putstring("EP2 IN"); break; case USB_INT_EP2_IN: //批量端点上传成功 CH375_WriteCMD(CMD_UNLOCK_USB); //释放缓冲区 putstring("EP2 IN"); break; case USB_INT_EP1_IN: //中断端点上传成功,未处理 CH375_WriteCMD(CMD_UNLOCK_USB); //释放缓冲区 putstring("EP1 IN"); break; case USB_INT_EP1_OUT: //中断端点下传成功 CH375_WriteCMD(CMD_RD_USB_DATA); //发出读数据命令 if( length = CH375_ReadDAT( ) ) { //长度为0跳出 for(len=0;len!=length;len++) c1=CH375_ReadDAT(); //取出下传数据 } //CH375_WriteCMD(CMD_UNLOCK_USB); //释放缓冲区,如果前面没有CMD_RD_USB_DATA命令则使用本命令 putstring("EP1 OUT"); break; case USB_INT_EP0_SETUP: //控制端点建立成功 CH375_WriteCMD(CMD_RD_USB_DATA); length=CH375_ReadDAT(); USART_putchar(length); USART_putchar(0x0d); USART_putchar(0x0a); for(len=0;len!=length;len++) request.buffer[len]=CH375_ReadDAT(); // 取出数据 //USART_putchar(0x55); //for(i=0;i //USART_putchar(length); //USART_putchar(0x55); //USART_putchar(0x0d); //USART_putchar(0x0a); if(length==0x08)//if(length==0x08) { mVarSetupLength=request.buffer[6]&0x7f; //控制传输数据长度最大设置为128 if((c1=request.r.bmReuestType)&0x40) //厂商请求,未处理 { } if((c1=request.r.bmReuestType)&0x20)//类请求,未处理 { if(request.buffer[1]==0x0a) { } //SET_IDLE else if(request.buffer[1]==0x09) { UPDATA_FLAG=1; } } if(!((c1=request.r.bmReuestType)&0x60))//标准请求 { mVarSetupRequest=request.r.bRequest; //暂存标准请求码 USART_putchar(request.r.bRequest); USART_putchar(0x0d); USART_putchar(0x0a); switch(request.r.bRequest) { // 分析标准请求 case DEF_USB_CLR_FEATURE: //清除特性 if((c1=request.r.bmReuestType&0x1F)==0X02)//是端点执行线面的语句 { //不是端点不支持 USART_putchar(request.buffer[4]); USART_putchar(0x0d); USART_putchar(0x0a); switch(request.buffer[4]) { case 0x82: CH375_WriteCMD(CMD_SET_ENDP7); //清除端点2上传 CH375_WriteDAT(0x8E); //发命令清除端点 break; case 0x02: CH375_WriteCMD(CMD_SET_ENDP6); CH375_WriteDAT(0x80); //清除端点2下传 break; case 0x81: CH375_WriteCMD(CMD_SET_ENDP5); //清除端点1上传 CH375_WriteDAT(0x8E); break; case 0x01: CH375_WriteCMD(CMD_SET_ENDP4); //清除端点1下传 CH375_WriteDAT(0x80); break; default: break; } } else { CH375FLAGERR=1; //不支持的清除特性,置错误标志 } putstring("CLR FEATURE"); break; case DEF_USB_GET_STATUS: //获得状态 request.buffer[0]=0; request.buffer[1]=0; //上传状态 putstring("GET STATUS"); break; case DEF_USB_SET_ADDRESS: //设置地址 VarUsbAddress=request.buffer[2]; //暂存USB主机发来的地址 putstring("SET ADDRESS"); break; case DEF_USB_GET_DESCR: //获得描述符 USART_putchar(request.buffer[3]); USART_putchar(0x0d); USART_putchar(0x0a); if(request.buffer[3]==1) //设备描述符上传 VarSetupDescr=DevDes; else if(request.buffer[3]==2) //配置描述符上传 VarSetupDescr=ConDes; else if(request.buffer[3]==3) { //if ( request.buffer[2]== 0 ) VarSetupDescr=LangDes; //else VarSetupDescr=SerDes; //做字符串处理 } else if(request.buffer[3]==0x22) { VarSetupDescr=Hid_des; //报表描述符上传 } mCh375DesUp(); //其余描述符不支持 putstring("GET DESCR"); break; case DEF_USB_GET_CONFIG: //获得配置 request.buffer[0]=0; //没有配置则传0 if(CH375CONFLAG) request.buffer[0]=1; //已经配置则传1;这是在描述符里规定的 putstring("GET CONFIG"); break; case DEF_USB_SET_CONFIG: //设置配置 CH375CONFLAG=0;

if ( request.buffer[2] != 0 ) { CH375CONFLAG=1; //设置配置标志 } putstring("SET CONFIG"); break; case DEF_USB_GET_INTERF: //得到接口 request.buffer[0]=1; //上传接口数,本事例只支持一个接口 putstring("GET INTERF"); break; default : putstring("default"); CH375FLAGERR=1; //不支持的标准请求 break; } } } else { //不支持的控制传输,不是8字节的控制传输 CH375FLAGERR=1; } putstring("mch"); if(!CH375FLAGERR) mCh375Ep0Up(); //没有错误/调用数据上传,,长度为0上传为状态 el

这个是你的软件上面没有正确的返回设备描述符.你看下计算机问你要了几次描述符?正常的应该先是获取设备描述符,然后设置地址,接着总线复位,在获取设备描述符,获取配置描述符,最后设置配置.完成每局过程.


谢谢你,我现在应该是在EP0 SETUP中上传的设备描述符的前8个字节,然后在EP0 IN中上传了设备描述符的后8个字节,然后设置地址,总线复位,又上传了设备描述符,设置地址。 按照你的说法我应该是在第二次上传描述符后上传配置描述符,再配置设置的。 我怀疑是第一次从上传描述符到设置地址中有哪一步不成功,导致它又进行了一次,还是没成功。结果就停了。


那你去跟踪程序运行到哪个步骤出现问题.


只有登录才能回复,可以选择微信账号登录