From 91bf93a8cf0ea667070b35f2efc6043fd5189d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Fri, 28 Jun 2024 12:03:21 +0200 Subject: [PATCH] [dmx] WIP on Open DMX USB support --- .../protocols/artnet/dmxusbpro_protocol.cpp | 114 +++++++++++------- .../protocols/artnet/dmxusbpro_protocol.hpp | 11 +- 2 files changed, 78 insertions(+), 47 deletions(-) diff --git a/src/ossia/protocols/artnet/dmxusbpro_protocol.cpp b/src/ossia/protocols/artnet/dmxusbpro_protocol.cpp index e2488812508..396df915fec 100644 --- a/src/ossia/protocols/artnet/dmxusbpro_protocol.cpp +++ b/src/ossia/protocols/artnet/dmxusbpro_protocol.cpp @@ -32,14 +32,14 @@ dmxusbpro_protocol::dmxusbpro_protocol( switch(m_version) { - case 1: + case open_dmx_usb: + case dmx_usb_pro_mk1: break; - case 2: { - + case dmx_usb_pro_mk2: { // SEND_DMX_PORT1: 0x06, - // SEND_DMX_PORT2: 0xCA, - // SET_API_KEY: 0x0D, - // SET_PORT_ASSIGNMENT: 0x93 + // SEND_DMX_PORT2: 0xCA, + // SET_API_KEY: 0x0D, + // SET_PORT_ASSIGNMENT: 0x93 static constexpr unsigned char set_api_key[]{0x7E, 0x0D, 0x04, 0x00, 0xC9, 0xA4, 0x03, 0xE4, 0xE7}; boost::asio::write(m_port, boost::asio::buffer(set_api_key)); @@ -60,52 +60,76 @@ void dmxusbpro_protocol::set_device(ossia::net::device_base& dev) { dmx_protocol_base::set_device(dev); - int command = 0x06; - if(m_version == 2 && this->m_conf.universe >= 1) - command = 0xCA; - m_timer.start([this, command] { this->update_function(command); }); + switch(m_version) + { + case dmx_usb_pro_mk1: + m_timer.start([this] { this->update_function_dmxusbpro(0x06); }); + break; + case dmx_usb_pro_mk2: { + int command = this->m_conf.universe >= 1 ? 0xCA : 0x06; + m_timer.start([this, command] { this->update_function_dmxusbpro(command); }); + break; + } + case open_dmx_usb: + m_timer.start([this] { this->update_function_opendmx(); }); + break; + } } -void dmxusbpro_protocol::update_function(uint8_t command) +void dmxusbpro_protocol::update_function_dmxusbpro(uint8_t command) { - try - { - // https://cdn.enttec.com/pdf/assets/70304/70304_DMX_USB_PRO_API.pdf - // 1: 0x7E - // 1: message code: 0x6 for DMX send / 0xCA for DMX send on port 2 (DMX USB PRO Mk2) - // 1: size LSB - // 1: size MSB - // N: message data: [ - // 1: start code (0x0 for DMX) - // N-1: DMX channels - // ] - // 1: 0xE7 - - constexpr uint32_t channels = 512; - constexpr uint32_t data_size = channels + 1; - constexpr uint32_t buffer_size = 4 + data_size + 1; + boost::system::error_code ec; + // https://cdn.enttec.com/pdf/assets/70304/70304_DMX_USB_PRO_API.pdf + // 1: 0x7E + // 1: message code: 0x6 for DMX send / 0xCA for DMX send on port 2 (DMX USB PRO Mk2) + // 1: size LSB + // 1: size MSB + // N: message data: [ + // 1: start code (0x0 for DMX) + // N-1: DMX channels + // ] + // 1: 0xE7 + + constexpr uint32_t channels = 512; + constexpr uint32_t data_size = channels + 1; + constexpr uint32_t buffer_size = 4 + data_size + 1; + + constexpr uint8_t data_size_lsb = data_size & 0x00FF; + constexpr uint8_t data_size_msb = (data_size & 0xFF00) >> 8; + + unsigned char buf[buffer_size]{0x7E, command, data_size_lsb, data_size_msb, 0}; + + for(uint32_t i = 0; i < channels; i++) + buf[5 + i] = m_buffer.data[i]; + buf[buffer_size - 1] = 0xE7; + + boost::asio::write(m_port, boost::asio::buffer(buf)); + if(ec) + ossia::logger().error("DMX write failure"); + + m_buffer.dirty = false; +} - constexpr uint8_t data_size_lsb = data_size & 0x00FF; - constexpr uint8_t data_size_msb = (data_size & 0xFF00) >> 8; +void dmxusbpro_protocol::update_function_opendmx() +{ + boost::system::error_code ec; + // + // 0 + // <512 channels> + m_port.send_break(ec); + if(ec) + return; - unsigned char buf[buffer_size]{0x7E, command, data_size_lsb, data_size_msb, 0}; + constexpr uint32_t buffer_size = 1 + 512; - for(uint32_t i = 0; i < channels; i++) - buf[5 + i] = m_buffer.data[i]; - buf[buffer_size - 1] = 0xE7; + unsigned char buf[buffer_size]; + buf[0] = 0; // DMX start code + std::copy_n(m_buffer.data, 512, buf + 1); // DMX channels - boost::asio::write(m_port, boost::asio::buffer(buf)); + boost::asio::write(m_port, boost::asio::buffer(buf), ec); + if(ec) + ossia::logger().error("DMX write failure"); - m_buffer.dirty = false; - } - catch(std::exception& e) - { - ossia::logger().error("write failure: {}", e.what()); - } - catch(...) - { - ossia::logger().error("write failure"); - } + m_buffer.dirty = false; } - } diff --git a/src/ossia/protocols/artnet/dmxusbpro_protocol.hpp b/src/ossia/protocols/artnet/dmxusbpro_protocol.hpp index d3d42610503..793840e4391 100644 --- a/src/ossia/protocols/artnet/dmxusbpro_protocol.hpp +++ b/src/ossia/protocols/artnet/dmxusbpro_protocol.hpp @@ -12,6 +12,12 @@ namespace ossia::net class OSSIA_EXPORT dmxusbpro_protocol final : public dmx_output_protocol_base { public: + enum devices + { + dmx_usb_pro_mk1 = 1, + dmx_usb_pro_mk2 = 2, + open_dmx_usb = 3, + }; dmxusbpro_protocol( ossia::net::network_context_ptr, const dmx_config& conf, const ossia::net::serial_configuration& socket, int version); @@ -21,10 +27,11 @@ class OSSIA_EXPORT dmxusbpro_protocol final : public dmx_output_protocol_base void set_device(ossia::net::device_base& dev) override; private: - void update_function(uint8_t command); + void update_function_dmxusbpro(uint8_t command); + void update_function_opendmx(); boost::asio::serial_port m_port; - int m_version = 1; + int m_version = devices::dmx_usb_pro_mk1; }; } #endif