国产高速芯片 CH9344 测试板

 CH9344是南京沁恒出品的一款串口芯片。现在市面上常见的 CH340 也是他们家的产品。相比之下,CH9344有下面2个显著的特点:

1.      最高支持 12,000,000串口频率;

2.      一颗芯片带有4个串口。

更具体的信息可以在官方页面【参考1】上看到。

这次我尝试使用这个芯片制作了一个测试板。首先是绘制电路图,基本上就是照搬 Datasheet上提供的参考设计。需要特别注意的是:

1.      因为通讯速度较高(已经属于 USB High Speed了),因此使用的是30Mhz 的晶振;

2.      Pin37 务必预留一个按钮,后面会讲述原因;

3.      USB 口上预留了一个 H3 跳线,用于一些不需要从 USB口取电的情况;

Layout 还是比较狂野的:

3D 预览如下:

然后就做出来了,焊接难度中等,强烈推荐准备助焊锡膏(不是焊锡膏),因为在焊接的时候很容易出现引脚粘连,在助焊锡膏的帮助下才容易分开。

完成之后就开始了测试。测试中我发现当选择为 12Mhz 通讯时,实际只有  6Mhz。

为了解决这个问题首先在技术社区发帖咨询,管理员让我通过电子邮件联系技术支持(tech@wch.cn)。技术支持工程是先后确认过使用的驱动是最新版本,通讯软件正确(他们家有自己的串口软件),之后他们发现我的芯片版本较老:

升级的方法是:对地短接 Pin37 ,将模块插入电脑后运行升级软件即可更新内部Firmware:

之后,设备管理器中的设备信息有变化:

再次测量,可以看到能够实现 12Mhz 的通讯:

电路设计软件是立创 EDA

参考:

1. http://www.wch.cn/products/CH9344.html

VC 宏展开

相信很多人入门时都使用 MASM,这的 MASM 就是 Microsoft‘s Macro Assembler。其中的 Macro 就是宏的意思。相比函数,宏具有更加简洁,运行速度快(编译器会对代码进行“宏展开”,直接修改代码)等等特点。但是,如果需要调试和阅读具有多层宏定义就非常痛苦了。很多年前我接触到的P公司的BIOS代码就是这样,乍一看代码非常规整,每一行就像一个洋葱,追踪起来一层又一层,让人感叹阅读代码是个系统工程。

最近偶然看到 GCC 有展开宏功能,同样的在Microsoft 的Visual C++上也有类似功能,通过编译指令 /p 或者 /ep 即可实现。这两个参数的区别在于生成的” 预编译文件”是否有行号。例如,编写下面的代码,其中定义一个名为 SUM 的宏:

#include  <Uefi.h>
#include  <Library/UefiLib.h>
#include  <Library/ShellCEntryLib.h>
#define SUM(a,b) a+b


/***
  Print a welcoming message.

  Establishes the main structure of the application.

  @retval  0         The application exited normally.
  @retval  Other     An error occurred.
***/
INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
        int c =3,d=4;

  Print(L"Hello there fellow Programmer.\n");
  Print(L"Welcome to the world of EDK II.\n");

  Print(L"Macro test %d\n",SUM(c,d));
  
  return(0);
}

在 INF 中定义如下:

[BuildOptions]
  MSFT:*_*_X64_CC_FLAGS  = /P

在Build 目录下有生成一个 hello.i 其中有如下代码断,可以看到 SUM 宏已经展开。

INTN
__cdecl
ShellAppMain (
   UINTN Argc,
   CHAR16 **Argv
  )
{
        int c =3,d=4;

  Print(L"Hello there fellow Programmer.\n");
  Print(L"Welcome to the world of EDK II.\n");

  Print(L"Macro test %d\n",c+d);
  
  return(0);
}

如果使用 /EP  /P 参数,那么生成的预编译文件中不会有行号:

[BuildOptions]
  MSFT:*_*_X64_CC_FLAGS  = /EP /P

下图中,左侧是 /EP /P 参数的运行结果,右侧是/P 的结果:

UEFI TIPS: 定义一个注释宏

最近看了一下C语言中 Define 的用法,这个可以看成是C 语言的宏定义,在使用时会进行展开。从这个角度来说,可以用它实现编译过程中自动删除代码的功能。

