一、调试环境

平台:rk3568

kernel: 4.19.232

SDK: rk_android11.0_sdk

Board: rk3568-evb1-ddr4-v10

二、 rk3568 uart控制器

1. 特性:

rk3568 UART控制器特性如下:

- UART控制器通道:UART0~UART8    【datasheet好像写的有问题】
- 包含2组64字节的 FIFO,用于接收和传输
- 支持流控
- 支持速率 115.2Kbps, 460.8Kbps, 921.6Kbps, 1.5Mbps, 3Mbps, 4Mbps
- 支持5、6、7、8 bits数据位。
- 支持1、1.5、2 bits停止位。
- 支持奇校验和偶校验。
- 支持基于中断/DMA 模式

2. UART控制器架构

  1. APB INTERFACE

    处理器通过APB接口访问UART的数据,做控制,以及状态信息。

    UART支持8、16和32位的APB数据总线宽度。

  2. Register block

    负责UART的主要功能,包括控制、状态和中断产生。

  3. Modem Synchronization block

    同步modem输入信号.

  4. FIFO block

    负责FIFO控制和存储或向发送信号以控制外部RAM。

  5. Baud Clock Generator

    收发比特率设置。

  6. Serial Transmitter

    数据发送模块。

  7. Serial Receiver

    数据接收模块。

3. 控制器驱动

瑞芯微提供sdk中已经提供了8250uart驱动。

以下为主要驱动文件:

drivers/tty/serial/8250/8250_core.c     # 8250串口驱动核心
drivers/tty/serial/8250/8250_dw.c # Synopsis DesignWare 8250串口驱动
drivers/tty/serial/8250/8250_dma.c # 8250串口DMA驱动
drivers/tty/serial/8250/8250_port.c # 8250串口端口操作
drivers/tty/serial/8250/8250_early.c # 8250串口early console驱动

4. 设备树:

普通串口设备将会根据dts中的aliase来对串口进行编号,对应注册成ttySx设备。

