ch375B外置固件模式问题

我的调试信息如下: ============================================================================= 测试CH375工作状态:0xED 芯片ID:0xB7 有中断产生,中断状态为:0x07 USB复位 有中断产生,中断状态为:0x07 USB复位 有中断产生,中断状态为:0x07 USB复位 有中断产生,中断状态为:0x07 USB复位 有中断产生,中断状态为:0x07 USB复位 有中断产生,中断状态为:0x0C 端点0接收Setup包成功 0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00 标准请求输入--获取描述符 设备描述符 有中断产生,中断状态为:0x08 端点0写入数据成功0x0A 有中断产生,中断状态为:0x00 端点0接收Setup包成功

标准请求输入--获取描述符 设备描述符 有中断产生,中断状态为:0x08 端点0写入数据成功0x0A 有中断产生,中断状态为:0x07 USB复位 有中断产生,中断状态为:0x07 USB复位 有中断产生,中断状态为:0x0C 端点0接收Setup包成功 0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00 标准请求输入--获取描述符 设备描述符 有中断产生,中断状态为:0x08 端点0写入数据成功0x0A 有中断产生,中断状态为:0x00 端点0接收Setup包成功

标准请求输入--获取描述符 设备描述符 有中断产生,中断状态为:0x00 端点0接收Setup包成功 0x00 0x05 0x01 0x00 0x00 0x00 0x00 0x00 标准输出请求--设置地址 有中断产生,中断状态为:0x0C 端点0接收Setup包成功

标准输出请求--设置地址 有中断产生,中断状态为:0x07 USB复位 有中断产生,中断状态为:0x07 USB复位 有中断产生,中断状态为:0x0C 端点0接收Setup包成功 0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00 标准请求输入--获取描述符 设备描述符 有中断产生,中断状态为:0x08 端点0写入数据成功0x0A 有中断产生,中断状态为:0x00 端点0接收Setup包成功

标准请求输入--获取描述符 设备描述符 有中断产生,中断状态为:0x00 端点0接收Setup包成功 0x00 0x05 0x01 0x00 0x00 0x00 0x00 0x00 标准输出请求--设置地址 有中断产生,中断状态为:0x0C 端点0接收Setup包成功

标准输出请求--设置地址 =============================================================================

我现在遇到的问题是:1.能收到pc发送的获取设备描述符命令 即调试输出中的: 有中断产生,中断状态为:0x0C 端点0接收Setup包成功 0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00 标准请求输入--获取描述符 设备描述符 2.也成功返回了设备描述符的前8个字节 即调试输出中的: 有中断产生,中断状态为:0x08 端点0写入数据成功0x0A (这里0X0A表示发送8个字节后剩余字节数) 3.问题再这里: 这时产生了USB_INT_EP0_OUT中断 即调试输出中的: 有中断产生,中断状态为:0x00 按理说这时PC应将总线复位一次,然后发送设置地址命令的,不明白,问题会出在哪呢?

================================================================ 代码见2楼:mega16+ch375B+GCCAVR

#include "includes.h"

unsigned char Req_Buf[8];// /*设备描述符变量定义*/ unsigned char bmRequestType; unsigned char bRequest; unsigned int wValue; unsigned int wIndex; unsigned int wLength; /*数据传输控制变量*/ const unsigned char* pSendData;//当前发送数据的位置 unsigned int SendLength;//需要发送数据的长度 unsigned char NeedZeroPacket;//是否返回0长度数据包标志 unsigned char SendBuf[8];

