From d44be72953a350d0fbc975e16a6070518a106947 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Wed, 3 May 2023 22:46:22 -0500 Subject: [PATCH] ENTTEC OpenDMX USB using serial port rather than libftdi, Linux only for now --- .../DMXController/RGBController_DMX.cpp | 31 ++++++----------- Controllers/DMXController/RGBController_DMX.h | 3 +- OpenRGB.pro | 1 - serial_port/serial_port.cpp | 20 ++++++++++- serial_port/serial_port.h | 34 +++++++++++++++++++ 5 files changed, 64 insertions(+), 25 deletions(-) diff --git a/Controllers/DMXController/RGBController_DMX.cpp b/Controllers/DMXController/RGBController_DMX.cpp index 1fa379c6e..05ba7286a 100644 --- a/Controllers/DMXController/RGBController_DMX.cpp +++ b/Controllers/DMXController/RGBController_DMX.cpp @@ -45,18 +45,9 @@ RGBController_DMX::RGBController_DMX(std::vector device_list) } /*-----------------------------------------*\ - | Open OpenDMX FTDI | + | Open OpenDMX port | \*-----------------------------------------*/ - ftdi_device_list* devlist; - ftdi = ftdi_new(); - //ftdi_usb_open(ftdi, 0x0403, 0x6001); - LOG_WARNING("ftdi_set_interface %d", ftdi_set_interface(ftdi, INTERFACE_ANY)); - LOG_WARNING("ftdi_usb_find_all %d", ftdi_usb_find_all(ftdi, &devlist, 0, 0)); - LOG_WARNING("ftdi_usb_open_dev %d", ftdi_usb_open_dev(ftdi, devlist[0].dev)); - ftdi_list_free(&devlist); - LOG_WARNING("ftdi_set_baudrate %d", ftdi_set_baudrate(ftdi, 250000)); - LOG_WARNING("ftdi_set_line_property2 %d", ftdi_set_line_property2(ftdi, BITS_8, STOP_BIT_2, NONE, BREAK_ON)); - LOG_WARNING("ftdi_usb_purge_buffers %d", ftdi_usb_purge_buffers(ftdi)); + port = new serial_port("/dev/ttyUSB0", 250000); /*-----------------------------------------*\ | Set up modes | @@ -177,8 +168,7 @@ void RGBController_DMX::DeviceUpdateLEDs() last_update_time = std::chrono::steady_clock::now(); - unsigned char dmx_data[512]; - const unsigned char startcode = 0; + unsigned char dmx_data[513]; memset(dmx_data, 0, sizeof(dmx_data)); @@ -186,29 +176,28 @@ void RGBController_DMX::DeviceUpdateLEDs() { if(devices[device_idx].brightness_channel > 0) { - dmx_data[devices[device_idx].brightness_channel - 1] = modes[0].brightness; + dmx_data[devices[device_idx].brightness_channel] = modes[0].brightness; } if(devices[device_idx].red_channel > 0) { - dmx_data[devices[device_idx].red_channel - 1] = RGBGetRValue(colors[device_idx]); + dmx_data[devices[device_idx].red_channel] = RGBGetRValue(colors[device_idx]); } if(devices[device_idx].green_channel > 0) { - dmx_data[devices[device_idx].green_channel - 1] = RGBGetGValue(colors[device_idx]); + dmx_data[devices[device_idx].green_channel] = RGBGetGValue(colors[device_idx]); } if(devices[device_idx].blue_channel > 0) { - dmx_data[devices[device_idx].blue_channel - 1] = RGBGetBValue(colors[device_idx]); + dmx_data[devices[device_idx].blue_channel] = RGBGetBValue(colors[device_idx]); } } - ftdi_set_line_property2(ftdi, BITS_8, STOP_BIT_2, NONE, BREAK_ON); - ftdi_set_line_property2(ftdi, BITS_8, STOP_BIT_2, NONE, BREAK_OFF); - ftdi_write_data(ftdi, &startcode, 1); - ftdi_write_data(ftdi, (const unsigned char*)dmx_data, sizeof(dmx_data)); + port->serial_break(); + port->serial_write((char*)&dmx_data, sizeof(dmx_data)); + //port->serial_flush_tx(); } void RGBController_DMX::UpdateZoneLEDs(int /*zone*/) diff --git a/Controllers/DMXController/RGBController_DMX.h b/Controllers/DMXController/RGBController_DMX.h index c3a452ee4..d93cf391d 100644 --- a/Controllers/DMXController/RGBController_DMX.h +++ b/Controllers/DMXController/RGBController_DMX.h @@ -12,7 +12,6 @@ #include "serial_port.h" #include #include -#include struct DMXDevice { @@ -44,7 +43,7 @@ public: private: std::vector devices; - ftdi_context * ftdi; + serial_port * port; std::thread * keepalive_thread; std::atomic keepalive_thread_run; std::chrono::milliseconds keepalive_delay; diff --git a/OpenRGB.pro b/OpenRGB.pro index 590039969..5e0035b42 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -1711,7 +1711,6 @@ contains(QMAKE_PLATFORM, linux) { -lmbedtls \ -lmbedcrypto \ -ldl \ - -lftdi1 \ COMPILER_VERSION = $$system($$QMAKE_CXX " -dumpversion") if (!versionAtLeast(COMPILER_VERSION, "9")) { diff --git a/serial_port/serial_port.cpp b/serial_port/serial_port.cpp index 62efab3e1..2d573dab6 100644 --- a/serial_port/serial_port.cpp +++ b/serial_port/serial_port.cpp @@ -104,8 +104,9 @@ bool serial_port::serial_open() struct termios2 options; ioctl(file_descriptor, TCGETS2, &options); + options.c_cflag &= ~PARENB; options.c_cflag &= ~CBAUD; - options.c_cflag |= BOTHER; + options.c_cflag |= CBAUDEX | CSTOPB | CLOCAL; options.c_lflag &= ~ICANON; options.c_lflag &= ~ECHO; // Disable echo options.c_lflag &= ~ECHOE; // Disable erasure @@ -116,6 +117,10 @@ bool serial_port::serial_open() options.c_ospeed = baud_rate; options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes ioctl(file_descriptor, TCSETS2, &options); + + int RTS_flag; + RTS_flag = TIOCM_RTS; + ioctl(file_descriptor,TIOCMBIC,&RTS_flag);//Set RTS pin #endif /*-----------------------------------------------------*\ @@ -357,3 +362,16 @@ void serial_port::serial_flush_tx() tcflush(file_descriptor, TCOFLUSH); #endif } + +/*---------------------------------------------------------*\ +| serial_break | +\*---------------------------------------------------------*/ +void serial_port::serial_break() +{ +#ifdef __linux__ + //Send break for at least 1 ms + ioctl(file_descriptor, TIOCSBRK); + usleep(1000); + ioctl(file_descriptor, TIOCCBRK); +#endif +} diff --git a/serial_port/serial_port.h b/serial_port/serial_port.h index 2da9a49e8..8f7007cb3 100644 --- a/serial_port/serial_port.h +++ b/serial_port/serial_port.h @@ -61,6 +61,33 @@ #endif /* __APPLE__ */ +/*-------------------------------------------------------------------------*\ +| Serial Port Enums | +\*-------------------------------------------------------------------------*/ +typedef unsigned int serial_port_parity; +enum +{ + SERIAL_PORT_PARITY_NONE = 0, /* No parity */ + SERIAL_PORT_PARITY_ODD = 1, /* Odd parity */ + SERIAL_PORT_PARITY_EVEN = 2, /* Even parity */ +}; + +typedef unsigned int serial_port_size; +enum +{ + SERIAL_PORT_SIZE_8 = 0, /* 8 bits per byte */ + SERIAL_PORT_SIZE_7 = 1, /* 7 bits per byte */ + SERIAL_PORT_SIZE_6 = 2, /* 6 bits per byte */ + SERIAL_PORT_SIZE_5 = 3, /* 5 bits per byte */ +}; + +typedef unsigned int serial_port_stop_bits; +enum +{ + SERIAL_PORT_STOP_BITS_1 = 0, /* 1 stop bit */ + SERIAL_PORT_STOP_BITS_2 = 1, /* 2 stop bits */ +}; + /*-------------------------------------------------------------------------*\ | Serial Port Class | | The reason for this class is that serial ports are treated differently | @@ -72,6 +99,12 @@ class serial_port public: serial_port(); serial_port(const char * name, unsigned int baud); + serial_port(const char * name, + unsigned int baud, + serial_port_parity parity, + serial_port_size size, + serial_port_stop_bits stop_bits, + bool flow_control); ~serial_port(); @@ -90,6 +123,7 @@ public: void serial_flush_rx(); void serial_flush_tx(); + void serial_break(); int serial_available();