dts中的aliases如下:

 aliases {
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
......
@kernel\arch\arm64\boot\dts\rockchip\rk3568.dtsi

	uart6: serial@fe6a0000 {
compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart";
reg = <0x0 0xfe6a0000 0x0 0x100>;
interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>;
clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
dmas = <&dmac0 12>, <&dmac0 13>;
pinctrl-names = "default";
pinctrl-0 = <&uart6m0_xfer>;
status = "disabled";
};

UART的板级dts配置只有以下参数允许修改:

  • dma-names:

    "tx" 打开tx dma

    "rx" 打开rx dma

    "!tx" 关闭tx dma

    "!rx" 关闭rx dma
  • pinctrl-0:

    &uart1m0_xfer 配置tx和rx引脚为iomux group 0

    &uart1m1_xfer 配置tx和rx引脚为iomux group 1

    &uart1m0_ctsn和&uart1m0_rtsn 配置硬件自动流控cts和rts引脚为iomux group 0

    &uart1m1_ctsn和&uart1m1_rtsn 配置硬件自动流控cts和rts引脚为iomux group 1
  • status:

    "okay" 打开

    "disabled" 关闭

引脚说明在下面定义:

以UART6为例:

@kernel\arch\arm64\boot\dts\rockchip\rk3568-pinctrl.dtsi

	uart6 {
/omit-if-no-ref/
uart6m0_xfer: uart6m0-xfer {
rockchip,pins =
/* uart6_rxm0 */
<2 RK_PA3 3 &pcfg_pull_up>,
/* uart6_txm0 */
<2 RK_PA4 3 &pcfg_pull_up>;
}; /omit-if-no-ref/
uart6m0_ctsn: uart6m0-ctsn {
rockchip,pins =
/* uart6m0_ctsn */
<2 RK_PC0 3 &pcfg_pull_none>;
}; /omit-if-no-ref/
uart6m0_rtsn: uart6m0-rtsn {
rockchip,pins =
/* uart6m0_rtsn */
<2 RK_PB7 3 &pcfg_pull_none>;
}; /omit-if-no-ref/
uart6m1_xfer: uart6m1-xfer {
rockchip,pins =
/* uart6_rxm1 */
<1 RK_PD6 3 &pcfg_pull_up>,
/* uart6_txm1 */
<1 RK_PD5 3 &pcfg_pull_up>;
};
};

5. 使用硬件自动流控

UART使用硬件自动流控时,需要确保UART驱动使能硬件自动流控功能,且在dts中已经切换cts和rts流控引脚的iomux。

建议在高波特率(1.5M波特率及以上)、大数据量的场景下都使用硬件自动流控,即使用四线UART。

6. 使用串口唤醒系统

串口唤醒系统功能是在系统待机时串口保持打开,并且把串口中断设置为唤醒源。使用时需要在dts中增

加以下参数:

	&uart1 {
wakeup-source;
};

注意,串口唤醒系统需要同时修改trust固件,请联系Rockchip以获取支持。

三、 移植

1. 修改设备树

sdk中UART默认并没有打开,所以我们只需要修改设备树就可以了。

下面以uart6为例,带流控:

/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi

&uart6{
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&uart6m1_xfer >;
};

注意:

引脚选择有两种配置: m0、m1;

编写设备树之前,查看电路图先确认,

公板是m1。

只有m0支持流控,如果需要支持设置 pinctrl-0:

​ pinctrl-0 = <&uart6m0_xfer &uart6m0_ctsn &uart6m0_rtsn>;

重新编译烧录boot.img即可。

查看设备文件

rk3568_r:/ # ls /dev/ttyS*
/dev/ttyS6 /dev/ttyS8

其中ttyS8是给蓝牙使用。

2. 引脚复用问题:uart6与gmac0冲突

uart6引脚与以太网口Gmac0会有冲突:

@kernel\arch\arm64\boot\dts\rockchip\rk3568-pinctrl.dtsi

	gmac0 {
/omit-if-no-ref/
gmac0_miim: gmac0-miim {
rockchip,pins =
/* gmac0_mdc */
<2 RK_PC3 2 &pcfg_pull_none>,
/* gmac0_mdio */
<2 RK_PC4 2 &pcfg_pull_none>;
}; ………………………… /omit-if-no-ref/
gmac0_rgmii_bus: gmac0-rgmii-bus {
rockchip,pins =
/* gmac0_rxd2 */
<2 RK_PA3 2 &pcfg_pull_none>,
/* gmac0_rxd3 */
<2 RK_PA4 2 &pcfg_pull_none>,
/* gmac0_txd2 */
<2 RK_PA6 2 &pcfg_pull_none_drv_level_2>,
/* gmac0_txd3 */
<2 RK_PA7 2 &pcfg_pull_none_drv_level_2>;
};
};

只需要禁用gmac0即可

/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi

&gmac0 {
………………
phy-handle = <&rgmii_phy0>;
status = "disable";
};

3. 通过寄存器,查看引脚复用配置情况

uart6使用到的引脚如下:

1) GRF_GPIO1D_IOMUX_H

Address: Operational Base + offset (0x001C)

2) GRF_GPIO2A_IOMUX_L

Address: Operational Base + offset (0x0020)

3) GRF_GPIO2A_IOMUX_H

Address: Operational Base + offset (0x0024)

4) GRF_GPIO2B_IOMUX_H

Address: Operational Base + offset (0x002C)

5) GRF_GPIO2C_IOMUX_L

Address: Operational Base + offset (0x0030)

uart6寄存器配置对应位位置如下图所示:,

我们只设置m1引脚为uart6的收发引脚,m0引脚未设置

所以只有寄存器 0xFDC60000+0x1c 的 bit[11:4]为 33

四、测试

公板预留了UART2~UART7的接口(4根线),

一口君不会焊接线,所以直接找的硬件工程师把线连好,

我只负责测试。

板子上的测试程序,瑞芯微官方已经提供了: ts_uart.uart

该工具获取,见文章底部

1. 移植ts_uart.uart

adb root
adb remount
adb push ts_uart.uart /bin
adb push send_0x55 /bin
adb push send_00_ff /bin

2. ts_uart.uart实用

1) 查看ts_uart.uart帮助信息:

rk3568_r:/ # ts_uart.uart

 Use the following format to run the HS-UART TEST PROGRAM