/************************************************************************************ **函数功能:USB连接函数 **入口参数:无 **返 回:无 **备 注:无 ************************************************************************************/ void USB_Connect(void) { CH375_Write_Cmd(CMD_SET_USB_MODE); CH375_Write_Data(USB_MODE1); delay_10us(5); } //=================================================================================== /************************************************************************************ **函数功能:USB断开连接函数 **入口参数:无 **返 回:无 **备 注:无 ************************************************************************************/ void USB_Disconnect(void) { CH375_Write_Cmd(CMD_SET_USB_MODE); CH375_Write_Data(USB_MODE0); delay_10us(5); } //=================================================================================== /************************************************************************************ **函数功能:USB设备复位处理函数 **入口参数:无 **返 回:无 **备 注:对于任何一个CH375中断,必须唯一对应一个UNLOCK_USB命令或者RD_USB_DATA命令 ************************************************************************************/ void USB_Reset(void) { #ifdef DEBUG usartTransStr("USB复位"); usartTransStr("\r\n"); #endif CH375_Write_Cmd(CMD_UNLOCK_USB); } //=================================================================================== /************************************************************************************ **函数功能:USB接收建立包成功处理函数 **入口参数:无 **返 回:无 **备 注:无 ************************************************************************************/ void USB_Ep0_Setup(void) { unsigned char i; unsigned char Len; //pUSB_Req p = &Req_Buf; #ifdef DEBUG usartTransStr("端点0接收Setup包成功"); usartTransStr("\r\n"); #endif CH375_Write_Cmd(CMD_RD_USB_DATA); Len = CH375_Read_Data(); //接收到的数据长度 for(i=0; i { Req_Buf[i] = CH375_Read_Data(); #ifdef DEBUG usartTransHex(Req_Buf[i]); #endif } #ifdef DEBUG usartTransStr("\r\n"); #endif bmRequestType = Req_Buf[0]; bRequest = Req_Buf[1]; wValue = (((unsigned int)Req_Buf[3])<<8) + Req_Buf[2]; wIndex = (((unsigned int)Req_Buf[5])<<8) + Req_Buf[4]; wLength = (((unsigned int)Req_Buf[7])<<8) + Req_Buf[6];

if((bmRequestType&0x80) == 0x80) //设备到主机 { switch((bmRequestType>>5) & 0x03) { case 0: //标准请求 #ifdef DEBUG usartTransStr("标准请求输入--"); //usartTransStr("\r\n"); #endif switch(bRequest) { case GET_CONFIGURATION://获取配置 #ifdef DEBUG usartTransStr("获取配置"); usartTransStr("\r\n"); #endif break; case GET_DESCRIPTOR: //获取描述符 #ifdef DEBUG usartTransStr("获取描述符"); usartTransStr("\r\n"); #endif switch((wValue>>8) & 0xFF) { case DEVICE_DESCRIPTOR: //设备描述符 #ifdef DEBUG usartTransStr("设备描述符"); usartTransStr("\r\n"); #endif pSendData = &DeviceDescriptor[0]; if(wLength > 0x12) { SendLength = 0x12; } else { SendLength = wLength; } USB_Ep0_Send_Data(); break; case CONFIGURATION_DESCRIPTOR://配置描述符 #ifdef DEBUG usartTransStr("配置描述符"); usartTransStr("\r\n"); #endif break; case STRING_DESCRIPTOR: //字符串描述符 #ifdef DEBUG usartTransStr("字符串描述符"); usartTransStr("\r\n"); #endif break; default: //其他描述符 #ifdef DEBUG usartTransStr("其他描述符"); usartTransStr("\r\n"); #endif break; } break; case GET_INTERFACE: //获取接口 #ifdef DEBUG usartTransStr("获取接口"); usartTransStr("\r\n"); #endif break; case GET_STATUS: //获取状态 #ifdef DEBUG usartTransStr("获取状态"); usartTransStr("\r\n"); #endif break; case SYNCH_FRAME: //同步帧 #ifdef DEBUG usartTransStr("同步帧"); usartTransStr("\r\n"); #endif break; default: #ifdef DEBUG usartTransStr("未知"); usartTransStr("\r\n"); #endif break; } break; case 1: //类请求 #ifdef DEBUG usartTransStr("类请求输入--"); #endif break; case 2: //厂商请求 #ifdef DEBUG usartTransStr("厂商请求输入--"); #endif break; default: #ifdef DEBUG usartTransStr("未知请求输入--"); #endif break; } } else //主机到设备 { switch((bmRequestType>>5) & 0x03) { case 0: //标准输出请求 #ifdef DEBUG usartTransStr("标准输出请求--"); #endif switch(bRequest) { case CLEAR_FEATURE: //清除特性 #ifdef DEBUG usartTransStr("清除特性"); usartTransStr("\r\n"); #endif break; case SET_ADDRESS: //设置地址 #ifdef DEBUG usartTransStr("设置地址"); usartTransStr("\r\n"); #endif //CH375_Write_Cmd(CMD_SET_USB_ADDR); //CH375_Write_Data((unsigned char)wValue); break; case SET_CONFIGURATION: //设置配置 #ifdef DEBUG usartTransStr("设置配置"); usartTransStr("\r\n"); #endif break; case SET_DESCRIPTOR: //设置描述符 #ifdef DEBUG usartTransStr("设置描述符"); usartTransStr("\r\n"); #endif break; case SET_FEATURE: //设置特性 #ifdef DEBUG usartTransStr("设置特性"); usartTransStr("\r\n"); #endif break; case SET_INTERFACE: //设置接口 #ifdef DEBUG usartTransStr("设置接口"); usartTransStr("\r\n"); #endif break; default: //未知标准输出请求 #ifdef DEBUG usartTransStr("未知标准输出请求"); usartTransStr("\r\n"); #endif break; } break; case 1: //类输出请求 #ifdef DEBUG usartTransStr("类输出请求--"); #endif break; case 2: //厂商输出请求 #ifdef DEBUG usartTransStr("厂商输出请求--"); #endif break; default: //未知输出请求 #ifdef DEBUG usartTransStr("未知输出请求--"); #endif break; } } } //=================================================================================== /************************************************************************************ **函数功能:端点0输入中断处理函数 **入口参数:无 **返 回:无 **备 注:无 ************************************************************************************/ void USB_Ep0_In(void) { #ifdef DEBUG usartTransStr("端点0写入数据成功"); usartTransHex(SendLength); usartTransStr("\r\n"); #endif //CH375_Write_Cmd(CMD_UNLOCK_USB); //if(bRequest == GET_DESCRIPTOR) //{ // USB_Write_Ep0_Buff(); USB_Ep0_Send_Data(); //} //else if(bRequest == SET_ADDRESS) //{ // CH375_Write_Cmd(CMD_SET_USB_ADDR); // CH375_Write_Data(wValue); //} CH375_Write_Cmd(CMD_UNLOCK_USB); } //=================================================================================== /************************************************************************************ **函数功能:向端点0缓冲区写入数据函数 **入口参数:len-->写入数据长度 ** p---->数据缓冲区首地址 **返 回:无 **备 注:无 ************************************************************************************/

