CH34X-MPHSI高速Master扩展应用—SPI设备调试

一、前言 

本文介绍,基于USB2.0高速USB转接芯片CH347,配合厂商提供的USB转MPHSI(Multi Protocol High-Speed Serial Interface)Master总线驱动(CH34X-MPHSI-Master)为系统扩展SPI总线的用法,除此之外,还可以扩展I2C总线和GPIO等资源。

驱动软件正常工作后,会在系统下创建新的SPI Master,拥有独立的bus num,原SPI器件的设备驱动可直接通过DTS配置文件或者sysfs节点挂载到该总线上,原有设备驱动无需任何修改。

项目地址:GitHub - WCHSoftGroup/ch34x_mphsi_master_linux

 二、应用框图

三、CH347 SPI接口特点

CH347F SPI接口

PIN脚 SPI功能脚 GPIO复用脚
13 SCS0 -
7 SCS1 -
14 SCK -
16 MOSI -
15 MISO -

CH347T SPI接口

PIN脚 SPI功能脚 GPIO复用脚
5 SCS0 gpio2
9 SCS1 gpio5
6 SCK gpio0
8 MOSI -
7 MISO gpio1

SPI接口特性:

  • SPI模式0/1/2/3

  • SPI时钟频率60MHz~218.75KHz

  • MSB/LSB传输

  • 8位/16位传输

  • 2路片选

  • 片选高/低有效

四、驱动使用与确认SPI总线信息

本文基于树莓派4B平台,使用CH347F/T芯片通过树莓派的USB接口扩展SPI总线接口,介绍不同SPI设备的应用实例。

驱动程序默认未开启 spidev 设备创建,如需要使用 /dev/spidev*,在 ch34x_mphsi_master_spi.c 文件中要开放 SPIDEV 宏定义,即修改成:

#define SPIDEV
//#undef SPIDEV

1. 编译驱动

root@raspberrypi:/home/wch/ch34x_mphsi_master_linux_V1.1/driver # make
make -C /lib/modules/6.1.21-v8+/build M=/home/wch/ch34x_mphsi_master_linux_V1.1/driver modules
make[1]: 进入目录“/usr/src/linux-headers-6.1.21-v8+”
  CC [M]  /home/wch/ch34x_mphsi_master_linux_V1.1/driver/ch34x_mphsi_master_usb.o
  CC [M]  /home/wch/ch34x_mphsi_master_linux_V1.1/driver/ch34x_mphsi_master_spi.o
  CC [M]  /home/wch/ch34x_mphsi_master_linux_V1.1/driver/ch34x_mphsi_master_i2c.o
  CC [M]  /home/wch/ch34x_mphsi_master_linux_V1.1/driver/ch34x_mphsi_master_gpio.o
  LD [M]  /home/wch/ch34x_mphsi_master_linux_V1.1/driver/ch34x_mphsi_master.o
  MODPOST /home/wch/ch34x_mphsi_master_linux_V1.1/driver/Module.symvers
  CC [M]  /home/wch/ch34x_mphsi_master_linux_V1.1/driver/ch34x_mphsi_master.mod.o
  LD [M]  /home/wch/ch34x_mphsi_master_linux_V1.1/driver/ch34x_mphsi_master.ko
make[1]: 离开目录“/usr/src/linux-headers-6.1.21-v8+”

2. 加载驱动

root@raspberrypi:/home/wch/ch34x_mphsi_master_linux_V1.1/driver # make load
insmod ch34x_mphsi_master.ko

3、确认SPI总线信息

将CH347F/T 设备通过USB连接至树莓派,查看系统日志,可看到扩展的SPI总线号为SPI bus 7

[  218.193644] ch34x_mphsi_master: loading out-of-tree module taints kernel.
[  218.194619] mphsi-ch34x 1-1.2:1.2: ch34x_cfg_probe: output SPI slave with CS0
[  218.194633] mphsi-ch34x 1-1.2:1.2: ch34x_cfg_probe: output SPI slave with CS1
[  218.195050] mphsi-ch34x 1-1.2:1.2: ch34x_spi_probe: SPI master connected to SPI bus 7
[  218.195323] mphsi-ch34x 1-1.2:1.2: ch34x_mphsi_i2c_probe: I2C master connected to I2C bus 22
[  218.195645] mphsi-ch34x 1-1.2:1.2: ch34x_mphsi_gpio_probe: registered GPIOs from 501 to 503
[  218.195663] mphsi-ch34x 1-1.2:1.2: ch34x_usb_probe: USB to SPI/I2C/GPIO adapter ch34x now attached.
[  218.195778] usbcore: registered new interface driver mphsi-ch34x

五、W25Q16模块调试

