#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); | |
} |