//
|
// Created by YY on 2017/9/5.
|
//
|
|
#include <jni.h>
|
#include <string>
|
|
#include <sys/stat.h>
|
#include <stdbool.h>
|
#include <stdint.h>
|
#include <termios.h>
|
#include <android/log.h>
|
#include <sys/ioctl.h>
|
#include <unistd.h>
|
#include <sys/types.h>
|
#include <sys/stat.h>
|
#include <fcntl.h>
|
#include <pthread.h>
|
#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);
|
// }
|
// }
|
//}
|