#ifndef __UART_H_
#define __UART_H_
//#include "njrc_buc_ctr.h"
//#include "wavstr_buc_ctr.h"
#define    UART0                "/dev/ttyAT1"    //0
#define UART1                "/dev/ttyAT2"    //1
#define UART2                "/dev/ttyAT3"    //2
#define WIFI_UART            "/dev/ttyAT4"    //3 modem控制的串口
#define UART_422            "/dev/ttyAT5"    //422 功放控制串口
#define FSK_UART            "/dev/ttyAT6"    //
#define UART_TEST            "/dev/ttyS1"
//#define UART_TEST            "/dev/ttyUSB0"
#define BUC_CTR_UART UART0
#define FALSE    0
#define TRUE    1
#define _DEBUG    1
extern int buc_uart_fd;
extern int buc_init(const char * uart_dev);
//extern int buc_write(SET_BUC_DATA *send_buc_data,const int fd);
//extern int buc_read(GET_BUC_DATA * buc_buf, int fd);

#endif

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include "uart.h"
//#include "njrc_buc_ctr.h"
//#include "wavstr_buc_ctr.h"
int buc_uart_fd = 0;

static int speed_arr[] =
    { B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200 };
static int name_arr[] =
    { 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200 };

void set_speed(int fd, int speed)
{
    int i;
    int status;
    struct termios Opt;

    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);
    }
}
int set_Parity(int fd, int databits, int stopbits, int parity)
{
    struct termios options;

    if (tcgetattr(fd, &options) != 0) {
        perror("SetupSerial 1");
        return FALSE;
    }
    options.c_cflag &= ~CSIZE;
    switch (databits) {
    case 7:
        options.c_cflag |= CS7;
        break;
    case 8:
        options.c_cflag |= CS8;
        break;
    default:
        fprintf(stderr, "Unsupported data size\n");
        return FALSE;
    }
    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:
        fprintf(stderr, "Unsupported parity\n");
        return FALSE;
    }
    switch (stopbits) {
    case 1:
        options.c_cflag &= ~CSTOPB;
        break;
    case 2:
        options.c_cflag |= CSTOPB;
        break;
    default:
        fprintf(stderr, "Unsupported stop bits\n");
        return FALSE;
    }

    options.c_iflag &=
        ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL |
          IXON);
    options.c_oflag &= ~OPOST;
    options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);

    /* Set input parity option */
    if (parity != 'n') {
        options.c_iflag |= INPCK;
    }
    options.c_cc[VTIME] = 150;    // 15 seconds
    options.c_cc[VMIN] = 0;

    tcflush(fd, TCIFLUSH);        /* Update the options and do it NOW */
    if (tcsetattr(fd, TCSANOW, &options) != 0) {
        perror("SetupSerial 3");
        return FALSE;
    }
    return TRUE;
}

/*=============================================================
 * * Function    : buc_init
 * * Description : open buc com
 * * Input Para  : ttyS(num)
 * * Output Para : buc_fd,dev fd
 * * Return Value: if error return -1 ,else return dev fd
 * *=============================================================*/
int buc_init(const char * uart_dev)
{
    int uart_fd = -1;

    if ((uart_fd = open(uart_dev, O_RDWR | O_NONBLOCK)) < 0)    // buc
    {

        perror("open() uart_fd");
        uart_fd = open(uart_dev, O_RDWR | O_NONBLOCK);
    }else;
    set_speed(uart_fd, 9600);
    if (set_Parity(uart_fd, 8, 1, 'N') == 0)
        close(uart_fd);
    return uart_fd;
}

#if 0
/*=============================================================
 * * Function    : buc_write
 * * Description : write to buc cmd
 * * Input Para  : write msg, dev_fd
 * * Output Para : NULL
 * * Return Value: if error return -1 ,else return 0
 * *=============================================================*/
int buc_write(SET_BUC_DATA *send_buc_data,const int fd)
{
    char buf[100] = { 0 };
    int size, ret = 0, pos = 0;

    size = send_buc_data->buc_buf_len;
    memcpy(buf, send_buc_data->set_buc_buf, size);
    while (size > 0) {
        ret = write(fd, buf + pos, size);
        if (ret < 0) {
            if (errno == EINTR) {
                continue;
            }else{
                perror("write()");
                return -1;
            }
        }else;
        size -= ret;
        pos += ret;

    }
    return 0;
}

/*=============================================================
 * * Function    : buc_read
 * * Description : read msg from buc
 * * Input Para  : read msg struct addr, dev_fd
 * * Output Para : read msg
 * * Return Value: if error return -1 ,else return 0
 * *=============================================================*/
int buc_read(GET_BUC_DATA * buc_buf, int fd)
{
    int num = 0, num_tmp = 0, return_num = 0;
    char i = 0;
    int loop = 50;
    if(buc_buf->buc_buf_len < 1)
        buc_buf->buc_buf_len = 47;
    buc_buf->read_len = 0;
    if (fd < 1) {
        fd = buc_init(BUC_CTR_UART);
        buc_uart_fd = fd;
    }
    if (fd > 0) {
        while (loop) {
            usleep(300);
            num_tmp = read(fd, &(buc_buf->get_buc_buf[num]), buc_buf->buc_buf_len+1);
            if(num_tmp > -1){
                num += num_tmp;
            }else;
            if (num >= buc_buf->buc_buf_len) {
                break;
            } else;
            loop--;
        }
//        if (num >= buc_buf->buc_buf_len) {
#if _DEBUG
            printf("num:%d\n",num);
            for (i = 0; i < num; i++) {
                //printf("[%d][%02x]%c ",i, buc_buf->get_buc_buf[i], buc_buf->get_buc_buf[i]);
                printf("[%d]%c " ,i,buc_buf->get_buc_buf[i]);
            }
            printf("\n");
#endif
//         } else;
    }else
        return_num = -1;

    buc_buf->read_len = num;
    return return_num;
}
#endif