#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include "appuart.h"
static int speed_arr[] = { B115200, B57600, B38400, B19200, B9600,
B4800, B2400, B1200, B600, B300,
};
static int name_arr[] = { 115200, 57600, 38400, 19200, 9600,
4800, 2400, 1200, 600, 300,
} ;
static int fd_uart[MAXNUM_UART] = {-1, -1, -1, -1};
//extern int semgprsuart;
extern struct gprsdev_t *gprs_devp;
#define SIZE_APPUART_RCVBUF 2048
struct appuart_rcvst
{
char buf[SIZE_APPUART_RCVBUF];
int len;
int head;
};
static struct appuart_rcvst appuart_rcvbuf[MAXNUM_UART];
int appuart_open(unsigned int port)
{
char dev[16];
int fd;
if(port >= MAXNUM_UART)
return 1;
if(-1 != fd_uart[port])
close(fd_uart[port]);
sprintf(dev, "/dev/ttyS%d", port+1);
fd = open(dev, O_RDWR|O_NONBLOCK);
if(-1 == fd)
return 1;
// printf("uartport:%d,fd:%d\n",port,fd); //add by boll
fd_uart[port] = fd;
appuart_rcvbuf[port].len = 0;
return 0;
}
void appuart_close(unsigned int port)
{
if((port >= MAXNUM_UART) || (-1 == fd_uart[port]))
return;
close(fd_uart[port]);
fd_uart[port] = -1;
}
void appuart_set_speed(unsigned int port, int speed)
{
int i;
int status;
struct termios Opt;
int fd;
if(port >= MAXNUM_UART)
return;
fd = fd_uart[port];
if(fd < 0)
return;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if (speed == name_arr[i])
{
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0)
{
perror("tcsetattr fd1");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
void appuart_set_parity(unsigned int port, int databits,int stopbits, char parity)
{
struct termios options;
int fd;
if(port >= MAXNUM_UART)
return;
fd = fd_uart[port];
if(fd < 0)
return;
if(tcgetattr(fd, &options) != 0)
return;
options.c_iflag = 0;
options.c_cflag &= ~CSIZE;
switch (databits)
{
case 5:
options.c_cflag |= CS5;
break;
case 6:
options.c_cflag |= CS6;
break;
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
return;
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB);
options.c_iflag |= INPCK;
break;
case 'e':
case 'E':
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_iflag |= INPCK;
break;
case 'S':
case 's':
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
return;
}
switch(stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
return;
}
options.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC); //add 2007-10-19
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
tcflush(fd, TCIFLUSH);
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
if (tcsetattr(fd, TCSANOW, &options) != 0)
return;
}
void appuart_set(unsigned int port, int speed, int databits, int stopbits, char parity)
{
appuart_set_speed(port, speed);
appuart_set_parity(port, databits, stopbits, parity);
}
int appuart_send(unsigned int port, unsigned char *buf, int len)
{
int fd;
//if(0 == port) print_logo(0, "gprs port send\r\n");
if(port >= MAXNUM_UART)
return 1;
//if(1 == port) print_logo(0, "232port send\r\n");
fd = fd_uart[port];
if(fd < 0)
return 1;
// printf("Uart %d Send %d bytes:\nHEX:\n",port,len); //add by boll
// print_hexbuf(buf,len); //add by boll
write(fd, (char *)buf, len);
// if(UART_GPRS == port) printf("gprssnd %s\n",buf);
return 0;
}
int appuart_recv(unsigned int port, unsigned char *buf, int len)
{
int fd, rtn;
if(port >= MAXNUM_UART)
return -1;
fd = fd_uart[port];
if(fd < 0)
return -1;
if(appuart_rcvbuf[port].len <= 0)
{
appuart_rcvbuf[port].len = 0;
appuart_rcvbuf[port].head = 0;
rtn = read(fd,appuart_rcvbuf[port].buf,SIZE_APPUART_RCVBUF);
if((rtn <=0) || (rtn > SIZE_APPUART_RCVBUF))
return 0;
appuart_rcvbuf[port].len = rtn;
}
if(appuart_rcvbuf[port].len > len)
rtn = len;
else
rtn = appuart_rcvbuf[port].len;
memcpy(buf, &appuart_rcvbuf[port].buf[appuart_rcvbuf[port].head], rtn);
appuart_rcvbuf[port].len -= rtn;
appuart_rcvbuf[port].head += rtn;
return rtn;
}
int appuart_getch(unsigned int port, unsigned char *buf)
{
int fd, rtn;
if(port >= MAXNUM_UART) return -1;
fd = fd_uart[port];
if(fd < 0) return -1;
if(appuart_rcvbuf[port].len <= 0)
{
appuart_rcvbuf[port].len = 0;
appuart_rcvbuf[port].head = 0;
rtn = read(fd, appuart_rcvbuf[port].buf, SIZE_APPUART_RCVBUF);
if((rtn <=0) || (rtn > SIZE_APPUART_RCVBUF)) return 0;
appuart_rcvbuf[port].len = rtn;
//printf( "rx %d\n",rtn);
}
if(appuart_rcvbuf[port].len > 0)
{
*buf = appuart_rcvbuf[port].buf[appuart_rcvbuf[port].head++];
appuart_rcvbuf[port].len --;
// print_hexbuf((UCHAR*)buf,12);
return 1;
}
return -1;
}
int appuart_getfd(unsigned int port)
{
if(port >= MAXNUM_UART)
return -1;
return(fd_uart[port]);
}