RZ/G2L支持的最大波特率

RZ/G2L的SCIFA異步通訊模式下支持的最高波特率可以達(dá)到12.5Mbps,如果異步基礎(chǔ)時(shí)鐘選擇16倍波特率,同時(shí)關(guān)閉波特率發(fā)生器的倍頻模式下依然可以達(dá)到3.125Mbps。如果異步基礎(chǔ)時(shí)鐘選擇8倍波特率或者波特率發(fā)生器開啟倍頻模式,最大波特率可以達(dá)到6.25Mbps。
在上集中我們有講過RZ/G2L在Linux下的使用遵循POSIX標(biāo)準(zhǔn)。只要POSIX支持的波特率,RZ/G2L都可以支持,并且支持各種波特率下的誤差修正,需要開啟MDDRS寄存器。
Linux下串口的波特率
Linux下termbits.h支持的波特率如下
左右滑動(dòng)查看完整內(nèi)容
/* c_cflag bit meaning */ #define CBAUD 0000377 #define B0 0000000 /* hang up */ #define B50 0000001 #define B75 0000002 #define B110 0000003 #define B134 0000004 #define B150 0000005 #define B200 0000006 #define B300 0000007 #define B600 0000010 #define B1200 0000011 #define B1800 0000012 #define B2400 0000013 #define B4800 0000014 #define B9600 0000015 #define B19200 0000016 #define B38400 0000017 #define EXTA B19200 #define EXTB B38400 #define CBAUDEX 0000000 #define B57600 00020 #define B115200 00021 #define B230400 00022 #define B460800 00023 #define B500000 00024 #define B576000 00025 #define B921600 00026 #define B1000000 00027 #define B1152000 00030 #define B1500000 00031 #define B2000000 00032 #define B2500000 00033 #define B3000000 00034 #define B3500000 00035 #define B4000000 00036
也就是標(biāo)準(zhǔn)的Linux支持的最大波特率是4Mbps,但并不是4Mbps以下任意一個(gè)波特率都可以支持,只有30種選擇。
那如果在特殊的應(yīng)用場(chǎng)景中,需要這30種波特率以外的選擇,是否能夠?qū)崿F(xiàn)呢?答案是肯定的,但是比較復(fù)雜。
這里我們提供一種Linux下實(shí)現(xiàn)非POSIX標(biāo)準(zhǔn)串口波特率的方法給大家參考。
Linux串口非標(biāo)波特率的實(shí)現(xiàn)
涉及兩部分他,包括內(nèi)核和應(yīng)用層
首先第一步:我們需要修改內(nèi)核中的串口驅(qū)動(dòng),確保串口驅(qū)動(dòng)能夠支持需要添加的非標(biāo)波特率。上集我們已經(jīng)分享過RZ/G2L的串口驅(qū)動(dòng)代碼路徑是drivers/tty/serial/sh-sci.c,目前通過開啟MDDRS,RZ/G2L幾乎可以支持12.5Mbps以下的任意串口波特率。
這里我們以前面提到的3.125Mbps/6.25Mbps/12.5Mbps為例,github上下載的sh-sci.c驅(qū)動(dòng)默認(rèn)并沒有開啟波特率發(fā)生器的倍頻模式,異步基礎(chǔ)時(shí)鐘選擇的是默認(rèn)的16倍波特率。所以最大的波特率可以支持到3.125Mbps,如果需要支持6.25Mbps或者更高的12.5Mbps,需要開啟波特率發(fā)生器的倍頻模式,并且允許異步基礎(chǔ)時(shí)鐘選擇8倍波特率。
左右滑動(dòng)查看完整內(nèi)容
+ #if ABCS0_BGDM_EN
+ if(baud > 6250000){
+ //SEMR_BGDM:Baud rate generator double-speed mode Select:
+ //SEMR_ABCS0:Asynchronous Base Clock Select:
+ serial_port_out(port, SEMR,
+ serial_port_in(port, SEMR) | (SEMR_ABCS0 | SEMR_BGDM));
+ freq *= 2;
+ prediv /= 2;
+ }else if(baud > 3125000){
+ //SEMR_BGDM:Baud rate generator double-speed mode Select:
+ serial_port_out(port, SEMR,
+ serial_port_in(port, SEMR) | SEMR_BGDM);
+ freq *= 2;
+ }
+ #endif
這部分代碼與RZ/G2L的平臺(tái)相關(guān),需要根據(jù)RZ/G2L的規(guī)格書配置對(duì)應(yīng)的寄存器。
第二步:為了允許應(yīng)用層配置我們添加的這三種波特率,需要修改drivers/tty/tty_baudrate.c和include/uapi/asm-generic/termbits.h,這兩個(gè)文件與平臺(tái)無關(guān)。想要在內(nèi)核中添加系統(tǒng)默認(rèn)的30種波特率以外的波特率都需要修改這兩個(gè)文件。這兩個(gè)文件的修改內(nèi)容可以參考以下:
左右滑動(dòng)查看完整內(nèi)容
diff --git a/drivers/tty/tty_baudrate.c b/drivers/tty/tty_baudrate.c
index bdfaee2c1331..75d287893d11 100644
--- a/drivers/tty/tty_baudrate.c
+++ b/drivers/tty/tty_baudrate.c
@@ -24,7 +24,7 @@ static const speed_t baud_table[] = {
1000000, 1152000, 1500000, 2000000
#else
500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
- 2500000, 3000000, 3500000, 4000000
+ 2500000, 3000000, 3500000, 4000000, 3125000, 6250000, 12500000
#endif
};
@@ -36,7 +36,7 @@ static const tcflag_t baud_bits[] = {
B1000000, B1152000, B1500000, B2000000
#else
B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000,
- B2500000, B3000000, B3500000, B4000000
+ B2500000, B3000000, B3500000, B4000000, B3125000, B6250000, B12500000
#endif
};
@@ -73,6 +73,14 @@ speed_t tty_termios_baud_rate(struct ktermios *termios)
else
cbaud += 15;
}
+ if (cbaud & CBAUDEX2) {
+ cbaud &= ~CBAUDEX2;
+
+ if (cbaud < 1 || cbaud + 30 > n_baud_table)
+ termios->c_cflag &= ~CBAUDEX2;
+ else
+ cbaud += 30;
+ }
return cbaud >= n_baud_table ? 0 : baud_table[cbaud];
}
EXPORT_SYMBOL(tty_termios_baud_rate);
diff --git a/include/uapi/asm-generic/termbits.h b/include/uapi/asm-generic/termbits.h
index 7db62a33ee52..1353300b6934 100644
--- a/include/uapi/asm-generic/termbits.h
+++ b/include/uapi/asm-generic/termbits.h
@@ -110,7 +110,7 @@ struct ktermios {
#define FF1 0100000
/* c_cflag bit meaning */
-#define CBAUD 0010017
+#define CBAUD 0030017
#define B0 0000000 /* hang up */
#define B50 0000001
#define B75 0000002
@@ -158,7 +158,9 @@ struct ktermios {
#define B3500000 0010016
#define B4000000 0010017
+#define CBAUDEX2 0020000
+#define B3125000 0020001
+#define B6250000 0020002
+#define B12500000 0020003
#define CIBAUD 002003600000 /* input baud rate */
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#define CRTSCTS 020000000000 /* flow control */
經(jīng)過上面兩步修改,內(nèi)核已支持我們需要添加的3種非POSIX標(biāo)準(zhǔn)的串口波特率。
接下來演示應(yīng)用層如何使用我們添加的這三種串口波特率。
左右滑動(dòng)查看完整內(nèi)容
#define B3125000 0020001 #define B6250000 0020002 #define B12500000 0020003 ** ** 串口配置 ** 參數(shù) cfg 指向一個(gè) uart_cfg_t 結(jié)構(gòu)體對(duì)象 **/ static int uart_cfg(const uart_cfg_t *cfg) { struct termios new_cfg = {0}; //將 new_cfg 對(duì)象清零 speed_t speed; /* 設(shè)置為原始模式 */ cfmakeraw(&new_cfg); /* 使能接收 */ new_cfg.c_cflag |= CREAD| CLOCAL; /* 設(shè)置波特率 */ speed = B3125000; // B3125000 B6250000 B12500000 new_cfg.c_cflag |= speed; /* 串口的其他屬性配置參考標(biāo)準(zhǔn)的POSIX */ /* 寫入配置、使配置生效 */ if (0 > tcsetattr(fd, TCSANOW, &new_cfg)) { fprintf(stderr, "tcsetattr error: %s ", strerror(errno)); return -1; }
經(jīng)過以上修改,我們就可以在linux下使用文章開頭提到的RZ/G2L的最大波特率12.5Mbps進(jìn)行串口通訊。
需要注意的是,我們給RZ/G2L添加的這三個(gè)波特率尤其是6.25Mbps或者12.5Mbps遠(yuǎn)超標(biāo)準(zhǔn)linux下支持的最大波特率4Mbps,所以,通過PC端的Ubuntu是無法使用這三種波特率與RZ/G2L的SMARC EVK板進(jìn)行通訊測(cè)試的,如果要使用我們上面添加的這三種波特率,只能在兩個(gè)SMARC EVK板上進(jìn)行。
所以,除以上添加的這三種波特率外,如果要添加POSIX標(biāo)準(zhǔn)支持的30種以外的其他波特率,都可以參考這個(gè)方法來實(shí)現(xiàn)。
審核編輯:湯梓紅
-
寄存器
+關(guān)注
關(guān)注
31文章
5587瀏覽量
128984 -
瑞薩
+關(guān)注
關(guān)注
36文章
22428瀏覽量
89680 -
串口
+關(guān)注
關(guān)注
15文章
1605瀏覽量
81873 -
異步通訊
+關(guān)注
關(guān)注
0文章
12瀏覽量
7579
發(fā)布評(píng)論請(qǐng)先 登錄
基于瑞薩64位MPU RZ/G2L進(jìn)行32位應(yīng)用軟件開發(fā)
基于瑞薩64位MPU RZ/G2L的uboot串口多波特率支持介紹
基于瑞薩電子RZ/G2L的FET-G2LD-C核心板和OK-G2LD-C開發(fā)板評(píng)測(cè)
RZ/G2L高速虛擬串口方案 基于瑞薩RZ/G2L SMARC開發(fā)板的虛擬(Virtual UART)實(shí)現(xiàn)方案

瑞薩RZ/G2L串口SCI的使用(下)
評(píng)論