ts_uart v1.1
For sending data:
./ts_uart <tx_rx(s/r)> <file_name> <baudrate> <flow_control(0/1)> <max_delay(0-100)> <random_size(0/1)>
tx_rx : send data from file (s) or receive data (r) to put in file
file_name : file name to send data from or place data in
baudrate : baud rate used for TX/RX
flow_control : enables (1) or disables (0) Hardware flow control using RTS/CTS lines
max_delay : defines delay in seconds between each data burst when sending. Choose 0 for continuous stream.
random_size : enables (1) or disables (0) random size data bursts when sending. Choose 0 for max size.
max_delay and random_size are useful for sleep/wakeup over UART testing. ONLY meaningful when sending data
Examples:
Sending data (no delays)
ts_uart s init.rc 1500000 0 0 0 /dev/ttyS0
loop back mode:
ts_uart m init.rc 1500000 0 0 0 /dev/ttyS0
receive, data must be 0x55
ts_uart r init.rc 1500000 0 0 0 /dev/ttyS0

2) 非流控read:

ts_uart.uart r init.rc 115200 0 0 0  /dev/ttyS6

3) 流控read:

ts_uart.uart r init.rc 115200 1 0 0  /dev/ttyS6

4) 非流控write:

ts_uart.uart s /data/send_0x55.0x55 115200 0 0 0 /dev/ttyS6

5) 流控write:

ts_uart.uart s /data/send_0x55.0x55 115200 1 0 0 /dev/ttyS6

五、编写自己的测试程序

下面是一口君自己编写的测试程序,可以实现简单的数据收发,

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<termios.h>
#include<string.h> int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
struct termios newtio,oldtio;
if ( tcgetattr( fd,&oldtio) != 0)
{
perror("SetupSerial 1");
return -1;
}
bzero( &newtio, sizeof( newtio ) );
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE; switch( nBits )
{
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
} switch( nEvent )
{
case 'O':
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break;
case 'E':
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
break;
case 'N':
newtio.c_cflag &= ~PARENB;
break;
} switch( nSpeed )
{
case 2400:
cfsetispeed(&newtio, B2400);
cfsetospeed(&newtio, B2400);
break;
case 4800:
cfsetispeed(&newtio, B4800);
cfsetospeed(&newtio, B4800);
break;
case 9600:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
case 115200:
cfsetispeed(&newtio, B115200);
cfsetospeed(&newtio, B115200);
break;
case 460800:
cfsetispeed(&newtio, B460800);
cfsetospeed(&newtio, B460800);
break;
default:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
}
if( nStop == 1 )
newtio.c_cflag &= ~CSTOPB;
else if ( nStop == 2 )
newtio.c_cflag |= CSTOPB;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
tcflush(fd,TCIFLUSH);
if((tcsetattr(fd,TCSANOW,&newtio))!=0)
{
perror("com set error");
return -1;
}
// printf("set done!\n\r");
return 0;
} int main(void)
{
int fd1;
char data[10] = "yikoupeng";
char buf[100]={0}; fd1 = open( "/dev/ttyS6", O_RDWR);
if (fd1 == -1)
exit(1); nset = set_opt(fd1, 115200, 8, 'N', 1);
if (nset == -1)
{
exit(1);
}
printf("write start!\n");
write(fd1,data,strlen(data));
read(fd1,buf,sizeof(buf));
printf("rcv:%s\n",buf);
close(fd1);
return 0;
}

工具ts_uart.uart s获取

公众号后台回复:rxw

