CH9434嵌入式Linux与安卓系统驱动移植和使用教程

发布时间:2024-06-24  

1 前言

CH9434是一款SPI转四串口转接芯片,提供四组全双工的9线异步串口,用于单片机/嵌入式/安卓系统扩展异步串口。提供25路GPIO,以及支持RS485收发控制引脚TNOW。本篇基于STM32MP157处理器平台,介绍CH9434在嵌入式Linux系统/安卓系统的驱动移植和使用方法。


CH9434相关资料下载链接:



CH9434评估板设计原理图,单片机端操作例程,LINUX驱动及应用例程下载


2 驱动移植流程

2.1 移植准备

1、配置系统SPI设备信息,若支持DTS设备树可以直接在DTS文件中直接定义此SPI结构体信息,如下所示:


&spi5 {

     pinctrl-names = "default","sleep";

     pinctrl-0 = <&spi5_pins_a>;

     pinctrl-1 = <&spi5_sleep_pins_a>;

     status = "okay";

     cs-gpios = <&gpioz 4 GPIO_ACTIVE_LOW>;

     ch9434: ch9434@1 {

     compatible = "wch,ch943x";

     reg = <0>;

     spi-max-frequency = <3000000>;

     interrupt-parent = <&gpiod>;

     interrupts = <8 IRQ_TYPE_LEVEL_LOW>;

    };

};



对于不支持DTS设备树的系统,则需要在board源文件中定义spi0_board_info对象,如下所示:


static struct spi_board_info spi0_board_info[] __initdata = {

    {

        .modalias = "ch943x_spi",

        .platform_data = NULL,

        .max_speed_hz = 3000000,

        .bus_num = 0,

        .chip_select = 0,

        .mode = SPI_MODE_0,

        .controller_data = &spi0_csi[0],

        .irq = IRQ_EINT(8),

    }

};



2、配置IO中断引脚,确认CH9434芯片INT中断请求引脚所连接的CPU的IO口编号,此IO需支持中断功能。此编号可以直接在驱动源码ch9434.c中直接指定,也可以在如上SPI设备结构体中指定,如步骤1所示。


此外,注意有些平台上中断申请方式可能与驱动中默认实现方式不同,此时需修改ch9434.c文件中ch943x_spi_probe的相关代码


注:默认情况下请不要修改uart时钟,若确实需修改以支持部分非标波特率,可在ch943x_probe中修改:


freq = 32 *1000000 *15 / clkdiv;



2.2 静态编译驱动

(1)将驱动程序拷贝到内核目录:$kernel_srcdrivers tyserial


(2)向$kernel_srcdrivers tyserialKonfig 中添加:


config SERIAL_CH9434

tristate "SERIAL_CH9434 serial support"

depends on SPI

select SERIAL_CORE

help

    This selects support for ch9434 serial ports.



(3)向$kernel_srcdrivers tyserialMakefile 中添加:


obj-$(CONFIG_SERIAL_CH943X)+= ch9434.o



(4)运行make menuconfig,选择驱动/tty/serial下的ch9434 serial support,然后保存配置。


(5)重新编译系统


2.3 动态编译驱动—方式1

(1)拷贝驱动文件至用于添加驱动的package/kernel目录下


(2)新建模块目录,如:ch9434,然后添加相关的Makefile和Kconfig文件,通常可以从系统已有的其他驱动下拷贝然后修改


(3)运行“make menuconfig”然后选中“ ch9434 serial support”作为“modules”项


(4)单独编译模块,命令为:


make package/kernel/ch9434/compile V=s



2.4 动态编译驱动—方式2

拷贝驱动文件至宿主机工作目录,在driver目录下新增Makefile文件,如下所示:


KERN_DIR = /home/Linux-5.4 

all:

    make -C $(KERN_DIR) M=`pwd` modules 

    $(CROSS_COMPILE)gcc -o ch9434 ch9434.c 

clean:

    make -C $(KERN_DIR) M=`pwd` modules clean

    rm -rf modules.order

    rm -f ch9434

obj-m += ch9434.o