void USB_Write_Ep0_Buff(unsigned char len, const unsigned char* p) { unsigned char i;

CH375_Write_Cmd(CMD_WR_USB_DATA3); CH375_Write_Data(len); for(i=0; i { CH375_Write_Data(p[i]); } }

/* void USB_Write_Ep0_Buff(void) { unsigned char i;

for(i=0; i { SendBuf[i] = *pSendData; pSendData++; } } */ //===========================================================


按照道理来讲的话,你应该给计算机只返回设备描述符的前9个字节,或者只给计算机返回4个字节的描述符,因为你返回的是整包数据,计算机会认为你还有数据,这个时候你只需要在写一个非满包的数据通过端点0,这样的话,计算机就会给你总线复位,发送设置地址的命令的。


另外不要加这么多调试信息,这样会占用大量的时间,可能会导致计算机认为超时,这点务必注意。


貌似还是不对, ========================================================================== USB复位 USB复位 USB复位 USB复位 端点0接收Setup包成功 0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00 标准请求输入--获取描述符 设备描述符 端点0发送8字节数据成功 端点0收到数据成功 端点0收到数据成功 端点0收到数据成功 端点0接收Setup包成功 0x00 0x05 0x01 0x00 0x00 0x00 0x00 0x00 标准输出请求--设置地址 =============================================================================== 在我返回8字节的设备描述符后,pc又发送了0字节的数据包,我在USB_INT_EP0_OUT中断中返回0字节数据包, 这时USB_INT_EP0_OUT还是会触发2次,没有复位,就接收到设置地址的包 (另外,我不加调试信息的话也是一样的结果)


标准输出请求--设置地址 这一步需要做两个动作 1:设置CH375的地址 2:返回0长度的数据包 请参考我们提供的程序,你只要把硬件层接口写好,直接移植即可。 到在线下载里搜索CH372EVT.ZIP,找到XFIRM文件夹,就是MCU的参考程序。


thanks,我先看看


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