| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <fcntl.h> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <string.h> | |
| #include <errno.h> | |
| #include <termios.h> | |
| #include <unistd.h> | |
| #include <stdint.h> | |
| #include <sys/ioctl.h> | |
| #include <dlfcn.h> | |
| #include "gsw_uart_interface.h" | |
| #define MODEM_CONNECT_MCU_PORT "/dev/ttyS1" | |
| #include "gsw_log_interface.h" | |
| #define GSW_UART "[HAL][GSW_UART]" | |
| typedef enum | |
| { | |
| GSW_HAL_BAUDRATE_1200=1200, | |
| GSW_HAL_BAUDRATE_1800=1800, | |
| GSW_HAL_BAUDRATE_4800=4800, | |
| GSW_HAL_BAUDRATE_9600=9600, | |
| GSW_HAL_BAUDRATE_19200=19200, | |
| GSW_HAL_BAUDRATE_38400=38400, | |
| GSW_HAL_BAUDRATE_57600=57600, | |
| GSW_HAL_BAUDRATE_115200=115200, | |
| GSW_HAL_BAUDRATE_230400=230400, | |
| GSW_HAL_BAUDRATE_460800=460800, | |
| GSW_HAL_BAUDRATE_500000=500000, | |
| GSW_HAL_BAUDRATE_576000=576000, | |
| GSW_HAL_BAUDRATE_921600=921600 | |
| }gsw_hal_uart_baudrate; | |
| static inline int handle() | |
| { | |
| return GSW_HAL_SUCCESS; | |
| } | |
| int32_t gsw_uart_open_ex(int8_t *port, gsw_hal_uart_baudrate baudrate, uint32_t bits, int8_t parity, uint32_t stop) | |
| { | |
| if (handle()) | |
| return GSW_HAL_NORMAL_FAIL; | |
| int fd = -1; | |
| if((fd = open((const char *)port, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) | |
| { | |
| LOGE(GSW_UART,"open %s failed - %d", port, errno); | |
| return -1; | |
| } | |
| LOGD(GSW_UART,"Open %s success.", port); | |
| /* set newtio */ | |
| struct termios newtio; | |
| memset(&newtio, 0, sizeof(newtio)); | |
| if (tcflush(fd, TCIOFLUSH) < 0) { | |
| LOGE(GSW_UART,"Could not flush uart port"); | |
| return -1; | |
| } | |
| newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ | |
| newtio.c_cc[VMIN] = 0; /* blocking read until 5 chars received */ | |
| /* c_iflag 输入模式 */ | |
| newtio.c_iflag &= ~(ICRNL | INLCR); | |
| newtio.c_iflag &= ~(IXON | IXOFF | IXANY); | |
| // /* c_lflag 本地模式 */ | |
| newtio.c_cflag &= ~ INPCK; | |
| newtio.c_cflag |= (CLOCAL | CREAD); | |
| // /* c_lflag 本地模式 */ | |
| newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); | |
| /* c_oflag 输出模式 */ | |
| newtio.c_oflag &= ~ OPOST; | |
| newtio.c_oflag &= ~(ONLCR | OCRNL); | |
| /* c_cflag 控制模式 */ | |
| newtio.c_cflag &= ~ CSIZE; | |
| newtio.c_cflag |= CS8; | |
| newtio.c_cflag &= ~ CSTOPB; | |
| newtio.c_cflag &= ~ PARENB; | |
| switch(baudrate) | |
| { | |
| case GSW_HAL_BAUDRATE_1200: | |
| cfsetospeed(&newtio, B1200); | |
| cfsetispeed(&newtio, B1200); | |
| break; | |
| case GSW_HAL_BAUDRATE_1800: | |
| cfsetospeed(&newtio, B1800); | |
| cfsetispeed(&newtio, B1800); | |
| break; | |
| case GSW_HAL_BAUDRATE_4800: | |
| cfsetospeed(&newtio, B4800); | |
| cfsetispeed(&newtio, B4800); | |
| break; | |
| case GSW_HAL_BAUDRATE_9600: | |
| cfsetospeed(&newtio, B9600); | |
| cfsetispeed(&newtio, B9600); | |
| break; | |
| case GSW_HAL_BAUDRATE_19200: | |
| cfsetospeed(&newtio, B19200); | |
| cfsetispeed(&newtio, B19200); | |
| break; | |
| case GSW_HAL_BAUDRATE_38400: | |
| cfsetospeed(&newtio, B38400); | |
| cfsetispeed(&newtio, B38400); | |
| break; | |
| case GSW_HAL_BAUDRATE_57600: | |
| cfsetospeed(&newtio, B57600); | |
| cfsetispeed(&newtio, B57600); | |
| break; | |
| case GSW_HAL_BAUDRATE_115200: | |
| cfsetospeed(&newtio, B115200); | |
| cfsetispeed(&newtio, B115200); | |
| break; | |
| case GSW_HAL_BAUDRATE_230400: | |
| cfsetospeed(&newtio, B230400); | |
| cfsetispeed(&newtio, B230400); | |
| break; | |
| case GSW_HAL_BAUDRATE_460800: | |
| cfsetospeed(&newtio, B460800); | |
| cfsetispeed(&newtio, B460800); | |
| break; | |
| case GSW_HAL_BAUDRATE_500000: | |
| cfsetospeed(&newtio, B500000); | |
| cfsetispeed(&newtio, B500000); | |
| break; | |
| case GSW_HAL_BAUDRATE_576000: | |
| cfsetospeed(&newtio, B576000); | |
| cfsetispeed(&newtio, B576000); | |
| break; | |
| case GSW_HAL_BAUDRATE_921600: | |
| cfsetospeed(&newtio, B921600); | |
| cfsetispeed(&newtio, B921600); | |
| break; | |
| default: | |
| cfsetospeed(&newtio, B115200); | |
| cfsetispeed(&newtio, B115200); | |
| break; | |
| } | |
| switch(bits) | |
| { | |
| case 5: | |
| newtio.c_cflag &= ~CSIZE; | |
| newtio.c_cflag |= CS5; | |
| break; | |
| case 6: | |
| newtio.c_cflag &= ~CSIZE; | |
| newtio.c_cflag |= CS6; | |
| break; | |
| case 7: | |
| newtio.c_cflag &= ~CSIZE; | |
| newtio.c_cflag |= CS7; | |
| break; | |
| case 8: | |
| newtio.c_cflag &= ~CSIZE; | |
| newtio.c_cflag |= CS8; | |
| break; | |
| default: | |
| LOGD(GSW_UART,"No set databit."); | |
| break; | |
| } | |
| if(stop == 2) { | |
| newtio.c_cflag |= CSTOPB; | |
| } else { | |
| newtio.c_cflag &= ~CSTOPB; | |
| } | |
| switch (parity) | |
| { | |
| case 'O': | |
| case 'o':// 奇校验 | |
| newtio.c_cflag |= PARENB; | |
| newtio.c_cflag |= PARODD; | |
| break; | |
| case 'E': | |
| case 'e':// 偶校验 | |
| newtio.c_cflag |= PARENB; | |
| newtio.c_cflag &= ~PARODD; | |
| break; | |
| case 'N': | |
| case 'n':// 无奇偶校验 | |
| newtio.c_cflag &= ~PARENB; | |
| break; | |
| default: | |
| LOGD(GSW_UART,"No set parity."); | |
| break; | |
| } | |
| if (tcsetattr(fd, TCSANOW, &newtio) < 0) { | |
| LOGE(GSW_UART,"Can't set port setting"); | |
| return -1; | |
| } | |
| return fd; | |
| } | |
| void gsw_uart_flush(int32_t fd) | |
| { | |
| if (handle()) | |
| return; | |
| if (tcflush(fd, TCIOFLUSH) < 0) | |
| { | |
| LOGE(GSW_UART,"flush fail\n"); | |
| //return GSW_HAL_NORMAL_FAIL; | |
| } | |
| else | |
| LOGD(GSW_UART,"flush success\n"); | |
| //return GSW_HAL_SUCCESS; | |
| } | |
| int gsw_uart_read(int fd, unsigned char *buffer, int len, int timeout_ms) | |
| { | |
| if (handle()) | |
| return GSW_HAL_NORMAL_FAIL; | |
| if(len <= 0 || timeout_ms < -1) | |
| { | |
| LOGE(GSW_UART,"timeout_ms = %d, len = %d; timeout_ms needs to be greater than -1 and len needs to be greater than 0!\n",timeout_ms, len); | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| int flags = fcntl(fd, F_GETFL); // 获取当前状态标志 | |
| if (flags == -1) | |
| { | |
| perror("fcntl get"); | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| struct termios newtio; | |
| if (tcgetattr(fd, &newtio) < 0) { | |
| perror("tcgetattr failed"); | |
| return -1; | |
| } | |
| if (timeout_ms == 0) | |
| { | |
| flags |= O_NONBLOCK; // 设置非阻塞标志 | |
| fcntl(fd, F_SETFL, flags); | |
| newtio.c_cc[VMIN] = 0; | |
| newtio.c_cc[VTIME] = 0; | |
| } | |
| else if (timeout_ms == -1) | |
| { | |
| flags &= ~O_NONBLOCK; // 清除非阻塞标志 | |
| fcntl(fd, F_SETFL, flags); | |
| newtio.c_cc[VMIN] = 1; | |
| newtio.c_cc[VTIME] = 0; | |
| } | |
| else | |
| { | |
| flags &= ~O_NONBLOCK; // 清除非阻塞标志 | |
| fcntl(fd, F_SETFL, flags); | |
| newtio.c_cc[VMIN] = 0; | |
| newtio.c_cc[VTIME] = timeout_ms/100; | |
| } | |
| if(timeout_ms != 0) | |
| LOGI(GSW_UART,"%s :VMIN = %d ;VTIME = %d\n",__func__,newtio.c_cc[VMIN],newtio.c_cc[VTIME]); | |
| if (tcsetattr(fd, TCSANOW, &newtio) != 0) | |
| { | |
| perror("tcsetattr"); | |
| return -1; | |
| } | |
| //gsw_uart_flush(fd); | |
| int data_len = read(fd, buffer, len); | |
| if (data_len < 0) | |
| { | |
| if(errno == EAGAIN || errno == EWOULDBLOCK) | |
| return 0; | |
| else | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| return data_len; | |
| } | |
| int gsw_uart_write(int fd, const unsigned char *buffer, int len) | |
| { | |
| //gsw_uart_flush(fd); | |
| if (write(fd, buffer, len) < 0) | |
| { | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| return GSW_HAL_SUCCESS; | |
| } | |
| int32_t gsw_uart_ioctl(int32_t fd, uint32_t cmd, void *pvalue) | |
| { | |
| if (handle()) | |
| return GSW_HAL_NORMAL_FAIL; | |
| if (fd < 0 || pvalue == NULL) | |
| { | |
| LOGE(GSW_UART,"Invalid file descriptor"); | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| if (ioctl(fd, cmd, pvalue) < 0) | |
| { | |
| LOGE(GSW_UART,"Could not set DCB,error:%d, %s\n",errno, strerror(errno)); | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| return GSW_HAL_SUCCESS; | |
| } | |
| void gsw_uart_close(int fd) | |
| { | |
| if (handle()) | |
| return; | |
| if (fd <= 0) | |
| LOGE(GSW_UART,"fd = %d fail\n",fd); | |
| //return GSW_HAL_NORMAL_FAIL; | |
| else | |
| { | |
| //gsw_uart_flush(fd); | |
| int ret = close(fd); | |
| if(ret < 0) | |
| { | |
| LOGE(GSW_UART,"close fail ret = %d\n",ret); | |
| } | |
| else | |
| { | |
| LOGI(GSW_UART,"close success ret = %d\n",ret); | |
| } | |
| } | |
| //return GSW_HAL_SUCCESS; | |
| } | |
| int gsw_uart_open(unsigned int baudrate, unsigned int bits, char parity, unsigned int stop) | |
| { | |
| return gsw_uart_open_ex((int8_t *)MODEM_CONNECT_MCU_PORT, (gsw_hal_uart_baudrate)baudrate, bits, parity, stop); | |
| } |