// // Created by YY on 2017/9/5. // #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../jni_log.h" #include "serial_port.h" using namespace std; static volatile int serial_port_fd[2] = {0, 0}; static pthread_mutex_t mutex[2] = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER}; int setRTS(int fd, int level) { int status; if (ioctl(fd, TIOCMGET, &status) == -1) { LOGD("setRTS(): TIOCMGET"); return 0; } if (level) status |= TIOCM_RTS; else status &= ~TIOCM_RTS; if (ioctl(fd, TIOCMSET, &status) == -1) { LOGD("setRTS(): TIOCMSET"); return 0; } return 1; } /********************************************************************* * PUBLIC FUNCTIONS */ static int SetSerialPort(int fd, int speed, int databits, char parity, int stopbits, int flowctrl) { int status = 0; struct termios opt; int speed_arr[] = {B921600, B576000, B500000, B460800, B230400, B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300}; int name_arr[] = {921600, 576000, 500000, 460800, 230400, 115200, 38400, 19200, 9600, 4800, 2400, 1200, 300}; status = tcgetattr(fd, &opt); if (status != 0) { goto SET_SERIAL_PORT_END; } status = tcflush(fd, TCIOFLUSH); if (status != 0) { goto SET_SERIAL_PORT_END; } //Set baud for (int i = 0; i < sizeof(speed_arr) / sizeof(int); i++) { if (speed == name_arr[i]) { cfsetispeed(&opt, speed_arr[i]); cfsetospeed(&opt, speed_arr[i]); break; } } //Set databit opt.c_cflag &= ~CSIZE; if (databits == 7) { opt.c_cflag |= CS7; } else { opt.c_cflag |= CS8; } //Set parity switch (parity) { case 'E': case 'e': opt.c_cflag |= PARENB; /*Enable parity*/ opt.c_cflag &= ~PARODD; opt.c_iflag |= INPCK; /*Enable pairty checking*/ break; case 'O': case 'o': opt.c_cflag |= PARENB | PARODD; opt.c_iflag |= INPCK; break; case 'N': case 'n': default: opt.c_cflag &= ~PARENB; opt.c_iflag &= ~INPCK; break; } //Set stop if (stopbits == 2) { opt.c_cflag |= CSTOPB; } else { opt.c_cflag &= ~CSTOPB; } opt.c_cflag |= CLOCAL | CREAD; //Set raw mode opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/ opt.c_oflag &= ~OPOST; /*Output*/ opt.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL); //Disable XON/XOFF flowcontrol opt.c_iflag &= ~(ICRNL | INLCR); //Disable 0x0d and 0x0a convert opt.c_cc[VTIME] = 0;//150; //15 seconds 150x100ms = 15s opt.c_cc[VMIN] = 1; //Recv one char, read() will return if (flowctrl) { opt.c_cflag |= CRTSCTS; } else { opt.c_cflag &= ~CRTSCTS; //Disable hard flowcontrol } tcflush(fd, TCIOFLUSH); status = tcsetattr(fd, TCSANOW, &opt); SET_SERIAL_PORT_END: if (status != 0) { LOGD("Serial Port set fail"); } else { LOGD("Serial Port set success"); } // setRTS(fd, 1); return status; } static int OpenSerialPort(const char *name) { int uart_fd; // uart_fd = open(name, O_RDWR /*| O_NONBLOCK/*| O_NOCTTY | O_NDELAY*/); uart_fd = open(name, O_RDWR | O_NOCTTY); LOGD("open serial port fd = %d", uart_fd); return uart_fd; } static void CloseSerialPort(int fd) { close(fd); } int WriteSerialPort(int id, const void *buf, int len) { int ret = -1; int fds_ret; int fd = GetSerialPort(id); struct timeval tv; fd_set wrfds; if (fd <= 0) { return -1; } tv.tv_sec = 1; tv.tv_usec = 0; FD_ZERO(&wrfds); //clean FD_SET(fd, &wrfds); //set pthread_mutex_lock(&mutex[id]); fds_ret = select(fd + 1, NULL, &wrfds, NULL, &tv); if (fds_ret < 0) { LOGE("Serial port select error\n"); } else if(fds_ret == 0) { LOGE("Serial port write timeout\n"); } else if(FD_ISSET(fd, &wrfds)) { ret = write(fd, buf, len); //serial write data if (ret != len ) { LOGE("Serial Port Error\n"); tcflush(fd, TCOFLUSH); } } else { LOGE("Serial Port error 2\n"); } pthread_mutex_unlock(&mutex[id]); return ret; } int GetSerialPort(int id) { return serial_port_fd[id]; } int InitSerialPort(int id, int baud, int dataBits, char parity, int stopBits, int flowctrl) { char name[32]; if (id == UART_0) { strcpy(name, "/dev/ttyHSL0"); } else if (id == UART_1) { strcpy(name, "/dev/ttyHSL1"); } else { return -1; } UninitSerialPort(id); serial_port_fd[id] = OpenSerialPort(name); if (serial_port_fd[id] <= 0) { return -1; } if (SetSerialPort(serial_port_fd[id], baud, dataBits, parity, stopBits, flowctrl) != 0) { return -2; } pthread_mutex_init(&mutex[id], NULL); return 0; } void UninitSerialPort(int id) { if (serial_port_fd[id] > 0) { CloseSerialPort(serial_port_fd[id]); pthread_mutex_destroy(&mutex[id]); serial_port_fd[id] = 0; } } int ReadSerialPort(int id, uint8_t *out, uint16_t length) { if (serial_port_fd[id] <= 0) return 0; return read(serial_port_fd[id], out, length); } //extern "C" //JNIEXPORT jint JNICALL //Java_com_example_yy_jnicallback_MyService_InitSerialPort( // JNIEnv *env, // jobject /* this */, // jstring name, // jint baud, // jint dataBits, // jbyte parity, // jint stopBits) { // // const char *s = env->GetStringUTFChars(name, 0); // char item_value[128]; // strcpy(item_value, s); // env->ReleaseStringUTFChars(name, s); // LOGD("serial port = %s", item_value); // // if (serial_port_fd > 0) { // CloseSerialPort(serial_port_fd); // pthread_mutex_destroy(&mutex); // serial_port_fd = 0; // } // // serial_port_fd = OpenSerialPort(item_value); // if (serial_port_fd <= 0) { // return -1; // } // // if (SetSerialPort(serial_port_fd, baud, dataBits, parity, stopBits) != 0) { // return -2; // } // pthread_mutex_init(&mutex, NULL); // return 0; //} // //extern "C" //JNIEXPORT void JNICALL //Java_com_example_yy_jnicallback_MyService_MonitSerialPort( // JNIEnv *env, // jobject /* this */) { // if (serial_port_fd > 0) { // uint8_t UartRxBuf[4096]; // ///* uint8_t pkt[] = {0x7E, 0x80, 0x02, 0x00, 0x00, 0x26, 0x00, 0x00, 0x01, 0x38, 0x20, 0x20, // 0x55, 0x45, 0x04, 0x4E, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x61, 0x63, // 0x0C, 0x06, 0xEA, 0x04, // 0xFE, 0x00, 0x00, 0x01, 0x63, 0x00, 0xB4, 0x13, 0x03, 0x05, 0x18, 0x18, // 0x52, 0x01, 0x04, 0x00, // 0x00, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x4D, 0x7E}; // WriteSerialPort(serial_port_fd, pkt, sizeof(pkt));*/ // // int length = read(serial_port_fd, UartRxBuf, sizeof(UartRxBuf)); // // if (length > 0) { // Parse(DATA_ACCESS_MCU, UartRxBuf, length); // } // } //}