注意:此方式需系统下提前配置交叉编译工具链,在如上Makefile文件中修改KERN_DIR为已编译的内核目录。同时设置环境变量如下:


export ARCH=arm

export CROSS_COMPILE=arm-buildroot-linux-gnueabihf

export PATH=$PATH:/home/xxx/sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin



在driver目录下直接执行make,成功时可生成ch9434.ko驱动模块。


3 加载驱动并验证

3.1 加载驱动

[root@100ask:/mnt/ch9434]# insmod ch9434.ko

[ 477.091787] ch9434: loading out-of-tree module taints kernel.

[ 477.096776] ch9434: module verification failed: signature and/or required key missing - tainting kernel

[ 477.109272] ch9434: SPI driver for spi to serial chip ch9434, etc.

[ 477.114026] ch9434: V1.00 On 2020.06.17

[ 477.123448] ch943x_spi spi0.1: change to SPI MODE 3!



3.2 查看串口节点

进入/dev目录,可以看到出现ttyWCH0、ttyWCH1、ttyWCH2和ttyWCH3设备节点,表示加载成功。


[root@100ask:/dev]# ls ttyWCH*

ttyWCH0  ttyWCH1  ttyWCH2  ttyWCH3



3.3 验证SPI通讯

ch943x_probe中会自动调用ch943x_scr_test接口,向4个串口的SPR寄存器分别写入0x55和0x66并读取寄存器值,若读取与写入的数值相匹配,则SPI接口通讯正常。


static int ch943x_scr_test(struct uart_port *port)

