现在打算用CH554G做一个转接板,需要驱动XR21V1410芯片,找了倒程只有PL2302,CH340,CP2012的,不知道XR21V1410如何设置串口参数,是否可以提供解决方法?怎么组SETUP包,应该按什么样的顺序发送SETUP包?
如果是通过USB通讯的话,可以先接入电脑,通过电脑端USB抓包工具看一下操作流程。然后单片机模拟这个流程操作USB设备。
有没有什么文档可以说明这个过程如何分析操作的?现在用Bus Hound 抓包也不会看,有点头大
自己搞定了,因为自己的需求很简单,就是透传USB口和串口的数据,9600的波特率,停止位-1,奇偶校验-无,数据位-8。
还是看芯片的规格书,不需要插电脑上用USB数据抓包,用的原厂的例程,然后找到芯片的PID,VID,再按着例程的驱动CH340的方式来写匹配PID,VID,匹配上了后设置波特率,根据规格书来组SETUP包,其中发SETUP包的时候,刚开始用FOR循环发会有问题,后面改成一条条好就可以,花了很多时间来了解USB的相关内容,其实例程已经做好了很多前面的工作,只要自己组SETUP包,然后发送就可以正常运行起来了。参考了这个文章的思路http://www.wch.cn/bbs/thread-72287-1.html
下面是程序改动的地方:
USBHOST_IF.C文件
#define XR21V1410_VENDOR_ID0X04E2 //ADD by sean增加VID
#define XR21V1410_PRODUCT_ID 0X1410 //ADD by sean增加PID
const UINT16 XR21V1410_ID_Table[]={XR21V1410_VENDOR_ID,XR21V1410_PRODUCT_ID,}; //ADD by sean 增加表
//配置XR21V1410波特率 ,成功返回0
UINT8 XR21V1410_Baud_Config(UINT32 baud)
{
UINT8 s=0;
//UINT16 i=0,j=0;
/*UINT8 XR21V1410_Setup_Packet[32]=
{
0x40,0x00,0x10,0x00,0X01,0x04,0x00,0x00,//FIFO_ENABLE = 0x1 // Enable TX FIFO
0x40,0x00,0x03,0x00,0X03,0x00,0x00,0x00,//UART_ENABLE = 0x3 // Enable TX and RX of that channel
0x40,0x00,0x10,0x00,0X03,0x04,0x00,0x00,//FIFO_ENABLE = 0x3 // Enable RX FIFO
0x40,0x00,0x03,0x00,0X03,0x00,0x00,0x00,//使能TX,RX
//0x40,0x00,0x04,0x00,0x88,0x00,0x00,0x00,//波特率时钟除数0
//0x40,0x00,0x05,0x00,0x13,0x00,0x00,0x00,//波特率时钟除数1
//0x40,0x00,0x06,0x00,0x00,0x00,0x00,0x00,//波特率时钟除数2
//0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x00,//波特率时钟余数TX查找表的索0
//0x40,0x00,0x08,0x00,0x00,0x00,0x00,0x00,//波特率时钟余数TX查找表的索1
//0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x00,//波特率时钟余数RX查找表的索0
//0x40,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,//波特率时钟余数RX查找表的索1
//0x40,0x00,0x0B,0x00,0x08,0x00,0x00,0x00 //停止位-1,奇偶校验-无,数据位-8
};*/
#if DE_PRINTF
printf( "XR21V1410_Baud_Config START by sean\n " ); //测试是否程序运行到此处 by sean
printf("ThisUsbDev815.GpVar0=x%02X \n",(UINT16)(ThisUsbDev.GpVar0)); // 可能是断开了
printf("ThisUsbDev816.GpVar1=x%02X \n",(UINT16)(ThisUsbDev.GpVar1)); // 可能是断开了
printf("ThisUsbDev817.GpVar2=x%02X \n",(UINT16)(ThisUsbDev.GpVar2)); // 可能是断开了
#endif
/*while(j<32)
{
for(i=0;i<8;++i)
{
TxBuffer[i]=XR21V1410_Setup_Packet[j];
++j;
#if DE_PRINTF
printf( "TxBuffer[%d]=x%02X \n", j,(UINT16)( TxBuffer[i] ) ); //测试是否程序运行到此处 by sean
#endif
}
i = 0;
s = HostCtrlTransfer( NULL, NULL );
}
*/
//0x40,0x00,0x10,0x00,0X01,0x04,0x00,0x00,//FIFO_ENABLE = 0x1 // Enable TX FIFO
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x10;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x01;
TxBuffer[5] = 0x04;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x03,0x00,0X03,0x00,0x00,0x00,//UART_ENABLE = 0x3 // Enable TX and RX of that channel
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x03;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x03;
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x10,0x00,0X03,0x04,0x00,0x00,//FIFO_ENABLE = 0x3 // Enable RX FIFO
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x10;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0X03;
TxBuffer[5] = 0x04;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x03,0x00,0X03,0x00,0x00,0x00,//使能TX,RX
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x03;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x03;
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x04,0x00,0x88,0x00,0x00,0x00,//波特率时钟除数0
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x04;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x88;
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x05,0x00,0x13,0x00,0x00,0x00,//波特率时钟除数1
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x05;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x13;
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x06,0x00,0x00,0x00,0x00,0x00,//波特率时钟除数2
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x06;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x00;
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x00,//波特率时钟余数TX查找表的索0
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x07;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x00;
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x08,0x00,0x00,0x00,0x00,0x00,//波特率时钟余数TX查找表的索1
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x08;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x00;
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x00,//波特率时钟余数RX查找表的索0
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x09;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x00;
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,//波特率时钟余数RX查找表的索1
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x0A;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x00;
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
//0x40,0x00,0x0B,0x00,0x08,0x00,0x00,0x00 //停止位-1,奇偶校验-无,数据位-8
TxBuffer[0] = 0x40;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x0B;
TxBuffer[3] = 0x00;
TxBuffer[4] = 0x08;
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0x00;
s = HostCtrlTransfer( NULL, NULL );
#if DE_PRINTF
printf( "XR21V1410_Baud_Config END by sean\n " ); //测试是否程序运行到此处 by sean
printf("ThisUsbDev832.GpVar0=x%02X \n",(UINT16)(ThisUsbDev.GpVar0)); // 可能是断开了
printf("ThisUsbDev833.GpVar1=x%02X \n",(UINT16)(ThisUsbDev.GpVar1)); // 可能是断开了
printf("ThisUsbDev834.GpVar2=x%02X \n",(UINT16)(ThisUsbDev.GpVar2)); // 可能是断开了
#endif
return( s );
}
InitRootDevice函数匹配芯片PID,VID,进行波特率设置
if( MatchID(dev_vid,dev_pid,XR21V1410_ID_Table,sizeof(XR21V1410_ID_Table)/sizeof(UINT16)) ) //XR21V1410 //ADD by sean
{
ThisUsbDev.DeviceType = DEV_TYPE_XR21V1410;
//初始化波特率参数(类命令)
s = XR21V1410_Baud_Config(Comm_Baud);
if(s==ERR_SUCCESS)
{
ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS; //设备初始化成功
return ERR_SUCCESS;
}
}
DEBUG.C
#define DE_PRINTF 1 //打开调试信息 by sean
main.c
//#pragma NOAREGS //屏蔽编程命令 by sean
/* //屏蔽 dataflash读取设置参数功能 by sean
//ReadDataFlash(0,4,(UINT8 *)&Comm_Baud); //屏蔽从dataflash读取参数,并配置 功能 by sean
Comm_Baud = 9600; //手动设置波特率为9600 by sean
寄存器说明REGISTER NAME0x40 XR_SET_REG0val address0registerblock00寄存器值功能UART管理器寄存器 启用寄存器描述(读/写)Enable TX FIFO0x400x000x100x000X010x040x000x00FIFO_ENABLE = 0x1 // Enable TX FIFO
Enable TX and RX0x400x000x030x000X030x000x000x00UART_ENABLE = 0x3 // Enable TX and RX of that channel
Enable RX FIFO0x400x000x100x000X030x040x000x00FIFO_ENABLE = 0x3 // Enable RX FIFOUART寄存器 启用寄存器描述(读/写)Enable UART TX RX0x400x000x030x000X030x000x000x00使能TX.RX时钟除数0寄存器描述(读/写) 48000000 / Baud RateCLOCK_DIVISOR00x400x000x040x000x880x000x000x00波特率115200=416,波特率9600=5000,?10001000?时钟除数1寄存器描述CLOCK_DIVISOR10x400x000x050x000x130x000x000x0000010011时钟除数2寄存器描述CLOCK_DIVISOR20x400x000x060x000x000x000x000x0000000000( ( ( 48000000 / Baud Rate ) - CLOCK_DIVISOR ) * 32)TX_CLOCK_MASK00x400x000x070x000x000x000x000x00((48000000/9600)-5000)*32=0TX时钟索引(读/写)TX_CLOCK_MASK10x400x000x080x000x000x000x000x00((48000000/9600)-5000)*32=0RX时钟屏蔽寄存器的波特率RX_CLOCK_MASK00x400x000x090x000x000x000x000x00((48000000/9600)-5000)*32=0
RX_CLOCK_MASK10x400x000x0A0x000x000x000x000x00((48000000/9600)-5000)*32=0[7]:停止位选择;[6:4]:奇偶校验模式选择;[3:0]:数据位CHARACTER_FORMAT0x400x000x0B0x000x080x000x000x00停止位-1,奇偶校验-无,数据位-8,00001000
规格书就是看下面的内容,XR_SET_REG 0x04的设置命令