CH343PT库使用<二>USB转串口设备描述符配置


前言

支持EEPROM配置的USB转串口设备型号有很多包括:CH340B、CH342F(USB转双串)、CH343P、CH344L/Q(USB转4串)、CH347T、CH348L/Q(USB转8串口)、CH9101U/R/Y、CH9102F、CH9103M(USB转双串)、CH‘9104L(USB转4串口)等型号。下面将使用CH343PT库中的接口去配置USB转串口设备CH9102F的EERPOM中的厂商字符串、产品字符串和Serial 字符串。


一、配置EEPROM接口函数介绍

1.1 芯片功能信息结构体

//芯片功能信息结构
typedef struct _USBSER_Property
{
	UCHAR    ChipType;              //芯片型号,USER_TYPE_CHxxx	
	CHAR     ChipTypeStr[32];       //芯片型号字符串
	CHAR     FwVerStr[32];          //固件版本字符串
	UCHAR    GpioCount;             //GPIO脚数,如果大于0,此型号有专用GPIO脚或复用脚;为0表示芯片不支持GPIO引脚
	BOOL     IsEmbbedEeprom;        //是否内置EEPROM,如支持,可进行设备信息的配置	
	BOOL     IsSupportMcuBootCtrl;  //是否支持Modem引脚作为103 MCU下载控制
	CHAR     ManufacturerString[64];//USB描述符内厂商字符串
	CHAR     ProductString[64];     //USB描述符内产品字符串
	USHORT   bcdDevice;             //USB描述符内bcdDevice值
	UCHAR    PortIndex;             //单串为0,如多串则为芯片第几个号串口
	BOOL     IsSupportGPIOInit;     //是否支持GPIO上电初始化设置
	CHAR     PortName[32];          //串口号
	ULONG    ResvD[8];              //预留数据
}ChipPropertyS,*pChipPropertyS;

如果想过滤CH9102F,可以使用该结构体中ChipType去判断芯片是否是CH9102F。代码实现如下:

BOOL IsCH9102F(HANDLE hCom, pChipPropertyS ChipProperty)
{
	CH343PT_GetChipProperty(hCom, ChipProperty);
	if(ChipProperty->ChipType == USER_TYPE_CH9102F)
		return TRUE;
	else
		return FALSE;
}

使用该函数会打开关闭未占用的串口(COM端口),如果想避免打开串口,可以用友好名称中CH9102F去过滤,如下图所示。
在这里插入图片描述

1.2 USB串口芯片配置EEPROM结构体

