需要串口支持高波特率的应用,手册上看最高可以支持9.5MHz,客户实际测试最高只能测到2.1M,需要帮忙确认一下,串口实际最高波特率能支持到多少,提供相关测试验证方法。
2023/07/07 10:03
用non-os代码进行internal loop back测试是可以达到TRM 所描述的数值,而在Linux我们测试情况是FIFO trigger level 设置为0x30,波特率为6Mbps,在IoT板子 UART10把rx和tx短接进行2K Bytes自发自收100次是正常的。
FIFO trigger level 设置为0x30方法:
1. 驱动
output/build/linux-custom/drivers/tty/serial/ma35d1_serial.c
ma35d1serial_startup()里面
serial_out(up, UART_REG_FCR, serial_in(up, UART_REG_FCR) | 0x10 | 0x20000);
改为
serial_out(up, UART_REG_FCR, serial_in(up, UART_REG_FCR) | 0x30 | 0x20000);
2. 设备树
output/build/linux-custom/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi里面做以下修改
assigned-clocks = <&clk UART10_MUX>;
assigned-clock-parents = <&clk SYSCLK1_DIV2>;
uart10:serial@407A0000 {
compatible = "nuvoton,ma35d1-uart";
reg = <0x0 0x407A0000 0x0 0x10000>;
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk UART10_GATE>;
port-number = <10>;
pdma-enable = <0>;
assigned-clocks = <&clk UART10_MUX>;
assigned-clock-parents = <&clk SYSCLK1_DIV2>;
status = "disabled";
};
3. 波特率修改方式:
static int open_port(const char *portname)
{
struct sigaction sa;
int portfd;
struct termios to;
if((portfd=open(portname,O_RDWR | O_NOCTTY)) < 0 )
{
printf("open serial port %s fail \n ",portname);
return portfd;
}
/*get serial port parnms,save away */
tcgetattr(portfd,&newtios);
memcpy(&oldtios,&newtios,sizeof newtios);
/* configure new values */
cfmakeraw(&newtios); /*see man page */
newtios.c_iflag |=IGNPAR; /*ignore parity on input */
newtios.c_iflag &= ~(IXON | IXOFF | IXANY);
//newtios.c_iflag |= (INPCK | ISTRIP); // for test
newtios.c_oflag &= ~(OPOST | ONLCR | OLCUC | OCRNL | ONOCR | ONLRET | OFILL);
newtios.c_cflag = CS8 | CLOCAL | CREAD;
//newtios.c_cc[VMIN]=1; /* block until 1 char received */
newtios.c_cc[VMIN]=0xff;
newtios.c_cc[VTIME]=0; /*no inter-character timer */
newtios.c_iflag |= CRTSCTS;
/* register cleanup stuff */
atexit(reset_tty_atexit);
memset(&sa,0,sizeof sa);
sa.sa_handler = reset_tty_handler;
sigaction(SIGHUP,&sa,NULL);
sigaction(SIGINT,&sa,NULL);
sigaction(SIGPIPE,&sa,NULL);
sigaction(SIGTERM,&sa,NULL);
/*apply modified termios */
saved_portfd=portfd;
tcflush(portfd,TCIFLUSH);
tcsetattr(portfd,TCSADRAIN,&newtios);
ioctl(portfd, TCGETS2, &tio);
tio.c_cflag &= ~CBAUD;
tio.c_cflag |= BOTHER;
tio.c_ispeed = 6000000;
tio.c_ospeed = 6000000;
ioctl(portfd, TCSETS2, &tio);
return portfd;
}
执行/uart_demo_rx_tx
脚本:
#!/bin/sh
for i in $(seq 1 100)
do
echo "Running command: $i"
/uart_demo_rx_tx
sleep 1
done