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
Diff: DMX.cpp
- 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 () {