嵌入式linux UART驱动

2019-07-12 19:40发布

  #include
#include
#include
#include
#include
#include #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 ",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 ");
    if(port >= MAXNUM_UART)
        return 1;     //if(1 == port) print_logo(0, "232port send ");
    fd = fd_uart[port];     if(fd < 0)
        return 1; // printf("Uart %d Send %d bytes: HEX: ",port,len); //add by boll
// print_hexbuf(buf,len); //add by boll     write(fd, (char *)buf, len); // if(UART_GPRS == port) printf("gprssnd %s ",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 ",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]);
}