{

struct ch943x_port *s = dev_get_drvdata(port->dev);


dev_vdbg(&s->spi_dev->dev,"******Uart %d SPR Test Start******

", port->line);

    ch943x_port_write(port, CH943X_SPR_REG,0x55);

ch943x_port_read(port, CH943X_SPR_REG);

ch943x_port_write(port, CH943X_SPR_REG,0x66);

ch943x_port_read(port, CH943X_SPR_REG);

dev_vdbg(&s->spi_dev->dev,"******Uart %d SPR Test End******

", port->line);

return 0;

}



使用前需在驱动程序中定义宏:


#define DEBUG

#define VERBOSE_DEBUG



以及修改printk内核打印等级:


[root@100ask:~]# echo 8 4 1 7 > /proc/sys/kernel/printk



加载驱动后查看内核打印信息:


[root@100ask:/mnt/ch9434]# insmod ch9434.ko

[ 477.091787] ch9434: loading out-of-tree module taints kernel.

[ 477.096776] ch9434: module verification failed: signature and/or required key missing - tainting kernel

[ 477.109272] ch9434: SPI driver for spi to serial chip ch9434, etc.

[ 477.114026] ch9434: V1.00 On 2020.06.17

[ 477.123448] ch943x_spi spi0.1: change to SPI MODE 3!

[ 477.129197] ch943x_spi spi0.1: ch943x_port_write - reg:0x81, val:0x 0

[ 477.135149] ch943x_spi spi0.1: ch943x_port_write - reg:0x84, val:0x 0

[ 477.141604] ch943x_spi spi0.1: ch943x_port_read - reg:0x 6, val:0x 0

[ 477.148458] ch943x_spi spi0.1: ******Uart 0 SPR Test Start******

[ 477.154347] ch943x_spi spi0.1: ch943x_port_write - reg:0x87, val:0x55

[ 477.160705] ch943x_spi spi0.1: ch943x_port_read - reg:0x 7, val:0x55

[ 477.166982] ch943x_spi spi0.1: ch943x_port_write - reg:0x87, val:0x66

[ 477.173556] ch943x_spi spi0.1: ch943x_port_read - reg:0x 7, val:0x66

[ 477.179305] ch943x_spi spi0.1: ******Uart 0 SPR Test End******

[ 477.185633] ch943x_spi spi0.1: ch943x_port_write - reg:0x91, val:0x 0

[ 477.192274] ch943x_spi spi0.1: ch943x_port_write - reg:0x94, val:0x 0

[ 477.198463] ch943x_spi spi0.1: ch943x_port_read - reg:0x16, val:0x 0

[ 477.209156] ch943x_spi spi0.1: ******Uart 1 SPR Test Start******

[ 477.214381] ch943x_spi spi0.1: ch943x_port_write - reg:0x97, val:0x55

[ 477.225183] ch943x_spi spi0.1: ch943x_port_read - reg:0x17, val:0x55

[ 477.232922] ch943x_spi spi0.1: ch943x_port_write - reg:0x97, val:0x66

[ 477.241444] ch943x_spi spi0.1: ch943x_port_read - reg:0x17, val:0x66

[ 477.246359] ch943x_spi spi0.1: ******Uart 1 SPR Test End******

[ 477.252862] ch943x_spi spi0.1: ch943x_port_write - reg:0xa1, val:0x 0

[ 477.259188] ch943x_spi spi0.1: ch943x_port_write - reg:0xa4, val:0x 0

[ 477.265396] ch943x_spi spi0.1: ch943x_port_read - reg:0x26, val:0x 0

[ 477.272512] ch943x_spi spi0.1: ******Uart 2 SPR Test Start******

[ 477.277949] ch943x_spi spi0.1: ch943x_port_write - reg:0xa7, val:0x55

[ 477.284520] ch943x_spi spi0.1: ch943x_port_read - reg:0x27, val:0x55

[ 477.290761] ch943x_spi spi0.1: ch943x_port_write - reg:0xa7, val:0x66

[ 477.297358] ch943x_spi spi0.1: ch943x_port_read - reg:0x27, val:0x66

[ 477.303202] ch943x_spi spi0.1: ******Uart 2 SPR Test End******

[ 477.309544] ch943x_spi spi0.1: ch943x_port_write - reg:0xb1, val:0x 0

[ 477.315969] ch943x_spi spi0.1: ch943x_port_write - reg:0xb4, val:0x 0

[ 477.322556] ch943x_spi spi0.1: ch943x_port_read - reg:0x36, val:0x 0

[ 477.329200] ch943x_spi spi0.1: ******Uart 3 SPR Test Start******

[ 477.334860] ch943x_spi spi0.1: ch943x_port_write - reg:0xb7, val:0x55

[ 477.341359] ch943x_spi spi0.1: ch943x_port_read - reg:0x37, val:0x55

[ 477.347567] ch943x_spi spi0.1: ch943x_port_write - reg:0xb7, val:0x66

[ 477.354204] ch943x_spi spi0.1: ch943x_port_read - reg:0x37, val:0x66

[ 477.360005] ch943x_spi spi0.1: ******Uart 3 SPR Test End******

[ 477.366257] ch943x_spi spi0.1: ch943x_port_write - reg:0xc8, val:0xcd

[ 477.372805] ch943x_spi spi0.1: ch943x_port_read - reg:0x48, val:0xcd

[ 477.382495] ch943x_spi spi0.1: ch943x_probe - devm_request_threaded_irq =84 result:0

[ 477.392463] cpu cpu0: Looking up cpu-supply from device tree



3.4 验证IO中断功能

驱动程序处理串口数据的发送,接收以及Modem输入中断事件均是在中断服务函数中进行,因此当SPI接口正常串口功能不正常,需检查中断功能是否正常,当执行串口发送时,驱动会自动打开串口发送中断(IETHRE),芯片的INT引脚会输出低电平请求CPU中断。在打开调试开关时,正常情况下可观察到中断服务函数运行的打印信息。此外,也可以手动给CPU的IO口拉高/拉低,测试中断是否能正常应。


4 功能测试

编译demo目录下tty_test_ch9434.c得到可执行目标程序app,运行演示:


./app -D /dev/ttyWCH0 -S 115200 -v

//参数含义

-D --device  tty device to use

-S --speed  uart speed

-v --verbose  verbose (show rx buffer)

-f --hardflow  open hardware flowcontrol

-R --rs485  enable rs485 function

-s --savefile  save rx data to file


4.1 串口收发

(1)串口发送数据流程为:应用软件调用write方法—>驱动接收请求并将数据拷贝至串口circ_buf,打开串口发送空中断(IER寄存器IETHRE位)->执行中断服务函数->判断为发送空中断时执行ch943x_handle_tx函数,从circ_buf中拷贝数据,通过SPI发送函数,将数据写入到串口发送FIFO寄存器->发送完成再次触发空中断,当circ_buf仍有数据则继续发送,否则关闭发送空中断。

(2)串口接收数据流程为:芯片RXD引脚收到串口数据后->执行中断服务函数->判断IIR中断类型为接收数据超时或接收数据可用时执行ch943x_handle_rx函数->读取FIFO长度,通过SPI读取函数,从串口接收FIFO寄存器读取数据并拷贝至串口circ_buf->退出中断->通过应用层有数据可读,应用软件调用read方法读数据。

串口收发流程图:

通过串口向PC收发数据测试:

串口发送0x00-0xFF/接收0x61-0x64

4.2 使用MODEM功能

引脚介绍:

编辑

MODEM输出测试方法: 程序中设置MODEM信号输出后,可以直接用万用表测试信号电压,也可以将9434评估板串口的输出引脚连接USB转串口模块(如CH342)的MODEM输入引脚,CH342的USB端连接PC;打开串口调试工具,通断发送端连接,接收端可观察数据变化。

MODEM输入测试方法:

进入开发板系统,由PC端串口输出,调试工具中开启DTR和RTS,CH9434串口输入:

接收端运行应用程序,输入“g”获取modem状态:


[root@100ask:/mnt/ch9434/demo]# ./app -D /dev/ttyWCH0 -S 115200 -v

press s to set modem, z to clear modem, g to get modem,b to send break, w to write, r to read, q for quit.

g

DSR Active!

CTS Active!

press s to set modem, z to clear modem, g to get modem,b to send break, w to write, r to read, q for quit.


4.3 硬件流控

串口流控功能使能是将 MCR寄存器的AFE位置1,CH9434 将自动进行硬件流控。芯片将自动根据 FIFO 大小对流控引脚进行操作。启用自动流控后,CTS 有效时芯片串口将连续发送数据,CTS 引脚无效时,串口最多发送8 字节数据后停止发送。RTS 在触发 FIFO 达到设定的流控字节数目后自动失效。

FCR 寄存器的 RECVTG1 和 RECVTG0 位用于设置接收 FIFO 的中断和硬件流控制的触发点,00 对应256 个字节,即接收满256 个字节产生接收数据可用的中断,并在使能硬件流控制时自动无效 RTS 引脚,01 对应512 个字节,10 对应1024 个字节,11 对应1285 个字节。

PC发送端串口工具设置开启流控制:

接收端运行应用程序:

4.4 GPIO测试

CH9434 支持部分引脚复用为 GPIO 功能,最多支持25 路,每个 IO 都可以独立设置方向、上拉电阻和下拉电阻配置。启用 GPIO 功能后,将自动失效该 IO 其他复用功能。GPIO 功能在设置时需要注意该 IO 原来功能的模式,设置时需要注意 DIR、PD、PU 等 IO 寄存器的顺序防止 IO 出现“抖动”。


GPIO输出测试:


测试方法:以GPIO0为例,该IO默认复用为CTS0;将该IO配置输出高/低电平,此时默认功能将失效。 添加代码:


/* gpio test */

ret = libtty_gpioenable(fd, 0, 1);

if (ret != 0) {

printf("libtty_gpioenable error.

");

exit(0);

}


ret = libtty_gpiopullup(fd, 0, 1);

if (ret != 0) {

printf("libtty_gpiopullup error.

");

exit(0);

}


ret = libtty_gpiodir(fd, 0, 1);

if (ret != 0) {

printf("libtty_gpiodir error.

");

exit(0);

}


ret = libtty_gpioset(fd, 0, 1);

if (ret != 0) {

printf("libtty_gpioset error.

");

exit(0);

}


使用万用表查看GPIO0输出电平 输出低电平:

输出高电平:

GPIO输入测试:

测试方法:以GPIO11为例,配置为输入模式,gpioval表示IO值,1个字节表示8个IO,将对应IO交替接地和3.3V引脚,运行应用程序查看输入值。

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>