瑞芯微|rk3568 uart快速上手的更多相关文章

  1. 瑞芯微RK3399宣布系统开源,进入百余种行业市场!

    集微网消息,2月24日瑞芯微官方突然宣布, Rockchip RK3399Linux系统开源!作为Rockchip旗舰级芯片,RK3399具有高性能.高扩展.全能型应用特性. 这一重磅消息立马刷爆朋友 ...

  2. Linux下更新瑞芯微固件

    有这样的需求,是因为提供的BSP中是在windows下烧写的系统.我直接在linux下开发,每次编译后代码都要在windows下烧写,是一个很麻烦的事情.为了解决这个问题我尝试着用VirtualBox ...

  3. 9.7寸RK3188瑞芯微四核爱立顺M33平板电脑 - 深圳吉祥星晨科技有限公司 - 华强商情网

    9.7寸RK3188瑞芯微四核爱立顺M33平板电脑 - 深圳吉祥星晨科技有限公司 - 华强商情网 欢迎加入 2000人超级QQ群,平板电脑行业交流群:221371451,平板电脑产品及报价群:5765 ...

  4. 瑞芯微发布最新旗舰应用处理器-RK3588

    在瑞芯微电子第四届“开发者之春”大会上,瑞芯微推出了新一代8nm旗舰处理器-RK3588 这个芯片将采用8nm 制程工艺.基于A76+A55 内核组合,具备4K UI性能.8K VPU,拥有NPU2. ...

  5. 瑞芯微ROCK960 RK3399固件烧录总结

    1 下载固件 进入瑞芯微ROCK960下载主页 https://www.96boards.org/documentation/consumer/rock/downloads/ 选择os固件, Debi ...

  6. 瑞芯微RK3399六核-迅为3399开发板介绍

    迅为3399开发板基于瑞芯微的RK3399处理器设计,Rockchip RK3399是瑞芯微推出的一款低功耗.高性能的应用处理器芯片,该芯片基于Big.Little架构,即具有独立的NEON协同处理器 ...

  7. 瑞芯微RKnanC芯片处理器介绍

    RKnanC是一种低成本.低功耗.高效率的数字多媒体芯片,它是基于ARM的低功耗处理器结构和硬件加速器.它是专为便携式音频产品应用,如MP3播放器等. RKnanC可以支持各种音频标准的解码,如MP3 ...

  8. 瑞芯微RK3188如何配置USB摄像头支持

  9. 瑞芯微RK3188摄像头相关参数的配置

  10. 瑞芯微ROCK960 RK3399烧录image后扩容rootfs

    问题描述: RK3399开发板烧录官网提供的ubuntu镜像: Ubuntu 16.04 Server arm64(下载地址:https://www.96boards.org/documentatio ...

随机推荐

  1. python重拾第十三天-那就做个堡垒机吧

    本节内容 项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多人觉得,堡垒机就是跳板机,其实这个认识是不全面的,跳板功 ...

  2. 【资料分享】RK3568开发板规格书(4x ARM Cortex-A55(64bit),主频1.8GHz)

    1 开发板简介 创龙科技TL3568-EVM是一款基于瑞芯微RK3568J/RK3568B2处理器设计的四核ARM Cortex-A55国产工业评估板,每核主频高达1.8GHz/2.0GHz,由核心板 ...

  3. mermaid语法画图

    mermaid 脚本语言 graph TB 从上到下 graph BT 从下到上 graph RL 从右到左 graph LR 从左到右 graph LR; A001-->B001; graph ...

  4. power bi创建切片器导航

    现在很多报告使用的是按钮导航,今天分享另外一种方式:切片器导航. 第一步: 新建一个页面导航表,主页-输入数据-[填写列名,每页报表的表名] 如图: [页面导航表] 第二步: 添加一个切片器,将页面导 ...

  5. 机器学习策略篇:快速搭建你的第一个系统,并进行迭代(Build your first system quickly, then iterate)

    快速搭建的第一个系统,并进行迭代 如果正在考虑建立一个新的语音识别系统,其实可以走很多方向,可以优先考虑很多事情. 比如,有一些特定的技术,可以让语音识别系统对嘈杂的背景更加健壮,嘈杂的背景可能是说咖 ...

  6. Java异步判断线程池所有任务是否执行完成的方法

    1.使用ExecutorService和CountDownLatch的方法示例 在Java中,当我们使用线程池(如ExecutorService)来执行异步任务时,常常需要知道所有任务是否都已经完成. ...

  7. leetcode简单(设计):[225, 232, 303, 703, 705, 706, 933, 1603, 1656, 09, 30, 041, 03.06]

    目录 225. 用队列实现栈(先入后出) 232. 用栈实现队列(先入先出) 303. 区域和检索 - 数组不可变 703. 数据流中的第 K 大元素 705. 设计哈希集合 706. 设计哈希映射 ...

  8. elementplus弹窗可拖拽draggable,点击空白处不消失close-on-click-modal,modal是否去掉遮罩层

    <el-dialog :modal="false" v-model="dialogVisible" title="" width=&q ...

  9. sql server 编写函数,去除小数点后多余的0

    sql server 编写函数,去除小数点后多余的0 要在 SQL Server 中编写一个函数来去除小数点后多余的零,你可以使用以下示例的方法: CREATE FUNCTION dbo.Remove ...

  10. Node.js 处理 File

    Node.js 处理 File fs 模块 常规使用 运用递归遍历目录树 创建文件和目录 读写文件 path 模块 对于 file 的理解,此处 fs 模块 Node.js 提供了处理文件系统的内置模 ...