//除CH340和CH341之外的所有USB串口芯片配置EEPROM
typedef struct _USERCFG_343
{
	UCHAR SIG;      //对于 CH340B:内部配置信息有效标志,必须是 5BH。
	//对于 CH340H/S:外部配置芯片有效标志,必须是 53H。
	//对于 CH343??:外部配置芯片有效标志,必须是 53H。
	//其它值则配置无效
	UCHAR MODE;     //串口模式,必须是23H
	UCHAR CFG;      //芯片功能配置字节
	//BIT7:USB设备序列号字符串控制位;1=有效;0=无效;
	//BIT6:USB产品信息字符串控制位;1=有效;0=无效;
	//BIT5:USB厂商信息字符串控制位;1=有效;0=无效;
	//BIT4:CDC模式下是否启用硬件流控;1=启用;0=禁止;
	//BIT3:芯片引脚是否启用EEPROM的默认配置;如果启用则芯片上电后会根据EEPROM中的配置初始化引脚方向及电平状态,以及使能状态。具体配置值见后面说明。 1=启用;0=禁止;
	UCHAR WP;       //内部配置信息写保护标志,为 57H 则只读,否则可改写
	UCHAR Vid[2];   //Vendor ID,厂商识别码,高字节在后,任意值。
	UCHAR Pid[2];   //Product ID,产品识别码,高字节在后,任意值
	UCHAR BCD[2];   //高字节在后,任意值
	UCHAR Power;    //Max Power,USB电流配置字,以2mA为单位的最大电源电流
	UCHAR Attributes;//	USB供电方式、睡眠唤醒等功能配置信息
	//BIT7:必须设置成1;
	//BIT6:1= Self-Powered;
	//0=Bus-Powered;
	//BIT5:1= Remote Wakeup Enable;
	//0= Remote Wakeup Disable;
	//BIT4-BIT0:必须设置成0;
	UCHAR Reserved[4]; //保留字节00H或FFH
	CHAR  SN[24];    //USB设备序列号字符串.首字节是全部字节数(不超过16H),次字节开始为标准的USB字符串描述符格式(第1个字节为总长度,第2个字节固定为03H,第3个字节开始奇数为Unicode字符,偶数为0x00),如果不符合上述特征则使用厂商默认说明。
	UCHAR PROD[40];  //USB产品信息字符串.首字节是全部字节数(不超过28H),次字节开始为标准的USB字符串描述符格式(第1个字节为总长度,第2个字节固定为03H,第3个字节开始奇数为Unicode字符,偶数为0x00),如果不符合上述特征则使用厂商默认说明。
	UCHAR MAU[40];   //USB厂商信息字符串.首字节是全部字节数(不超过28H),次字节开始为标准的USB字符串描述符格式(第1个字节为总长度,第2个字节固定为03H,第3个字节开始奇数为Unicode字符,偶数为0x00),如果不符合上述特征则使用厂商默认说明。
}USERCFG_343,*pUSERCFG_343;

从结构体可以看出厂商字符串最多可以支持配置18个字节,产品字符串最多可以支持配置18个字节,Serial String最多可以支持配置10个字节。

1.3 进入芯片配置模式和退出芯片配置模式

调用CH343PT_EnterConfigMode函数成功后才能读取和写入EEPROM中的数据,成功调用CH343PT_ExitConfigMode函数后退出EEPROM配置模式。

//进入芯片配置模式:300bpsp;可进行非标准波特率配置和配置空间读写
BOOL WINAPI	CH343PT_EnterConfigMode(HANDLE iPortH);
//退出芯片配置模式:300bps
BOOL WINAPI	CH343PT_ExitConfigMode(HANDLE iPortH);

1.4 读取和写入芯片EEPROM中的信息

调用CH343PT_ReadDevConfig函数后可以读取芯片EEPROM中VID、PID、最大电流、厂商字符串、产品字符串、Serial字符串等信息。修改EEPROM中厂商字符串、产品字符串、Serial字符串需要调用CH343PT_WriteDevConfig函数。

//通过串口读取芯片EERPOM内设备配置数据
BOOL    WINAPI	 CH343PT_ReadDevConfig(HANDLE          iPortH,     // 指定CH341设备序号
									   PULONG          DataLen,    // 要读取的数据长度
									   PUCHAR          DataBuf);    // 数据缓冲区
//通过串口向芯片EERPOM内写入设备的配置数据,写入前需确保写位保护位已关闭。
BOOL    WINAPI	 CH343PT_WriteDevConfig(HANDLE          iPortH,
										ULONG           BufferSize,
										PUCHAR          DataBuf);

二、使用上述接口去配置CH9102F的EEPROM

2.1 进入EEPROM配置和退出EEPROM配置模式

代码实现如下:

