• 正文
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

瑞芯微|rk3568 uart快速上手

01/10 15:30
820
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

一、調(diào)試環(huán)境

平臺(tái):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字節(jié)的?FIFO,用于接收和傳輸??
-?支持流控
-?支持速率?115.2Kbps,?460.8Kbps,?921.6Kbps,?1.5Mbps,?3Mbps,?4Mbps
-?支持5、6、7、8?bits數(shù)據(jù)位。
-?支持1、1.5、2?bits停止位。
-?支持奇校驗(yàn)和偶校驗(yàn)。
-?支持基于中斷/DMA?模式

2. UART控制器架構(gòu)

APB INTERFACE
處理器通過(guò)APB接口訪問UART的數(shù)據(jù),做控制,以及狀態(tài)信息。
UART支持8、16和32位的APB數(shù)據(jù)總線寬度。

Register block
負(fù)責(zé)UART的主要功能,包括控制、狀態(tài)和中斷產(chǎn)生。

Modem Synchronization block
同步modem輸入信號(hào).

FIFO block
負(fù)責(zé)FIFO控制和存儲(chǔ)或向發(fā)送信號(hào)以控制外部RAM。

Baud Clock Generator
收發(fā)比特率設(shè)置。

Serial Transmitter
數(shù)據(jù)發(fā)送模塊。

Serial Receiver
數(shù)據(jù)接收模塊。

3. 控制器驅(qū)動(dòng)

瑞芯微提供sdk中已經(jīng)提供了8250uart驅(qū)動(dòng)。

以下為主要驅(qū)動(dòng)文件:

drivers/tty/serial/8250/8250_core.c?????#?8250串口驅(qū)動(dòng)核心
drivers/tty/serial/8250/8250_dw.c???????#?Synopsis?DesignWare?8250串口驅(qū)動(dòng)
drivers/tty/serial/8250/8250_dma.c?????#?8250串口DMA驅(qū)動(dòng)
drivers/tty/serial/8250/8250_port.c??????#?8250串口端口操作
drivers/tty/serial/8250/8250_early.c?????#?8250串口early?console驅(qū)動(dòng)

4. 設(shè)備樹:

普通串口設(shè)備將會(huì)根據(jù)dts中的aliase來(lái)對(duì)串口進(jìn)行編號(hào),對(duì)應(yīng)注冊(cè)成ttySx設(shè)備。
dts中的aliases如下:

?aliases?{
serial0?=?&uart0;
serial1?=?&uart1;
serial2?=?&uart2;
serial3?=?&uart3;
......
@kernelarcharm64bootdtsrockchiprk3568.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的板級(jí)dts配置只有以下參數(shù)允許修改:

    • dma-names:
    • "tx" 打開tx dma
    • "rx" 打開rx dma
    • "!tx" 關(guān)閉tx dma
    • "!rx" 關(guān)閉rx dmapinctrl-0:
    • &uart1m0_xfer 配置tx和rx引腳為iomux group 0
    • &uart1m1_xfer 配置tx和rx引腳為iomux group 1
    • &uart1m0_ctsn和&uart1m0_rtsn 配置硬件自動(dòng)流控cts和rts引腳為iomux group 0
    • &uart1m1_ctsn和&uart1m1_rtsn 配置硬件自動(dòng)流控cts和rts引腳為iomux group 1status:
    • "okay" 打開
    "disabled" 關(guān)閉

引腳說(shuō)明在下面定義:
以UART6為例:

@kernelarcharm64bootdtsrockchiprk3568-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. 使用硬件自動(dòng)流控

UART使用硬件自動(dòng)流控時(shí),需要確保UART驅(qū)動(dòng)使能硬件自動(dòng)流控功能,且在dts中已經(jīng)切換cts和rts流控引腳的iomux。

建議在高波特率(1.5M波特率及以上)、大數(shù)據(jù)量的場(chǎng)景下都使用硬件自動(dòng)流控,即使用四線UART。

6. 使用串口喚醒系統(tǒng)

串口喚醒系統(tǒng)功能是在系統(tǒng)待機(jī)時(shí)串口保持打開,并且把串口中斷設(shè)置為喚醒源。使用時(shí)需要在dts中增
加以下參數(shù):

?&uart1?{
??wakeup-source;
?};

注意,串口喚醒系統(tǒng)需要同時(shí)修改trust固件,請(qǐng)聯(lián)系Rockchip以獲取支持。

三、 移植

1. 修改設(shè)備樹

sdk中UART默認(rèn)并沒有打開,所以我們只需要修改設(shè)備樹就可以了。

下面以u(píng)art6為例,帶流控:

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

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

注意:

引腳選擇有兩種配置: m0、m1;

編寫設(shè)備樹之前,查看電路圖先確認(rèn),

公板是m1。

只有m0支持流控,如果需要支持設(shè)置 pinctrl-0:

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

重新編譯燒錄boot.img即可。

查看設(shè)備文件

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

其中ttyS8是給藍(lán)牙使用。

2. 引腳復(fù)用問題:uart6與gmac0沖突

uart6引腳與以太網(wǎng)口Gmac0會(huì)有沖突:

@kernelarcharm64bootdtsrockchiprk3568-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. 通過(guò)寄存器,查看引腳復(fù)用配置情況

uart6使用到的引腳如下:

請(qǐng)?zhí)砑訄D片描述

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寄存器配置對(duì)應(yīng)位位置如下圖所示:,

