CH554G如何驱动XR21V1410芯片?

现在打算用CH554G做一个转接板,需要驱动XR21V1410芯片,找了倒程只有PL2302,CH340,CP2012的,不知道XR21V1410如何设置串口参数,是否可以提供解决方法?怎么组SETUP包,应该按什么样的顺序发送SETUP包?

如果是通过USB通讯的话,可以先接入电脑,通过电脑端USB抓包工具看一下操作流程。然后单片机模拟这个流程操作USB设备。


有没有什么文档可以说明这个过程如何分析操作的?现在用Bus Hound 抓包也不会看,有点头大j_0064.gif


自己搞定了,因为自己的需求很简单,就是透传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的设置命令

image.png


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