Fuart & UART流控使用参考
1. Fuart流控流程¶
1.1. HW连接¶
1.2. 参数说明¶
-
RTS
Require To Send,发送请求为输出信号,用于指示本设备准备好可接收数据,低电平有效,低电平说明本设备可以接收数据。
-
CTS
Clear To Send,允许发送输入信号,用于判断是否可以向对方发送数据,低电平有效,低电平说明本设备可以向对方发送数据。
1.3. 流控制方式¶
如果本端处理数据流(接收对方数据),将RTS置为低电平; 对方设备CTS脚是低电平,则可以发送数据。
如果本端不处理数据流(不接收对方数据),将RTS置为高电平; 对方设备CTS脚是高电平,则停止发送数据, 等待CTS的脚位变化。
1.4. FUART 测试方式¶
1.4.1. kernel验证RTS CTS 流程¶
-
modify infinity6e.dtsi
-
modify infinity6e-padmux.dtsi add
1.4.2. 编译kernel¶
将kernel烧写到flash
重启
进入shell后(请先验证该组的四个pin是否可以单独控制拉高/低电平)
-
/ # ls /dev/ttyS2
-
/ # stty -F /dev/ttyS2 ispeed 115200 ospeed 115200 cs8
-
/ # cd mnt/
-
/mnt # ./enable_rtscts (应用程序,用来开启流控,请自行拷贝代码编译)
-
/ # /customer/riu_r 103c 6e(查看是否设置为mode1)
BANK:0x103C 16bit-offset 0x6E
0x0010
-
/ # /customer/riu_r 1102 8(查看rts cts enable)
BANK:0x1102 16bit-offset 0x08
0x0022
-
此时已经enable RTS CTS,使用LA测PAD_FUART_CTS,PAD_FUART_RTS
PAD_FUART_CTS = 1
PAD_FUART_RTS = 0(正确值)
-
将PAD_FUART_RX,PAD_FUART_TX连接到PC
/ # echo aaaaaaaa > /dev/ttyS2
此时PC上的串口工具没有接收到任何数据
将PAD_FUART_CTS接地,PC串口工具log如下:
CTS验证通过
-
/ # cat dev/ttyS2 &
-
/ # /customer/riu_r 1102 2
BANK:0x1102 16bit-offset 0x02
0x0005
-
/ # /customer/riu_w 1102 2 0(关闭fuart接收中断,tx接收到数据后不会将数据读出,fifo full后,RTS被置1)
BANK:0x1102 16bit-offset 0x02
0x0000
-
使用串口工具send 30byte data to fuart
-
使用LA测PAD_FUART_RTS
PAD_FUART_RTS = 1(正确值)
-
/ # /customer/riu_w 1102 2 5(打开fuart接收中断,fifo的数据被读出后,RTS被置0)
BANK:0x1102 16bit-offset 0x02
0x0005
-
使用LA测PAD_FUART_RTS
PAD_FUART_RTS = 0(正确值)
PC串口工具log如下:
RTS验证通过
1.4.3. 代码¶
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <errno.h> int enable_rtscts(int fd) { struct termios options; if ( tcgetattr( fd,&options) != 0) { perror("SetupSerial 1"); return -1; } options.c_cflag |= CRTSCTS; tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */ if (tcsetattr(fd,TCSANOW,&options) != 0) { perror("SetupSerial 3"); return -1; } return 0; } int main(int argc, char **argv) { int fd; fd = open("/dev/ttyS2",O_RDWR|O_NOCTTY|O_NDELAY); if (fd <= 0){ printf("Can't Open Serial Port!\n"); return -1; } if(enable_rtscts(fd)== -1) { printf("Set Parity Error\n"); exit(1); } printf("enable rts cts\n"); close(fd); return 0; }
1.5. 注意事项¶
-
确认pin脚配置Fuart
-
kernel\arch\arm\boot\dts\infinity2m-ssc011a-s01a-padmux-display.dtsi :
<PAD_FUART_RX PINMUX_FOR_FUART_MODE_1 MDRV_PUSE_FUART_RX>, <PAD_FUART_TX PINMUX_FOR_FUART_MODE_1 MDRV_PUSE_FUART_TX>, <PAD_FUART_CTS PINMUX_FOR_FUART_MODE_1 MDRV_PUSE_FUART_CTS>, <PAD_FUART_RTS PINMUX_FOR_FUART_MODE_1 MDRV_PUSE_FUART_RTS>,
-
kernel\arch\arm\boot\dts\infinity2m-ssc011a-s01a-padmux-display.dtsi :
fuart: uart2@1F220400 { compatible = "sstar,uart"; reg = <0x1F220400 0x100>, <0x1F220600 0x100>; interrupts = <GIC_SPI INT_IRQ_FUART IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_URDMA IRQ_TYPE_LEVEL_HIGH>; clocks = <&CLK_fuart>; dma = <0>; sctp_enable = <1>;//rts cts enable is 1 //pad = <PAD_FUART_RX>;//fuart mode2 pad = <PAD_FUART_CTS>;//fuart mode 1 tolerance = <2>; status = "ok"; };
-
确认软件使能cts/rts,如果没有使能cts/rts功能 ,他们默认值为高电平状态。
-
如果要保证ssd20x处于可接受状态,使用命令:cat /dev/ttyS2 & ,如果没有一直开启ttyS2的设备,那么Fuart的中断状态会自动清除。获取register[101e 2]==0x0000;正常为0x0005。
2. 接RS芯片,半双工通信流程¶
-
连接方法
RS485属于master-salver模式,同时mater作为发起端,salver应答端。网络中同时只有一台在发送数据,其他设备属于监听状态。
主要流程如下, 所有行为需要等待master端的通知。
Host/Master给RS485芯片发送数据时,先把R/D拉高, 发送完毕后,将R/D 拉低,Host/Master进入监听状态,等待slaver应答。
-
app层使用方法
struct serial_rs485 rs485conf; memset(&rs485conf,0,sizeof(rs485conf)); rs485conf.padding[0] = 17; //用来控制slaver收发的gpio index rs485conf.delay_rts_after_send = 2000; //发送完最后一个字节需要的delay,单位:us rs485conf.flags |= SER_RS485_RTS_ON_SEND; //发送前拉高gpio,打开SER_RS485_RTS_AFTER_SEND指的是发送后拉高 rs485conf.flags |= SER_RS485_ENABLED; // 使能本串口485模式,默认禁用 ioctl(iHandle, TIOCSRS485, &rs485conf);