本节介绍通过CH347的SPI接口操作W25Q16模块,相关资料:LibDriver W25QXX,是LibDriver推出的W25QXX全功能驱动,该驱动提供Flash读取,Flash写入等功能并且它符合MISRA标准)

GitHub - hepingood/w25qxx: W25QXX(W25Q80, W25Q16, W25Q32, W25Q64, W25Q128, W25Q256) full function driver for general MCU and Linux.

获得资料包后,进入w25qxx-master/project/raspberrypi4b目录,根据README编译得到可执行文件w25qxx.

注:

需进入w25qxx-master\project\raspberrypi4b\driver\src目录,修改raspberrypi4b_driver_w25qxx_interface.c文件,替换成CH347驱动创建的/dev/spi7.0节点设备。

#define SPI_DEVICE_NAME "/dev/spidev0.0" 修改为:

#define SPI_DEVICE_NAME "/dev/spidev7.0"

根据README运行可执行文件

寄存器测试

root@raspberrypi:/home/wch/w25qxx-master/project/raspberrypi4b/build # ./w25qxx -t reg --type=W25Q16 --interface=spi
w25qxx: chip is Winbond W25QXX.
w25qxx: manufacturer is Winbond.
w25qxx: interface is SPI QSPI.
w25qxx: driver version is 1.0.
w25qxx: min supply voltage is 2.7V.
w25qxx: max supply voltage is 3.6V.
w25qxx: max current is 25.00mA.
w25qxx: max temperature is 85.0C.
w25qxx: min temperature is -40.0C.
w25qxx: start register test.
w25qxx: w25qxx_set_type/w25qxx_get_type test.
w25qxx: set type W25Q80.
w25qxx: check chip type ok.
w25qxx: set type W25Q16.
w25qxx: check chip type ok.
w25qxx: set type W25Q32.
w25qxx: check chip type ok.
w25qxx: set type W25Q64.
w25qxx: check chip type ok.
w25qxx: set type W25Q128.
w25qxx: check chip type ok.
w25qxx: set type W25Q256.
w25qxx: check chip type ok.
w25qxx: w25qxx_set_interface/w25qxx_get_interface test.
w25qxx: set interface SPI.
w25qxx: check chip interface ok.
w25qxx: set interface QSPI.
w25qxx: check chip interface ok.
w25qxx: w25qxx_get_manufacturer_device_id test.
w25qxx: manufacturer is 0xEF, device id is 0x14.
w25qxx: w25qxx_get_jedec_id test.
w25qxx: manufacturer is 0xEF, device id is 0x40 0x15.
w25qxx: w25qxx_get_unique_id test.
w25qxx: unique id 0xE6 0x61 0x74 0xA2 0x43 0x3E 0xA0 0x2B.
w25qxx: w25qxx_set_status1/w25qxx_get_status1 test.
w25qxx: status1 is 0x00.
w25qxx: w25qxx_set_status2/w25qxx_get_status2 test.
w25qxx: status2 is 0x02.
w25qxx: w25qxx_set_status3/w25qxx_get_status3 test.
w25qxx: status3 is 0x60.
w25qxx: w25qxx_enable_write test.
w25qxx: check enable write ok.
w25qxx: w25qxx_disable_write test.
w25qxx: check disable write ok.
w25qxx: w25qxx_enable_write test.
w25qxx: check enable sr write ok.
w25qxx: w25qxx_erase_program_suspend test.
w25qxx: check erase program suspend ok.
w25qxx: w25qxx_erase_program_suspend test.
w25qxx: check erase program resume ok.
w25qxx: w25qxx_global_block_lock test.
w25qxx: check global block lock ok.
w25qxx: w25qxx_global_block_unlock test.
w25qxx: check global block unlock ok.
w25qxx: w25qxx_individual_block_lock test.
w25qxx: check individual block lock ok.
w25qxx: w25qxx_read_block_lock test.
w25qxx: check read block lock ok with 1.
w25qxx: w25qxx_individual_block_unlock test.
w25qxx: check individual block unlock ok.
w25qxx: w25qxx_set_burst_with_wrap test.
w25qxx: check set burst with wrap ok.
w25qxx: w25qxx_power_down test.
w25qxx: w25qxx_release_power_down test.
w25qxx: w25qxx_enable_reset test.
w25qxx: w25qxx_reset_device test.
w25qxx: finish register test.

读写FLASH测试

root@raspberrypi:/home/wch/w25qxx-master/project/raspberrypi4b/build # ./w25qxx -e write --type=W25Q16 --interface=spi --addr=0x000000 --data=0x08
w25qxx: addr 0 write data 8.
root@raspberrypi:/home/wch/w25qxx-master/project/raspberrypi4b/build # ./w25qxx -e read --type=W25Q16 --interface=spi --addr=0x000000
w25qxx: addr 0 is 8.

