ENTTEC OpenDMX USB using serial port rather than libftdi, Linux only for now

This commit is contained in:
Adam Honse
2023-05-03 22:46:22 -05:00
parent 5c5ceff4dd
commit d44be72953
5 changed files with 64 additions and 25 deletions

View File

@@ -45,18 +45,9 @@ RGBController_DMX::RGBController_DMX(std::vector<DMXDevice> 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*/)

View File

@@ -12,7 +12,6 @@
#include "serial_port.h"
#include <chrono>
#include <thread>
#include <libftdi1/ftdi.h>
struct DMXDevice
{
@@ -44,7 +43,7 @@ public:
private:
std::vector<DMXDevice> devices;
ftdi_context * ftdi;
serial_port * port;
std::thread * keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::chrono::milliseconds keepalive_delay;

View File

@@ -1711,7 +1711,6 @@ contains(QMAKE_PLATFORM, linux) {
-lmbedtls \
-lmbedcrypto \
-ldl \
-lftdi1 \
COMPILER_VERSION = $$system($$QMAKE_CXX " -dumpversion")
if (!versionAtLeast(COMPILER_VERSION, "9")) {

View File

@@ -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
}

View File

@@ -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();