比如下面的代码中,当定义LAB_APP_DEBUG 1 后,编译过程中 zPrint  会被解释成为 “\\” 这样对应的一行就会被注释掉。

#include  <Uefi.h>
#include  <Library/BaseLib.h>
#include  <Library/UefiLib.h>
#include  <Library/ShellCEntryLib.h>

#include  <stdio.h>
#include  <stdlib.h>

#define LAB_APP_DEBUG 1
#if defined(LAB_APP_DEBUG)
        #define        zPrint   Print
#else   
        #define        zPrint   /\
/
#endif

INTN
EFIAPI
main (
  IN UINTN Argc,
  IN CHAR8 **Argv
  )
{
    zPrint(L"StringAAAA\n");
    zPrint(L"StringBBBB\n");
    
    return EFI_SUCCESS;
}

运行结果,第一个是定义了LAB_APP_DEBUG=1的结果,第二个是删除了这定义的结果

此外,EDK2 中一些宏将一些函数定义为空,在编译时通过当前时 DEBUG 还是 REALSE 进行区分,可以做到和上面相同的效果。

Arduino CH376 模块调试指南

去年的时候,介绍过通过串口来和 CH376 通讯【参考1】,最近又将它拿出来玩,和之前不同,这次是和 ESP32 通讯,没想到遇到了奇怪的问题,以此为契机仔细研读 datasheet 总结如下。

  1. 硬件连接:USB 转串口卡,上面的 5V(必须5V),接VCC;GND 接 GND;TX接 RX; RX 接TX; 特别注意,这种板子上有一个5V转3.3V的ASM1117,就是说5V提供给USB 设备,但是芯片是工作在3.3V 下,这种情况下串口一般都能正常工作,但是如果用 SPI 模式,需要特别注意和单片机的电平匹配问题;
  2. 串口发送 CHECK_EXIST (57 AB 06 AA),正确的回复是 0x55 如果没有回复或者是错误的,请检查硬件连接,还有波特率设定;默认情况下波特率为 9600
测试串口参数如图

3.串口发送CMD_SET_USB_MOD (57 AB 15 06), 模式代码为 06H 时切换到已启用的 USB 主机方式,自动产生 SOF 包,正确回答是CMD_RET_SUCCESS 和 USB_INT_CONNECT (0x51 0x15)

  1. 串口发送 DISK_CONNECT(57 AB 30),检查U盘连接,正确回答是 0x14;如果有问题,请更换U盘或者检查格式,在【参考2】给出了一个Bug:如果保留扇区数>255,在老的芯片上会有问题;
  2. 串口发送 DISK_MOUNT (57 AB 31),初始化U盘,并且检测,正确回答是 0x14;
  3. 串口发送 DISK_CAPACITY (57 AB 3E), 查询U盘容量。查询结果需要发送 RD_USB_DATA0查询(57 AB 27),收到返回值 04 FF 7F 7D 00 ,意思是 4个字节,0x7D7FFF= 8224767个扇区电脑上查看如下(感觉这个命令查询的结果是“U盘上最大的扇区号”,所以数量等于这个值加1):

参考:

  1. https://www.lab-z.com/ardch376/
  2. http://www.wch.cn/bbs/thread-63674-1.html 工作人员回复说老版本芯片会有问题

FT232H UART 速度测试

很早之前入手过一块 FT232H 的板卡,这次进行一下 UART 最高速度的测试。测试条件是 Windows 10 操作系统,系统默认的驱动(VCP)。

FT232H 长江智动产的

FT232 上 TXD 是 Pin13 (AD0), RXD 是Pin14(AD1)

FT232H 做 Uart 通讯时的引脚定义
不同功能下引脚的功能

使用串口工具直接发送 HEX 55 55 55 55 55 55 55 55 55 55 值(这样从信号看起来就是不断变化的0 1 信号),示波器查看结果如下:

上面是FT232H uart 12M (波特率  12 000 000)的结果
上面是 6Mhz 的结果

此外,有一些波特率是无法使用的比如:10Mhz ,测试显示无信号输出。测试板子上的晶振是 12Mhz 的,可能是因为这个原因,所有有些分频是无法出来的。从上面可以看出, FT232H UART 模式下,最高的有效传输速度可以达到 12Mhz*(8/10)=9 600 000 bits/s = 1.444Mbytes/s。

