| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- /*************************************************************************
- > File Name: uart.c
- > Created Time: Fri 23 Oct 2020 11:02:21 AM CST
- ************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <termios.h>
- #include <limits.h>
- #include <errno.h>
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include "bsp.h"
- #include "rt.h"
- #include "uart_user.h"
- #define UART_MAX_FD 256 //noted by sunxi: 因为传进来的UART_CHANNEL[i]不一定是连续的。
- //static int am335x_uarts_fd[CFG_UART_NUM_MAX];
- static int am335x_uarts_fd[UART_MAX_FD] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,};
- static void am335x_uarts_init(int channel)
- {
- am335x_uarts_fd[channel] = -1;
- }
- static int set_port(int fd, int nSpeed, int nBits, char nEvent, int nStop)
- {
- struct termios newtio, oldtio;
-
- memset(&oldtio, 0, sizeof(oldtio));
- /* save the old serial port configuration */
- if(tcgetattr(fd, &oldtio) != 0) {
- perror("set_port/tcgetattr");
- return -1;
- }
- memset(&newtio, 0, sizeof(newtio));
- /* ignore modem control lines and enable receiver */
- newtio.c_cflag |= CLOCAL | CREAD;
- newtio.c_cflag &= ~CSIZE;
- /* set character size */
- switch (nBits) {
- case 8:
- newtio.c_cflag |= CS8;
- break;
- case 7:
- newtio.c_cflag |= CS7;
- break;
- case 6:
- newtio.c_cflag |= CS6;
- break;
- case 5:
- newtio.c_cflag |= CS5;
- break;
- default:
- newtio.c_cflag |= CS8;
- break;
- }
- /* set the parity */
- switch (nEvent) {
- default:
- case 'N':
- case 'n':
- {
- newtio.c_cflag &= ~PARENB; //清除校验位
- newtio.c_iflag &= ~(ICRNL|INPCK|IXON|IXOFF); //关闭奇偶校验 关闭软件流控
-
- break;
- }
-
- case 'o':
- case 'O':
- {
- newtio.c_cflag |= (PARODD | PARENB); //使用奇校验不是用偶校验
- newtio.c_iflag |= INPCK;
- break;
- }
-
- case 'e':
- case 'E':
- {
- newtio.c_cflag |= PARENB;
- newtio.c_cflag &= ~PARODD; //使用偶校验
- newtio.c_iflag |= INPCK;
- break;
- }
-
- case 's':
- case 'S':
- {
- newtio.c_cflag &= ~PARENB;
- newtio.c_cflag &= ~CSTOPB;
- break;
- }
-
- }
- /* set the stop bits */
- switch (nStop) {
- case 1:
- newtio.c_cflag &= ~CSTOPB;
- break;
- case 2:
- newtio.c_cflag |= CSTOPB;
- break;
- default:
- newtio.c_cflag &= ~CSTOPB;
- break;
- }
- /* set output and input baud rate */
- switch (nSpeed) {
- case 0:
- cfsetospeed(&newtio, B0);
- cfsetispeed(&newtio, B0);
- break;
- case 50:
- cfsetospeed(&newtio, B50);
- cfsetispeed(&newtio, B50);
- break;
- case 75:
- cfsetospeed(&newtio, B75);
- cfsetispeed(&newtio, B75);
- break;
- case 110:
- cfsetospeed(&newtio, B110);
- cfsetispeed(&newtio, B110);
- break;
- case 134:
- cfsetospeed(&newtio, B134);
- cfsetispeed(&newtio, B134);
- break;
- case 150:
- cfsetospeed(&newtio, B150);
- cfsetispeed(&newtio, B150);
- break;
- case 200:
- cfsetospeed(&newtio, B200);
- cfsetispeed(&newtio, B200);
- break;
- case 300:
- cfsetospeed(&newtio, B300);
- cfsetispeed(&newtio, B300);
- break;
- case 600:
- cfsetospeed(&newtio, B600);
- cfsetispeed(&newtio, B600);
- break;
- case 1200:
- cfsetospeed(&newtio, B1200);
- cfsetispeed(&newtio, B1200);
- break;
- case 1800:
- cfsetospeed(&newtio, B1800);
- cfsetispeed(&newtio, B1800);
- break;
- case 2400:
- cfsetospeed(&newtio, B2400);
- cfsetispeed(&newtio, B2400);
- break;
- case 4800:
- cfsetospeed(&newtio, B4800);
- cfsetispeed(&newtio, B4800);
- break;
- case 9600:
- cfsetospeed(&newtio, B9600);
- cfsetispeed(&newtio, B9600);
- break;
- case 19200:
- cfsetospeed(&newtio, B19200);
- cfsetispeed(&newtio, B19200);
- break;
- case 38400:
- cfsetospeed(&newtio, B38400);
- cfsetispeed(&newtio, B38400);
- break;
- case 57600:
- cfsetospeed(&newtio, B57600);
- cfsetispeed(&newtio, B57600);
- break;
- case 115200:
- cfsetospeed(&newtio, B115200);
- cfsetispeed(&newtio, B115200);
- break;
- case 230400:
- cfsetospeed(&newtio, B230400);
- cfsetispeed(&newtio, B230400);
- break;
- default:
- cfsetospeed(&newtio, B115200);
- cfsetispeed(&newtio, B115200);
- break;
- }
- /* set timeout in deciseconds for non-canonical read */
- newtio.c_cc[VTIME] = 0;
- /* set minimum number of characters for non-canonical read */
- newtio.c_cc[VMIN] = 0;
- /* flushes data received but not read */
- tcflush(fd, TCIFLUSH);
- /* set the parameters associated with the terminal from
- the termios structure and the change occurs immediately */
- if((tcsetattr(fd, TCSANOW, &newtio))!=0)
- {
- perror("set_port/tcsetattr");
- return -1;
- }
-
- return 0;
- }
- int uart_open(int channel, uint32_t baudRate, int setting)
- {
- /*
- * Initialize UART for serial communications
- */
- char tty_name[16] = {0x00};
- int ret;
- char parity;
- if(channel > (UART_MAX_FD - 1) || channel < 0)
- {
- return -1;
- }
- if (am335x_uarts_fd[channel] < 0)
- {
- am335x_uarts_init(channel);
- memset(tty_name,0,sizeof(tty_name));
- sprintf(tty_name, "/dev/ttyAS%d", channel); //sprintf(tty_name, "/dev/ttyO%d", channel); by ygl 2025.6.13
- am335x_uarts_fd[channel] = open(tty_name, O_RDWR, 0);
- if(am335x_uarts_fd[channel] < 0)
- {
- printf("inside open %s failed!\n", tty_name);
- return am335x_uarts_fd[channel];
- }
- }
-
- switch(setting)
- {
- case PARITY_EVEN://偶校验
- parity = 'E';
- break;
- case PARITY_ODD://奇校验
- parity = 'O';
- break;
- case PARITY_NONE://无校验
- default:
- parity = 'N';
- break;
- }
- ret = set_port(am335x_uarts_fd[channel], baudRate, 8, parity, 1);
- if(ret < 0)
- {
- close(am335x_uarts_fd[channel]);
- perror("set_port failed");
- return -2;
- }
-
- return 0;
- }
- void uart_close(int channel)
- {
- if(channel > (UART_MAX_FD - 1))
- {
- return;
- }
- if(am335x_uarts_fd[channel] >= 0)
- {
- close(am335x_uarts_fd[channel]);
- am335x_uarts_fd[channel] = -1;
- }
- }
- int uart_write(int channel, const char *data, int count)
- {
- int ret;
- if((channel > (UART_MAX_FD - 1)) || (data == NULL))
- return -1;
- if(am335x_uarts_fd[channel] < 0)
- return -2;
- ret = write(am335x_uarts_fd[channel], data, count);
- return ret;
- }
- void uart_puts (int channel, char *ch)
- {
- int write_len;
- if(ch == NULL)
- return;
- write_len = strlen(ch);
- uart_write(channel, (const char *)ch, write_len);
- }
- int uart_read(int channel, char *data, int count)
- {
- int ret;
- if((channel > (UART_MAX_FD - 1)) || (data == NULL))
- return -1;
- if(am335x_uarts_fd[channel] < 0)
- return -2;
- ret = read(am335x_uarts_fd[channel], data, count);
- return ret;
- }
- //noted by sunxi: 这个是read的select.
- int uart_select(int channel)
- {
- int ret;
- struct timeval tv;
- fd_set rset;
- tv.tv_sec = 0;
- tv.tv_usec = 10000;
- if(channel > (UART_MAX_FD - 1))
- return -1;
- if(am335x_uarts_fd[channel] < 0)
- return -2;
-
- FD_ZERO(&rset);
- FD_SET(am335x_uarts_fd[channel], &rset);
- ret = select(am335x_uarts_fd[channel]+1, &rset, NULL, NULL, &tv);
- return ret;
- }
- /********************************************************************/
- /*
- * Wait for a character to be received on the specified UART
- *
- * Return Values:
- * the received character
- */
- char uart_getchar (int channel)
- {
- return 0;
- }
- int uart_getchar2 (int channel,char *ch)
- {
- int ret = uart_read(channel, ch, 1);
- return ret;
- }
- /********************************************************************/
- /*
- * Wait for space in the UART Tx FIFO and then send a character
- */
- void uart_putchar (int channel, char ch)
- {
- }
- void uart_putchar2 (int channel, char ch)
- {
- uart_write(channel, (const char *)&ch, 1);
- }
- int uart_init(void)
- {
- int i, ret;
- for(i = 0; i < CFG_UART_NUM_MAX; i++)
- {
- if((UART_CHANNEL[i]==g_con_uart_index) || (UART_CHANNEL[i]==CFG_UART_HMI))
- {
- continue;
- }
- ret = uart_open(i,115200,PARITY_NONE);
- if (ret < 0)
- {
- #ifdef UART_DEBUG
- printf("%s: outside uart %d open failed!\n", __FUNCTION__, i);
- #endif
- }
- else
- {
- #ifdef UART_DEBUG
- printf("%s: outside uart %d open success!\n", __FUNCTION__, i);
- #endif
- }
- }
- return 0;
- }
- void uart_exit(void)
- {
- int i;
- printf("uart_exit\n");//sunxi for test
- for(i = 0; i < CFG_UART_NUM_MAX; i++)
- {
- if((UART_CHANNEL[i]==g_con_uart_index) || (UART_CHANNEL[i]==CFG_UART_HMI))
- {
- continue;
- }
- uart_close(i);
- }
- }
- int uart_test(void)
- {
- char tmp[] = "hello sunxi!";
- // u8 c;
- int ret;
- static unsigned char buf[256];
- static int ret_cnt =0;
- int i;
-
- uart_open(1,9600,PARITY_EVEN);
- uart_write(1, (const char *)&tmp, strlen(tmp));
- for(i = 0; i < 500; i++)
- {
- ret = uart_select(1);
- //有数据可读
- if(ret > 0)
- {
- printf("\nch_%d have select.",1);
-
- //读取数据
- memset(buf,0,sizeof(buf));
- ret = uart_read(1, buf, sizeof(buf));
- if(ret != -1)
- {
- //测试代码
- printf("\nch_%d RECV num=%d:",1,ret);
- for(i = 0; i < ret; i++)
- {
- printf("%02x ", (unsigned char)buf[i]);
- }
- printf("\n");
- if(++ret_cnt >= 3)
- {
- ret_cnt = 0;
- uart_write(1, buf, ret);
- }
- }
-
- }
-
- }
- return 0;
- }
|