54#if __linux__ || __APPLE__
65Serial_Port::Serial_Port(
const char* uart_name_,
int baudrate_) : fd(-1), lastStatus(), lock(), debug(false), uart_name(uart_name_), baudrate(baudrate_), is_open(false)
67 initialize_defaults();
70Serial_Port::Serial_Port() : fd(-1), lastStatus(), lock(), debug(false), uart_name(
"/dev/ttyUSB0"), baudrate(57600), is_open(false)
72 initialize_defaults();
75Serial_Port::~Serial_Port()
78 pthread_mutex_destroy(&lock);
81void Serial_Port::initialize_defaults()
88 uart_name =
"/dev/ttyUSB0";
92 int result = pthread_mutex_init(&lock,
nullptr);
95 LOG_ERROR(
"serial_port.cpp - mutex init failed\n");
102int Serial_Port::read_message(mavlink_message_t& message)
105 mavlink_status_t status;
106 uint8_t msgReceived =
false;
113 int result = _read_port(cp);
121 msgReceived = mavlink_parse_char(MAVLINK_COMM_1, cp, &message, &status);
124 if ((lastStatus.packet_rx_drop_count != status.packet_rx_drop_count) && debug)
126 LOG_ERROR(
"serial_port.cpp - DROPPED {} PACKETS\n", status.packet_rx_drop_count);
127 [[maybe_unused]]
unsigned char v = cp;
138 LOG_ERROR(
"serial_port.cpp - Could not read from fd {}\n", fd);
144 if (msgReceived && debug)
149 LOG_ERROR(
"serial_port.cpp - Received serial data");
150 std::array<uint8_t, MAVLINK_MAX_PACKET_LEN> buffer{};
153 auto messageLength = mavlink_msg_to_send_buffer(buffer.data(), &message);
156 if (messageLength > MAVLINK_MAX_PACKET_LEN)
158 LOG_ERROR(
"serial_port.cpp - MESSAGE LENGTH IS LARGER THAN BUFFER SIZE\n");
164 for (
size_t i = 0; i < messageLength; i++)
166 [[maybe_unused]]
auto v = buffer.at(i);
179int Serial_Port::write_message(
const mavlink_message_t& message)
181 std::array<char, 300> buf{};
184 auto len = mavlink_msg_to_send_buffer(
reinterpret_cast<uint8_t*
>(buf.data()), &message);
187 auto bytesWritten = _write_port(buf.data(), len);
198void Serial_Port::start()
203 LOG_INFO(
"serial_port.cpp - OPEN PORT\n");
205 fd = _open_port(uart_name);
210 LOG_ERROR(
"serial_port.cpp - failure, could not open port.\n");
217 auto success = _setup_port(baudrate, 8, 1,
false,
false);
224 LOG_ERROR(
"serial_port.cpp - failure, could not configure port.\n");
229 LOG_ERROR(
"serial_port.cpp - Connection attempt to port {} with {} baud, 8N1 failed, exiting.\n", uart_name, baudrate);
236 LOG_INFO(
"serial_port.cpp - Connected to {} with {} baud, 8 data bits, no parity, 1 stop bit (8N1)\n", uart_name, baudrate);
237 lastStatus.packet_rx_drop_count = 0;
245void Serial_Port::stop()
247 LOG_INFO(
"serial_port.cpp - CLOSE PORT\n");
249 int result = close(fd);
253 LOG_WARN(
"serial_port.cpp - Error on port close ({})\n", result);
263int Serial_Port::_open_port(
const char* port)
268 fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY | O_CLOEXEC);
273 LOG_ERROR(
"serial_port.cpp - Could not open the port.");
278 fcntl(fd, F_SETFL, 0);
289bool Serial_Port::_setup_port(
int baud,
int ,
int ,
bool ,
bool )
const
294 LOG_ERROR(
"serial_port.cpp - file descriptor {} is NOT a serial port\n", fd);
301 if (tcgetattr(fd, &config) < 0)
303 LOG_ERROR(
"serial_port.cpp - could not read configuration of fd {}\n", fd);
312 config.c_iflag &= ~static_cast<tcflag_t>(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON);
319 config.c_oflag &= ~static_cast<tcflag_t>(OCRNL | ONLCR | ONLRET | ONOCR | OFILL | OPOST);
322 config.c_oflag &= ~static_cast<tcflag_t>(OLCUC);
326 config.c_oflag &= ~static_cast<tcflag_t>(ONOEOT);
332 config.c_lflag &= ~static_cast<tcflag_t>(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
337 config.c_cflag &= ~static_cast<tcflag_t>(CSIZE | PARENB);
338 config.c_cflag |= CS8;
342 config.c_cc[VMIN] = 1;
343 config.c_cc[VTIME] = 10;
353 if (cfsetispeed(&config, B1200) < 0 || cfsetospeed(&config, B1200) < 0)
355 LOG_ERROR(
"serial_port.cpp - Could not set desired baud rate of {} Baud\n", baud);
360 cfsetispeed(&config, B1800);
361 cfsetospeed(&config, B1800);
364 cfsetispeed(&config, B9600);
365 cfsetospeed(&config, B9600);
368 cfsetispeed(&config, B19200);
369 cfsetospeed(&config, B19200);
372 if (cfsetispeed(&config, B38400) < 0 || cfsetospeed(&config, B38400) < 0)
374 LOG_ERROR(
"serial_port.cpp - Could not set desired baud rate of {} Baud\n", baud);
379 if (cfsetispeed(&config, B57600) < 0 || cfsetospeed(&config, B57600) < 0)
381 LOG_ERROR(
"serial_port.cpp - Could not set desired baud rate of {} Baud\n", baud);
386 if (cfsetispeed(&config, B115200) < 0 || cfsetospeed(&config, B115200) < 0)
388 LOG_ERROR(
"serial_port.cpp - Could not set desired baud rate of {} Baud\n", baud);
396 if (cfsetispeed(&config, B460800) < 0 || cfsetospeed(&config, B460800) < 0)
398 LOG_ERROR(
"serial_port.cpp - Could not set desired baud rate of {} Baud\n", baud);
403 if (cfsetispeed(&config, B921600) < 0 || cfsetospeed(&config, B921600) < 0)
405 LOG_ERROR(
"serial_port.cpp - Could not set desired baud rate of {} Baud\n", baud);
411 if (cfsetispeed(&config, B1500000) < 0 || cfsetospeed(&config, B1500000) < 0)
413 LOG_ERROR(
"serial_port.cpp - Could not set desired baud rate of {} Baud\n", baud);
419 LOG_ERROR(
"serial_port.cpp - Desired baud rate {} could not be set, aborting.\n", baud);
426 if (tcsetattr(fd, TCSAFLUSH, &config) < 0)
428 LOG_ERROR(
"serial_port.cpp - could not set configuration of fd {}\n", fd);
439int Serial_Port::_read_port(uint8_t& cp)
442 pthread_mutex_lock(&lock);
444 auto result =
static_cast<int8_t
>(read(fd, &cp, 1));
447 pthread_mutex_unlock(&lock);
455int Serial_Port::_write_port(
char* buf,
unsigned len)
458 pthread_mutex_lock(&lock);
461 const int bytesWritten =
static_cast<int>(write(fd, buf, len));
467 pthread_mutex_unlock(&lock);
Utility class for logging to console and file.
#define LOG_ERROR
Error occurred, which stops part of the program to work, but not everything.
#define LOG_WARN
Error occurred, but a fallback option exists and program continues to work normally.
#define LOG_INFO
Info to the user on the state of the program.
void stop()
Stops the Thread.
Serial interface definition.