DMX512, RDM send/recv library http://mbed.org/users/okini3939/notebook/dmx512

Dependents:   dmx_test ArtNodeLED SPK-DVIMXR SPK-DMXer ... more

DMX512 send/recv library

DMX512 is protocol for lighting.

調光プロトコル DMX512 を送受信するライブラリです。

see: http://mbed.org/users/okini3939/notebook/dmx512/

LPC1114 support is thanks to Stanly Chen

Revision:
19:ae8fd2ba7c53
Parent:
18:69d65ca92bcc
--- a/DMX.cpp	Mon Jan 11 06:17:04 2016 +0000
+++ b/DMX.cpp	Fri Oct 20 00:44:06 2017 +0000
@@ -1,6 +1,6 @@
 /*
- * DMX512 send/recv library
- * Copyright (c) 2013 Hiroshi Suga
+ * DMX512, RDM send/recv library
+ * Copyright (c) 2017 Hiroshi Suga
  * Released under the MIT License: http://mbed.org/license/mit
  */
 
@@ -11,8 +11,14 @@
 #include "mbed.h"
 #include "DMX.h"
 
-DMX::DMX (PinName p_tx, PinName p_rx) : _dmx(p_tx, p_rx) {
+
+DMX::DMX (PinName p_tx, PinName p_rx, PinName p_xmit) : _dmx(p_tx, p_rx) {
 
+    if (p_xmit == NC) {
+        _xmit = NULL;
+    } else {
+        _xmit = new DigitalOut(p_xmit, XMIT_RX);
+    }
     clear();
 //    mode_tx = DMX_MODE_BEGIN;
     mode_tx = DMX_MODE_STOP;
@@ -25,6 +31,15 @@
     time_mab   = DMX_TIME_MAB;
     time_mbb   = DMX_TIME_MBB;
 
+#ifdef RDM_ENABLE
+    mode_rdm = 0;
+    rdm_mute = 0;
+    rdm_msgcount = 0;
+    rdm_transno = 0;
+    cb_RdmParser = NULL;
+    buf_uid_size = 0;
+#endif
+
 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
     if (p_rx == P0_3) {
       _uart = (LPC_UART_TypeDef*)LPC_UART0;
@@ -111,6 +126,9 @@
     case DMX_MODE_BEGIN:
         // Break Time
         timeout01.detach();
+#ifdef RDM_ENABLE
+        if (mode_rdm && _xmit) _xmit->write(XMIT_TX);
+#endif
         _uart->LCR |= (1 << 6);
         mode_tx = DMX_MODE_BREAK;
         timeout01.attach_us(this, &DMX::int_timer, time_break);
@@ -129,13 +147,29 @@
         timeout01.detach();
         addr_tx = 0;
         mode_tx = DMX_MODE_DATA;
-        _dmx.attach(this, &DMX::int_tx, Serial::TxIrq);
 #ifdef DMX_UART_DIRECT
         while(!(_uart->LSR & (1<<5)));
+#ifdef RDM_ENABLE
+        if (mode_rdm) {
+            _uart->THR = RDM_START_CODE;
+        } else {
+            _uart->THR = DMX_START_CODE;
+        }
+#else
         _uart->THR = DMX_START_CODE;
+#endif // RDM_ENABLE
+#else
+#ifdef RDM_ENABLE
+        if (mode_rdm) {
+            _dmx.putc(RDM_START_CODE);
+        } else {
+            _dmx.putc(DMX_START_CODE);
+        }
 #else
         _dmx.putc(DMX_START_CODE);
+#endif // RDM_ENABLE
 #endif
+        _dmx.attach(this, &DMX::int_tx, Serial::TxIrq);
         break;
     }
 }
@@ -143,7 +177,17 @@
 void DMX::int_tx () {
     // Data
     if (mode_tx == DMX_MODE_DATA) {
+#ifdef RDM_ENABLE
+        if (mode_rdm && addr_tx < data_rdm[1] + 1) {
+            // RDM data
+            _dmx.putc(data_rdm[addr_tx]);
+            addr_tx ++;
+        } else
+        if (!mode_rdm && addr_tx < DMX_SIZE) {
+#else
         if (addr_tx < DMX_SIZE) {
+#endif // RDM_ENABLE
+            // DMX data
 #ifdef DMX_UART_DIRECT
             _uart->THR = (uint8_t)data_tx[addr_tx];
 #else
@@ -151,10 +195,20 @@
 #endif
             addr_tx ++;
         } else {
-            _dmx.attach(0, Serial::TxIrq);
+            _dmx.attach(0, Serial::TxIrq); // disable
             mode_tx = DMX_MODE_BEGIN;
             is_sent = 1;
+#ifdef RDM_ENABLE
+            if (mode_rdm) {
+                if (_xmit) _xmit->write(XMIT_RX);
+                mode_rdm = 0;
+                mode_tx = DMX_MODE_STOP;
+            } else {
+                timeout01.attach_us(this, &DMX::int_timer, time_mbb);
+            }
+#else
             timeout01.attach_us(this, &DMX::int_timer, time_mbb);
+#endif // RDM_ENABLE
         }
     }
 }
@@ -171,6 +225,9 @@
 
     if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) {
         // Break Time
+        if (is_rdm_received) {
+            return;
+        } else
         if (addr_rx >= 24 && mode_rx == DMX_MODE_DATA) {
             is_received = 1;
         }
@@ -184,6 +241,12 @@
         if (dat == DMX_START_CODE) {
             addr_rx = 0;
             mode_rx = DMX_MODE_DATA;
+#ifdef RDM_ENABLE
+        } else
+        if (dat == RDM_START_CODE) {
+            addr_rx = 0;
+            mode_rx = DMX_MODE_RDM;
+#endif
         } else {
             mode_rx = DMX_MODE_ERROR;
         }
@@ -199,11 +262,31 @@
             is_received = 1;
             mode_rx = DMX_MODE_BEGIN;
         }
+
+#ifdef RDM_ENABLE
+    } else
+    if (mode_rx == DMX_MODE_RDM) {
+
+        // Rdm
+        data_rx[addr_rx] = dat;
+        addr_rx ++;
+
+        if (addr_rx >= 2 && addr_rx >= data_rx[1] + 1) {
+            is_rdm_received = 1;
+            mode_rx = DMX_MODE_BEGIN;
+        } else
+        if (addr_rx >= sizeof(data_rdm)) {
+            mode_rx = DMX_MODE_ERROR;
+        }
+#endif
     }
 }
 
 void DMX::start () {
     if (mode_tx == DMX_MODE_STOP) {
+#ifdef RDM_ENABLE
+        if (_xmit) _xmit->write(XMIT_TX);
+#endif
         mode_tx = DMX_MODE_BEGIN;
         is_sent = 0;
         timeout01.attach_us(this, &DMX::int_timer, time_mbb);
@@ -214,6 +297,9 @@
     _dmx.attach(0, Serial::TxIrq);
     timeout01.detach();
     mode_tx = DMX_MODE_STOP;
+#ifdef RDM_ENABLE
+    if (_xmit) _xmit->write(XMIT_RX);
+#endif
 }
 
 void DMX::clear () {