//打开串口进入EEPROM配置模式
BOOL OpenCH34xCom(HANDLE hCom, LPCTSTR ComName)
{
	//打开串口	
	hCom = CreateFile(ComName, GENERIC_READ|GENERIC_WRITE,
			0,NULL,OPEN_EXISTING,
			NULL,
			NULL);
	if(hCom == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	CH343PT_EnterConfigMode(hCom); //进入EEPROM配置模式
	return TRUE;
}

//关闭串口退出EEPROM配置模式
BOOL CloseCH34xCom(HANDLE hCom)
{
	if (INVALID_HANDLE_VALUE != hCom)
	{
		CH343PT_ExitConfigMode(hCom); //退出EERPOM配置模式
		If(!CloseHandle(hCom)) //关闭串口
			return FALSE;
		hCom = INVALID_HANDLE_VALUE;		
	}
	return TRUE;
}

2.2 读写芯片中的EEPROM参数

//读EEPROM中厂商字符串
BOOL ReadEEPROMManuStr(USERCFG_343 *CH34XSetSerialStr, PCHAR ManuStrBuffer)
{
	UCHAR StrSize, StrType;

	//显示厂商字符串
	StrSize = CH34XSetSerialStr->MAU[0];
	StrType = CH34XSetSerialStr->MAU[2];
	if( ( StrSize>0 ) &&     //字符串长度
		( StrType == 0x03 ) )//固定字符串类型
		wcstombs(&ManuStrBuffer[0],(WCHAR *)&CH34XSetSerialStr->MAU[3],(CH34XSetSerialStr->MAU[0] - 0)/2);
	else //无效字符串
		return FALSE;
	return TRUE;
}

//读取EEPROM中的产品字符串
BOOL ReadEEPROMProdStr(USERCFG_343 *CH34XSetSerialStr, PCHAR ProdStrBuffer)
{
	UCHAR StrSize, StrType;
	//显示产品字符串
	StrSize = CH34XSetSerialStr->PROD[0];
	StrType = CH34XSetSerialStr->PROD[2];
	if( ( StrSize>0 ) &&     //字符串长度
		( StrType == 0x03 ) )//固定字符串类型	
		wcstombs(&ProdStrBuffer[0],(WCHAR *)&CH34XSetSerialStr->PROD[3],(CH34XSetSerialStr->PROD[0] - 2)/2);

	else //无效字符串
		return FALSE;
	return TRUE;
}

//读取EEPROM中的SN字符串
BOOL ReadEEPROMSNStr(USERCFG_343 *CH34XSetSerialStr, PCHAR SNStrBuffer)
{
	UCHAR StrSize, StrType;

	//获取EERPROM中的SN字符串
	StrSize = CH34XSetSerialStr->SN[0];
	StrType = CH34XSetSerialStr->SN[2];
	if( ( StrSize>0 ) &&     //字符串长度
		( StrType == 0x03 ) )//固定字符串类型	
		sprintf(SNStrBuffer,"%S",&CH34XSetSerialStr->SN[3]);
	else //无效字符串
		return FALSE;
	return TRUE;
}

//写EEPROM中的厂商字符串,产品字符串,SN字符串
BOOL WriteCH34xEEPROMStr(USERCFG_343 *CH34XSetSerialStr)
{
	ULONG CH34xEepromSize;
	
	CH34xEepromSize = sizeof(CH34XSetSerialStr); //获取配置空间大小
	if( !CH343PT_WriteDevConfig(hCom,CH34xEepromSize,(PUCHAR)&CH34XSetSerialStr) ) //写EEPROM
	{ 
		return FALSE;
	}
	return TRUE;
}

三、软件实现

使用VC6++创建一个对话框,界面如下。
在这里插入图片描述

3.1 获取界面中配置信息

//读取EDIT控件中的厂商字符串,并传入CH34XSetSerialStr结构体中
VOID ReadManuEditConfig(USERCFG_343 *CH34XSetSerialStr,PCHAR MauBuffer, ULONG ManuStrLength)
{
	//获取厂商字符串Manufacture String
	memset(CH34XSetSerialStr->MAU, 0, sizeof(CH34XSetSerialStr->MAU));
	mbstowcs((PWCHAR)(&CH34XSetSerialStr->MAU[3]),MauBuffer,ManuStrLength);
	CH34XSetSerialStr->MAU[0] = ManuStrLength*2+2; //字符个数
	CH34XSetSerialStr->MAU[1] = ManuStrLength*2+2; //字符个数
	CH34XSetSerialStr->MAU[2] = 0x03;        //字符串类型,固定03
	CH34XSetSerialStr->CFG |= 0x20; //设置序列号有效标志
	return;
}

//读取EDIT控件中的产品字符串,并传入CH34XSetSerialStr结构体中
VOID ReadProdEditConfig(USERCFG_343 *CH34XSetSerialStr,PCHAR ProdBuffer, ULONG ProdStrLength)
{
	//获取产品字符串Product String
	memset(CH34XSetSerialStr->PROD, 0, sizeof(CH34XSetSerialStr->PROD));
	mbstowcs((PWCHAR)(&CH34XSetSerialStr->PROD[3]),ProdBuffer,ProdStrLength);
	CH34XSetSerialStr->PROD[0] = ProdStrLength*2+2; //字符个数
	CH34XSetSerialStr->PROD[1] = ProdStrLength*2+2; //字符个数
	CH34XSetSerialStr->PROD[2] = 0x03;        //字符串类型,固定03
	CH34XSetSerialStr->CFG |= 0x40; //设置序列号有效标志
	return;
}

//读取EDIT控件中的serial string字符串,并传入CH34XSetSerialStr结构体中
VOID ReadSNEditConfig(USERCFG_343 *CH34XSetSerialStr, PCHAR SNBuffer, ULONG SNStrLength)
{
	//获取Serial String
	memset(CH34XSetSerialStr->SN, 0, sizeof(CH34XSetSerialStr->SN));
	mbstowcs((PWCHAR)(&CH34XSetSerialStr->SN[3]),SNBuffer,SNStrLength);
	CH34XSetSerialStr->SN[0] = SNStrLength*2+2; //字符个数
	CH34XSetSerialStr->SN[1] = SNStrLength*2+2; //字符个数
	CH34XSetSerialStr->SN[2] = 0x03; //字符串类型,固定为0x03
	CH34XSetSerialStr->CFG |= 0x80; //设置序列号有效标志
	return;
}
//读取界面中的厂商、产品和Serial字符串
VOID ReadEditConfig(USERCFG_343 *CH34XSetSerialStr)
{
	CHAR SerStr[1024] = {0};
	CHAR ProductStr[1024] = {0};
	CHAR MauBuffer[256] = ""; //需写入的厂商字符串
	CHAR ProdBuffer[256] = "";
	CHAR SNBuffer[256] = "";
	CHAR Temp[20] = {0};
	CHAR buf[512] ="";
	USHORT bcdDevice;
	ULONG ManuStrLength,ProdStrLength,SNStrLength;
	
	CH34XSetSerialStr->SIG = 0x53;
	CH34XSetSerialStr->MODE = 0x23;
	CH34XSetSerialStr->CFG = 0xE0;
	*(PUSHORT)CH34XSetSerialStr->Pid = 0x55D4;
	*(PUSHORT)CH34XSetSerialStr->Vid = 0x1A86;
	//*(PUSHORT)CH34XSetSerialStr->BCD = 0x0442;
	CH34XSetSerialStr->Power = 0x44;
	CH34XSetSerialStr->Attributes = 0xA0;
	
	//获取bcdDevice
	CH343PT_GetUsbComDevBcd(hCom,&bcdDevice);
	*(PUSHORT)CH34XSetSerialStr->BCD = bcdDevice;
	//获取厂商字符串Manufacture String
	memset(MauBuffer,0,sizeof(MauBuffer));
	GetDlgItemText(AfxMainHwnd,IDC_ManuString,MauBuffer,sizeof(MauBuffer));
	ManuStrLength = strlen(MauBuffer);
	ReadManuEditConfig(CH34XSetSerialStr,MauBuffer,ManuStrLength);
	
	//获取产品字符串Product String
	memset(ProdBuffer,0,sizeof(ProdBuffer));
	GetDlgItemText(AfxMainHwnd,IDC_ProductString,ProdBuffer,sizeof(ProdBuffer));
	ProdStrLength = strlen(ProdBuffer);	
	ReadProdEditConfig(CH34XSetSerialStr,ProdBuffer,ProdStrLength);

	//获取Serial String
	memset(SNBuffer,0,sizeof(SNBuffer));
	GetDlgItemText(AfxMainHwnd,IDC_SerialString,SNBuffer,sizeof(SNBuffer));
	SNStrLength = strlen(SNBuffer);
	ReadSNEditConfig(CH34XSetSerialStr,SNBuffer,SNStrLength);
	return;
}

3.2 在界面中显示读取EEPROM中的厂商、产品和Serial字符串

//读EEPROM中厂商字符串,产品字符串,SN字符串
BOOL ReadEEPROMStr(HANDLE hCom, USERCFG_343 *CH34XSetSerialStr, LPCTSTR ComName)
{
	CHAR TempStr[1024] = "";
	CHAR ManuStrBuffer[64] = "";
	CHAR ProdStrBuffer[256] = "";
	CHAR SNStrBuffer[64] = "";
	ULONG CH34xEepromSize,Retval;
	
	if(!OpenCH34xCom(hCom,ComName))
	{
		goto Exit;
	}
	
	CH34xEepromSize = sizeof(CH34XSetSerialStr);
	if( !CH343PT_ReadDevConfig(hCom,&CH34xEepromSize,(PUCHAR)&CH34XSetSerialStr) )
	{	
		goto Exit;
	}
	//读EEPROM中厂商字符串,产品字符串,SN字符串
	Retval = ReadEEPROMManuStr(CH34XSetSerialStr, ManuStrBuffer);
	if(Retval)
		SetDlgItemText(AfxMainHwnd,IDC_ManuString,ManuStrBuffer);
	else
		SetDlgItemText(AfxMainHwnd,IDC_ManuString,"");
	Retval = ReadEEPROMProdStr(CH34XSetSerialStr, ProdStrBuffer);
	if(Retval)
		SetDlgItemText(AfxMainHwnd,IDC_ProductString,ProdStrBuffer);
	else
		SetDlgItemText(AfxMainHwnd,IDC_ProductString,"");
	Retval = ReadEEPROMSNStr(CH34XSetSerialStr, SNStrBuffer);
	if(Retval)
		SetDlgItemText(AfxMainHwnd,IDC_SerialString,SNStrBuffer);
	else
		SetDlgItemText(AfxMainHwnd,IDC_SerialString,"");

	CloseCH34xCom(hCom); //关闭串口并退出配置模式
	return TRUE;
Exit:
	CloseCH34xCom(hCom); //关闭串口并退出配置模式
	return FALSE;
}

读取芯片默认的参数,如下图所示。
在这里插入图片描述

3.3 写入EEPROM配置

//写EEPROM中的厂商字符串,产品字符串,SN字符串
BOOL WriteEEPROMStr(USERCFG_343 CH34XSetSerialStr, LPCTSTR ComName)
{
	USERCFG_343 CH34XSetSerialStr;
	
	//打开串口进入EEPROM配置模式
	if(!OpenCH34xCom(hCom, ComName))
	{
		CloseCH34xCom(hCom); 
		return FALSE;
	}
	ReadEditConfig(CH34XSetSerialStr); //读取界面中的厂商、产品和Serial字符串
	WriteCH34xEEPROMStr(CH34XSetSerialStr)
	{
		CloseCH34xCom(hCom); 
		return FALSE;
	}
	CloseCH34xCom(hCom); //关闭串口并退出EEPROM配置模式 
	ResetFlag = TRUE;
	return TRUE;
}

写入成功可以用USB View工具查看是否修改成功,如下图所示。
写入配置界面
在这里插入图片描述
USBView界面可以看出修改后厂商、产品和Serial字符串已经配置成功了。
在这里插入图片描述
上述demo函数调用方法去配置芯片EEPROM参数,同样适应于支持EEPROM配置的芯片(CH342、CH343、CH344、CH347、CH348、CH9101、CH9102、CH9103、CH9104)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PC技术小能手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值