本文数据根据实验得出,有问题欢迎朋友直接指出共同探讨。

参考:

1. http://ftdichip.cn/Support/Documents/DataSheets/ICs/DS_FT232H.pdf

D3hot 和 D3Cold

从 Windows8 开始,操作系统将设备的 D3 状态分为2种: D3hot 和 D3Cold。

设备可以直接从 D0 状态进入D3Hot,D3Cold 只能从 D3Hot 状态进入。 从 D0 到 D3Hot 的状态切换是通过驱动程序来完成的。进入 D3Hot 后,仍然能够在这个设备连接的总线(Bus)上看到这个设备。当这个总线上的设备进入 D3Hot 后,总线必须处于 D0 状态。进入 D3Hot 后,设备可以返回 D0 状态,或者进入 D3Cold 状态。

当设备进入 D3Cold 后,总线上无法检测到这个设备(设备完全断电)。当设备进入 D3Cold 后,它所处的总线可以进入低功耗状态。同时这个设备不会响应总线上的检测动作。进入 D3Cold 后,设备只能返回 D0 状态,不能直接切换为 D3Hot 状态。

参考:

1.https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/device-sleeping-states

2.https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/supporting-d3cold-in-a-driver

3.https://blog.csdn.net/qq_38180524/article/details/106079187

4.http://blog.chinaunix.net/uid-7374279-id-5838168.html

WinDbg 查看OS 版本命令:vertarget

5: kd> vertarget
Windows 10 Kernel Version 19041 MP (8 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Edition build lab: 19041.1.amd64fre.vb_release.191206-1406
Machine Name:
Kernel base = 0xfffff805`0da00000 PsLoadedModuleList = 0xfffff805`0e62a2b0
Debug session time: Wed Feb 10 15:55:42.009 2021 (UTC + 8:00)
System Uptime: 7 days 23:02:38.960

参考:

1.https://www.cnblogs.com/yilang/p/12009225.html

Kabylake PCH UART 测试工具 UEFI Shell 版

在 KablyLake/AmberLake的PCH上存在着3个UART,默认情况下使用 UART2(第三个UART,INTEL RVP上使用的就是这个Port作为UEFI Debug Log 输出)。为此,编写一个 UEFI Shell Application 能够让三个 UART 分别发送 “This is PCH UART0/1/2”。在通过串口连接出去的机器上可以收到。这样能够方便的确认硬件连接以及配置是否工作正常。

运行结果:

ZUART UEFI Shell 下运行结果

工具下载(无 SourceCode):

ESP32 S2 进一步测试

春节这几天趁着有空再进一步研究了一下 ESP32 S2 的 USB 玩法。线路连接方法和之前介绍的相同【参考1】,特别注意,这次没有连接 ESP32S2 的5V和 USB 端口的5V,  这是防止 USB 端口上的5V和板子上的5V不同导致的电流倒灌。首先测试 HID的例子:

选择 ESP32 Tiny USB 中的 HID 例子

烧写代码后设备管理器中可以看到多出的 HID 设备。

新出现的 ESP32 S2 模拟出来的设备

我手上的开发板是ESP32-S2-Saola-1R,引脚入下图:

ESP32-S2-Saola-1R 引脚图

调试方法:

打开当前 Verbose 模式

这样,可以在 Arduino 串口监视器中看到 Debug 信息,比如插入时有如下信息:

插入时的Debug 信息

接下来研究一下 MSD (MassStorageDevice,U盘)的例子,在Example->ESP32 TinyUSB->MSC。这个例子需要使用1.5MB的 PSRAM ,对于我入手的板子来说 Flash 是4MB ,PSRAM 是2MB,完全能够满足要求。此外,需要 Enable PSRAM,否则会出现不断重启的问题:

需要Enable PSRAM

烧写之后系统中就会出现如下的硬盘。

很小的一个U盘

测试发现最新版本的 ESPTinyUSB 库似乎有问题,下面是我这边正常使用的老版本的库:

参考:

  1. http://www.lab-z.com/esp32s2/ 支持原生USB 的ESP32 :ESP32 S2
  2. https://www.mischianti.org/wp-content/uploads/2020/11/ESP32-S2-Saola-1MI-pinout-mischianti.png