六、SSD1306模块调试

SSD1306是一款带控制器的用于OLED点阵图形显示系统的单片CMOS OLED/PLED驱动器。它由128个SEG(列输出)和64个COM(行输出)组成。该芯片专为共阴极OLED面板设计。

参考资料链接:

GitHub - rm-hull/luma.oled: Python module to drive a SSD1306 / SSD1309 / SSD1322 / SSD1325 / SSD1327 / SSD1331 / SSD1351 / SH1106 OLED

加载OLED驱动程序

root@raspberrypi:~ # insmod oled_drv.ko

使用sysfs或dts绑定将此spi设备驱动挂载到ch347创建的spi总线

  • 配置driver_override,用于匹配设备和驱动

root@raspberrypi:~ # echo oled_drv > /sys/class/spi_master/spi7/spi7.0/driver_override
  • 此处echo的名称应与驱动中name一致,示例:

static struct spi_driver spidev_spi_driver = {
    .driver = {
        .name = "oled_drv",
        ...
    }
    ...
}
  • 解除spidev7.0与原有spidev驱动的绑定

root@raspberrypi:~ # echo spi7.0 > /sys/bus/spi/drivers/spidev/unbind
  • 进行spi7.0和oled驱动的绑定

root@raspberrypi:~ # echo spi7.0 > /sys/bus/spi/drivers/oled_drv/bind

进入/sys/bus/spi/drivers/oled_drv目录,可以看到driver指向了对应的device

root@raspberrypi:/sys/bus/spi/drivers/oled_drv # ls -l spi7.0
lrwxrwxrwx 1 root root 0  7月 24 16:56 spi7.0 -> ../../../../devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.2/spi_master/spi7/spi7.0

或进入/sys/bus/spi/devices/spi7.0目录。可以看到device和driver匹配成功

root@raspberrypi:/sys/bus/spi/devices/spi7.0 # ls -l driver
lrwxrwxrwx 1 root root 0  7月 24 17:02 driver -> ../../../../../../../../../../../../../../bus/spi/drivers/oled_drv

运行应用程序

./test_app /dev/spi_oled

查看OLED模块显示内容

CH34X-MPHSI高速Master扩展应用—SPI设备调试_第1张图片

七、TLC5615模块调试

TLC5615 为德州仪器公司推出的具有串行接口的数模转换器,输入采用三线SPI串行信号,其输出为电压模拟信号,最大输出电压是基准电压值的两倍,配置简单不需要配置过多的寄存器,仅需使用单5V的电源即可工作。

参考资料 TLC5615 数据表、产品信息和支持 | 德州仪器 TI.com.cn

引脚如图

CH34X-MPHSI高速Master扩展应用—SPI设备调试_第2张图片

CH347模块的MOSI连接DIN,作为串行信号输入;OUT脚用于输出模拟电压信号;REFIN为外接参考电压2.048V。

加载TLC5615驱动程序

root@raspberrypi:~ # insmod tlc5615_drv.ko

配置driver_override,用于匹配设备和驱动

root@raspberrypi:~ # echo tlc5615_drv > /sys/class/spi_master/spi7/spi7.0/driver_override

解除spidev7.0与原有spidev驱动的绑定

root@raspberrypi:~ # echo spi7.0 > /sys/bus/spi/drivers/spidev/unbind

进行spi7.0和tlc5615驱动的绑定

root@raspberrypi:~ # echo spi7.0 > /sys/bus/spi/drivers/tlc5615_drv/bind

分别查看/sys/bus/spi/drivers/tlc5615_drv/spi7.0文件和/sys/bus/spi/devices/spi7.0/driver文件,可以看到device和driver匹配成功。

root@raspberrypi:~ # ls /sys/bus/spi/drivers/tlc5615_drv/spi7.0 -l
lrwxrwxrwx 1 root root 0  7月 25 19:01 /sys/bus/spi/drivers/tlc5615_drv/spi7.0 -> ../../../../devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.2/spi_master/spi7/spi7.0
root@raspberrypi:~ #
root@raspberrypi:~ #
root@raspberrypi:~ # ls /sys/bus/spi/devices/spi7.0/driver -l
lrwxrwxrwx 1 root root 0  7月 25 19:02 /sys/bus/spi/devices/spi7.0/driver -> ../../../../../../../../../../../../../../bus/spi/drivers/tlc5615_drv
root@raspberrypi:~ #

驱动加载成功后运行应用程序测量OUT引脚输出电压,OUT脚输出电压 = 2 * VREFIN * n / 1024 = 2 * 2.048 * n / 1024,其中,n为DIN输入的原始值。

你可能感兴趣的:(嵌入式Linux,SPI总线扩展,SPI模块调试,USB转SPI)