| #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 "mbtk_log.h" | 
 | #include "ql/ql_uart.h" | 
 |  | 
 | int Ql_UART_Open(const char* port, Enum_BaudRate baudrate, Enum_FlowCtrl flowctrl) | 
 | { | 
 |     int fd; | 
 |     if((fd = open(port, O_RDWR | O_NOCTTY)) < 0) | 
 |     { | 
 |         LOGE("open %s failed - %d", port, errno); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     LOGD("Open %s success.", port); | 
 |  | 
 |     /* set newtio */ | 
 |     struct termios newtio; | 
 |     memset(&newtio, 0, sizeof(newtio)); | 
 |     if (tcflush(fd, TCIOFLUSH) < 0) { | 
 |         LOGE("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 */ | 
 |  | 
 |     if(flowctrl == FC_RTSCTS) { | 
 |         newtio.c_cflag |= CRTSCTS; | 
 |     } else if(flowctrl == FC_XONXOFF) { | 
 |         newtio.c_cflag |= (IXON | IXOFF); | 
 |     } else { | 
 |         // newtio.c_cflag |= CRTSCTS; | 
 |     } | 
 |         /* 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 B_300: | 
 |             cfsetospeed(&newtio, B300); | 
 |             cfsetispeed(&newtio, B300); | 
 |             break; | 
 |         case B_600: | 
 |             cfsetospeed(&newtio, B600); | 
 |             cfsetispeed(&newtio, B600); | 
 |             break; | 
 |         case B_1200: | 
 |             cfsetospeed(&newtio, B1200); | 
 |             cfsetispeed(&newtio, B1200); | 
 |             break; | 
 |         case B_2400: | 
 |             cfsetospeed(&newtio, B2400); | 
 |             cfsetispeed(&newtio, B2400); | 
 |             break; | 
 |         case B_4800: | 
 |             cfsetospeed(&newtio, B4800); | 
 |             cfsetispeed(&newtio, B4800); | 
 |             break; | 
 |         case B_9600: | 
 |             cfsetospeed(&newtio, B9600); | 
 |             cfsetispeed(&newtio, B9600); | 
 |             break; | 
 |         case B_19200: | 
 |             cfsetospeed(&newtio, B19200); | 
 |             cfsetispeed(&newtio, B19200); | 
 |             break; | 
 |         case B_38400: | 
 |             cfsetospeed(&newtio, B38400); | 
 |             cfsetispeed(&newtio, B38400); | 
 |             break; | 
 |         case B_57600: | 
 |             cfsetospeed(&newtio, B57600); | 
 |             cfsetispeed(&newtio, B57600); | 
 |             break; | 
 |         case B_115200: | 
 |             cfsetospeed(&newtio, B115200); | 
 |             cfsetispeed(&newtio, B115200); | 
 |             break; | 
 |         case B_230400: | 
 |             cfsetospeed(&newtio, B230400); | 
 |             cfsetispeed(&newtio, B230400); | 
 |             break; | 
 |         case B_460800: | 
 |             cfsetospeed(&newtio, B460800); | 
 |             cfsetispeed(&newtio, B460800); | 
 |             break; | 
 |         case B_921600: | 
 |             cfsetospeed(&newtio, B921600); | 
 |             cfsetispeed(&newtio, B921600); | 
 |             break; | 
 |         case B_3000000: | 
 |             cfsetospeed(&newtio, B3000000); | 
 |             cfsetispeed(&newtio, B3000000); | 
 |             break; | 
 |         case B_4000000: | 
 |             cfsetospeed(&newtio, B4000000); | 
 |             cfsetispeed(&newtio, B4000000); | 
 |             break; | 
 |         default: | 
 |             cfsetospeed(&newtio, B115200); | 
 |             cfsetispeed(&newtio, B115200); | 
 |             break; | 
 |     } | 
 |  | 
 |     if (tcsetattr(fd, TCSANOW, &newtio) < 0) { | 
 |         LOGE("Can't set port setting"); | 
 |         return -1; | 
 |     } | 
 |     /* Blocking behavior */ | 
 |     fcntl(fd, F_SETFL, 0); | 
 |  | 
 |     return fd; | 
 | } | 
 |  | 
 | int Ql_UART_Read(int fd, char* buf, unsigned int buf_len) | 
 | { | 
 |     return read(fd, buf, buf_len); | 
 | } | 
 |  | 
 |  | 
 | int Ql_UART_Write(int fd, const char* buf, unsigned int buf_len) | 
 | { | 
 |     return write(fd, buf, buf_len); | 
 | } | 
 |  | 
 |  | 
 | int Ql_UART_SetDCB(int fd, ST_UARTDCB *dcb) | 
 | { | 
 |     struct termios newtio; | 
 |     memset(&newtio, 0, sizeof(newtio)); | 
 |  | 
 |     if(tcgetattr(fd, &newtio) != 0) | 
 |     { | 
 |         LOGE("Serial port configuration backup errno"); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     switch(dcb->baudrate) | 
 |     { | 
 |         case B_300: | 
 |             cfsetospeed(&newtio, B300); | 
 |             cfsetispeed(&newtio, B300); | 
 |             break; | 
 |         case B_600: | 
 |             cfsetospeed(&newtio, B600); | 
 |             cfsetispeed(&newtio, B600); | 
 |             break; | 
 |         case B_1200: | 
 |             cfsetospeed(&newtio, B1200); | 
 |             cfsetispeed(&newtio, B1200); | 
 |             break; | 
 |         case B_2400: | 
 |             cfsetospeed(&newtio, B2400); | 
 |             cfsetispeed(&newtio, B2400); | 
 |             break; | 
 |         case B_4800: | 
 |             cfsetospeed(&newtio, B4800); | 
 |             cfsetispeed(&newtio, B4800); | 
 |             break; | 
 |         case B_9600: | 
 |             cfsetospeed(&newtio, B9600); | 
 |             cfsetispeed(&newtio, B9600); | 
 |             break; | 
 |         case B_19200: | 
 |             cfsetospeed(&newtio, B19200); | 
 |             cfsetispeed(&newtio, B19200); | 
 |             break; | 
 |         case B_38400: | 
 |             cfsetospeed(&newtio, B38400); | 
 |             cfsetispeed(&newtio, B38400); | 
 |             break; | 
 |         case B_57600: | 
 |             cfsetospeed(&newtio, B57600); | 
 |             cfsetispeed(&newtio, B57600); | 
 |             break; | 
 |         case B_115200: | 
 |             cfsetospeed(&newtio, B115200); | 
 |             cfsetispeed(&newtio, B115200); | 
 |             break; | 
 |         case B_230400: | 
 |             cfsetospeed(&newtio, B230400); | 
 |             cfsetispeed(&newtio, B230400); | 
 |             break; | 
 |         case B_460800: | 
 |             cfsetospeed(&newtio, B460800); | 
 |             cfsetispeed(&newtio, B460800); | 
 |             break; | 
 |         case B_921600: | 
 |             cfsetospeed(&newtio, B921600); | 
 |             cfsetispeed(&newtio, B921600); | 
 |             break; | 
 |         case B_3000000: | 
 |             cfsetospeed(&newtio, B3000000); | 
 |             cfsetispeed(&newtio, B3000000); | 
 |             break; | 
 |         case B_4000000: | 
 |             cfsetospeed(&newtio, B4000000); | 
 |             cfsetispeed(&newtio, B4000000); | 
 |             break; | 
 |         default: | 
 |             LOGD("No set speed."); | 
 |             break; | 
 |     } | 
 |  | 
 |     switch(dcb->databit) | 
 |     { | 
 |         case DB_CS5: | 
 |             newtio.c_cflag &= ~CSIZE; | 
 |             newtio.c_cflag |= CS5; | 
 |             break; | 
 |         case DB_CS6: | 
 |             newtio.c_cflag &= ~CSIZE; | 
 |             newtio.c_cflag |= CS6; | 
 |             break; | 
 |         case DB_CS7: | 
 |             newtio.c_cflag &= ~CSIZE; | 
 |             newtio.c_cflag |= CS7; | 
 |             break; | 
 |         case DB_CS8: | 
 |             newtio.c_cflag &= ~CSIZE; | 
 |             newtio.c_cflag |= CS8; | 
 |             break; | 
 |         default: | 
 |             LOGD("No set databit."); | 
 |             break; | 
 |     } | 
 |  | 
 |     if(dcb->stopbit == SB_2) { | 
 |         newtio.c_cflag |= CSTOPB; | 
 |     } else { | 
 |         newtio.c_cflag &= ~CSTOPB; | 
 |     } | 
 |  | 
 |     switch (dcb->parity) | 
 |     { | 
 |         case PB_ODD:// 奇校验 | 
 |             newtio.c_cflag |= PARENB; | 
 |             newtio.c_cflag |= PARODD; | 
 |             break; | 
 |         case PB_EVEN:// 偶校验 | 
 |             newtio.c_cflag |= PARENB; | 
 |             newtio.c_cflag &= ~PARODD; | 
 |             break; | 
 |         case PB_NONE:// 无奇偶校验 | 
 |             newtio.c_cflag &= ~PARENB; | 
 |             break; | 
 |         default: | 
 |             LOGD("No set parity."); | 
 |             break; | 
 |     } | 
 |  | 
 |     switch (dcb->flowctrl) | 
 |     { | 
 |         case FC_RTSCTS: | 
 |             newtio.c_cflag |= CRTSCTS; | 
 |             tcflush(fd, TCIFLUSH); | 
 |             break; | 
 |         case FC_XONXOFF: | 
 |             newtio.c_iflag |= (IXON | IXOFF); | 
 |             tcflush(fd, TCIFLUSH); | 
 |             break; | 
 |         case FC_NONE: | 
 |             newtio.c_cflag &= ~CRTSCTS; | 
 |             newtio.c_iflag &= ~(IXON | IXOFF); | 
 |             tcflush(fd, TCIFLUSH); | 
 |             break; | 
 |         default: | 
 |             LOGD("No set flow ctrl."); | 
 |             break; | 
 |     } | 
 |  | 
 |     if(tcsetattr(fd, TCSANOW, &newtio) != 0) | 
 |     { | 
 |         LOGE("Serial port configuration backup errno"); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 |  | 
 | int Ql_UART_GetDCB(int fd, ST_UARTDCB *dcb) | 
 | { | 
 |     struct termios newtio; | 
 |     memset(&newtio, 0, sizeof(newtio)); | 
 |  | 
 |     if(tcgetattr(fd, &newtio) != 0) | 
 |     { | 
 |         LOGE("Serial port configuration backup errno"); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     switch(cfgetispeed(&newtio)) | 
 |     { | 
 |         case B300: | 
 |             dcb->baudrate = B_300; | 
 |             break; | 
 |         case B600: | 
 |             dcb->baudrate = B_600; | 
 |             break; | 
 |         case B1200: | 
 |             dcb->baudrate = B_1200; | 
 |             break; | 
 |         case B2400: | 
 |             dcb->baudrate = B_2400; | 
 |             break; | 
 |         case B4800: | 
 |             dcb->baudrate = B_4800; | 
 |             break; | 
 |         case B9600: | 
 |             dcb->baudrate = B_9600; | 
 |             break; | 
 |         case B19200: | 
 |             dcb->baudrate = B_19200; | 
 |             break; | 
 |         case B38400: | 
 |             dcb->baudrate = B_38400; | 
 |             break; | 
 |         case B57600: | 
 |             dcb->baudrate = B_57600; | 
 |             break; | 
 |         case B115200: | 
 |             dcb->baudrate = B_115200; | 
 |             break; | 
 |         case B230400: | 
 |             dcb->baudrate = B_230400; | 
 |             break; | 
 |         case B460800: | 
 |             dcb->baudrate = B_460800; | 
 |             break; | 
 |         case B921600: | 
 |             dcb->baudrate = B_921600; | 
 |             break; | 
 |         case B3000000: | 
 |             dcb->baudrate = B_3000000; | 
 |             break; | 
 |         case B4000000: | 
 |             dcb->baudrate = B_4000000; | 
 |             break; | 
 |         default: | 
 |             dcb->baudrate = B_115200; | 
 |             break; | 
 |     } | 
 |  | 
 |     switch(newtio.c_cflag & CSIZE) | 
 |     { | 
 |         case CS5: | 
 |             dcb->databit = DB_CS5; | 
 |             break; | 
 |         case CS6: | 
 |             dcb->databit = DB_CS6; | 
 |             break; | 
 |         case CS7: | 
 |             dcb->databit = DB_CS7; | 
 |             break; | 
 |         case CS8: | 
 |             dcb->databit = DB_CS8; | 
 |             break; | 
 |         default: | 
 |             dcb->databit = DB_CS8; | 
 |             break; | 
 |     } | 
 |  | 
 |     if(newtio.c_cflag & CSTOPB) { | 
 |         dcb->stopbit = SB_2; | 
 |     } else { | 
 |         dcb->stopbit = SB_1; | 
 |     } | 
 |  | 
 |     if(newtio.c_cflag & PARENB) { // 启用了奇偶校验 | 
 |         if(newtio.c_cflag & PARODD) { | 
 |             dcb->parity = PB_ODD; // 奇校验 | 
 |         } else { | 
 |             dcb->parity = PB_EVEN; // 偶校验 | 
 |         } | 
 |     } else { | 
 |         dcb->parity = PB_NONE; | 
 |     } | 
 |  | 
 |     if(newtio.c_cflag & CRTSCTS) { | 
 |         dcb->flowctrl = FC_RTSCTS; | 
 |     } else if(newtio.c_iflag & (IXON | IXOFF) == (IXON | IXOFF)){ | 
 |         dcb->flowctrl = FC_XONXOFF; | 
 |     } else { | 
 |         dcb->flowctrl = FC_NONE; | 
 |     } | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 |  | 
 | int Ql_UART_IoCtl(int fd, unsigned int cmd, void* pValue) | 
 | { | 
 |     return 0; | 
 | } | 
 |  | 
 |  | 
 | int Ql_UART_Close(int fd) | 
 | { | 
 |     if (fd <= 0) | 
 |         return -1; | 
 |  | 
 |     close(fd); | 
 |     return 0; | 
 | } | 
 |  |