#include "gdserial.h" #define DEBUG_LOG 0 #include #include #include #include #include #include using namespace godot; void GDSerial::_register_methods() { register_method("start", &GDSerial::start); register_method("end", &GDSerial::end); register_method("send", &GDSerial::send); register_method("read_string", &GDSerial::read_string); register_method("get_available", &GDSerial::get_available); } GDSerial::GDSerial() {} GDSerial::~GDSerial() {} void GDSerial::_init() {} bool GDSerial::start(String port, int baud_rate) { const char *port_c = port.utf8().get_data(); #if DEBUG_LOG printf("GDSerial: Trying to open %s at baudrate %s.\n", port_c, baud_rate); #endif serial_port = open(port_c, O_RDWR | O_NOCTTY | O_NDELAY); struct termios tty; struct termios tty_old; memset(&tty, 0, sizeof tty); if (tcgetattr(serial_port, &tty) != 0) { #if DEBUG_LOG printf("GDSerial: Failed to get current serial parameters.\n"); #endif return false; } tty_old = tty; cfsetospeed(&tty, (speed_t)baud_rate); cfsetispeed(&tty, (speed_t)baud_rate); tty.c_cflag &= ~PARENB; tty.c_cflag &= ~CSTOPB; tty.c_cflag |= CS8; tty.c_cflag &= ~CRTSCTS; tty.c_cflag |= CREAD | CLOCAL; tty.c_lflag &= ~ICANON; tty.c_lflag &= ~ECHO; tty.c_lflag &= ~ECHOE; tty.c_lflag &= ~ECHONL; tty.c_lflag &= ~ISIG; tty.c_iflag &= ~(IXON | IXOFF | IXANY); tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); tty.c_oflag &= ~OPOST; tty.c_oflag &= ~ONLCR; tty.c_cc[VTIME] = 0; tty.c_cc[VMIN] = 0; cfmakeraw(&tty); tcflush(serial_port, TCIFLUSH); if (tcsetattr(serial_port, TCSANOW, &tty) != 0) { #if DEBUG_LOG printf("GDSerial: Could not set serial port parameters.\n"); #endif return false; } fcntl(serial_port, F_SETFL, FNDELAY); #if DEBUG_LOG printf("GDSerial: %s opened.\n", port_c); #endif return true; } void GDSerial::end() { close(serial_port); serial_port = 0; #if DEBUG_LOG printf("GDSerial: Serial port closed.\n"); #endif } void GDSerial::send(String text) { const char *text_c = text.utf8().get_data(); write(serial_port, text_c, text.length()); } String GDSerial::read_string() { String text = ""; unsigned char buf[4096]; int n; n = read(serial_port, &buf, sizeof(buf)); for (int x = 0; x < n; x++) { text += buf[x]; } return text; } int GDSerial::get_available() { int bytes_available = 0; ioctl(serial_port, FIONREAD, &bytes_available); return bytes_available; }