我們只設(shè)置m1引腳為uart6的收發(fā)引腳,m0引腳未設(shè)置

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

四、測(cè)試

公板預(yù)留了UART2~UART7的接口(4根線),

一口君不會(huì)焊接線,所以直接找的硬件工程師把線連好,

我只負(fù)責(zé)測(cè)試。

板子上的測(cè)試程序,瑞芯微官方已經(jīng)提供了: 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實(shí)用

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

五、編寫自己的測(cè)試程序

下面是一口君自己編寫的測(cè)試程序,可以實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)收發(fā),

#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!nr");
?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:%sn",buf);
?close(fd1);
?return?0;
}

工具ts_uart.uart s獲取,公眾號(hào)【一口Linux】后臺(tái)回復(fù):rxw

瑞芯微電子

瑞芯微電子

瑞芯微專注于移動(dòng)互聯(lián)網(wǎng)、數(shù)字多媒體芯片設(shè)計(jì),是專業(yè)的個(gè)人移動(dòng)信息終端SOC解決方案供應(yīng)商。瑞芯微在移動(dòng)互聯(lián)網(wǎng)領(lǐng)域有多個(gè)較完整的自主創(chuàng)新的知識(shí)產(chǎn)權(quán)群,為中國(guó)電子業(yè)發(fā)展做出積極努力。目前產(chǎn)品涵蓋Android平板電腦、Android電視機(jī)頂盒(智能電視)、電子書、WIFI/藍(lán)牙音頻解決方案等。

瑞芯微專注于移動(dòng)互聯(lián)網(wǎng)、數(shù)字多媒體芯片設(shè)計(jì),是專業(yè)的個(gè)人移動(dòng)信息終端SOC解決方案供應(yīng)商。瑞芯微在移動(dòng)互聯(lián)網(wǎng)領(lǐng)域有多個(gè)較完整的自主創(chuàng)新的知識(shí)產(chǎn)權(quán)群,為中國(guó)電子業(yè)發(fā)展做出積極努力。目前產(chǎn)品涵蓋Android平板電腦、Android電視機(jī)頂盒(智能電視)、電子書、WIFI/藍(lán)牙音頻解決方案等。收起

查看更多

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

公眾號(hào)『一口Linux』號(hào)主彭老師,擁有15年嵌入式開發(fā)經(jīng)驗(yàn)和培訓(xùn)經(jīng)驗(yàn)。曾任職ZTE,某研究所,華清遠(yuǎn)見教學(xué)總監(jiān)。擁有多篇網(wǎng)絡(luò)協(xié)議相關(guān)專利和軟件著作。精通計(jì)算機(jī)網(wǎng)絡(luò)、Linux系統(tǒng)編程、ARM、Linux驅(qū)動(dòng)、龍芯、物聯(lián)網(wǎng)。原創(chuàng)內(nèi)容基本從實(shí)際項(xiàng)目出發(fā),保持原理+實(shí)踐風(fēng)格,適合Linux驅(qū)動(dòng)新手入門和技術(shù)進(jìn)階。