blob: d706aaee74f729dbd35541864e1a1b2cd6ce752d [file] [log] [blame]
#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);
}