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
DMX.cpp
- Committer:
- okini3939
- Date:
- 2017-10-20
- Revision:
- 19:ae8fd2ba7c53
- Parent:
- 18:69d65ca92bcc
File content as of revision 19:ae8fd2ba7c53:
/* * DMX512, RDM send/recv library * Copyright (c) 2017 Hiroshi Suga * Released under the MIT License: http://mbed.org/license/mit */ /** @file * @brief DMX512 send/recv */ #include "mbed.h" #include "DMX.h" 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; mode_rx = DMX_MODE_BEGIN; is_received = 0; is_sent = 0; memset(data_tx, 0, sizeof(data_tx)); memset(data_rx, 0, sizeof(data_rx)); time_break = DMX_TIME_BREAK; 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; NVIC_SetPriority(UART0_IRQn, 1); } else if (p_rx == p14) { _uart = (LPC_UART_TypeDef*)LPC_UART1; NVIC_SetPriority(UART1_IRQn, 1); } else if (p_rx == p27) { _uart = LPC_UART2; NVIC_SetPriority(UART2_IRQn, 1); } else if (p_rx == p10) { _uart = LPC_UART3; NVIC_SetPriority(UART3_IRQn, 1); } #elif defined(TARGET_LPC4088) if (p_rx == p10 || p_rx == P0_26 || p_rx == P4_29) { _uart = LPC_UART3; NVIC_SetPriority(UART3_IRQn, 1); } else if (p_rx == p31) { _uart = (LPC_UART_TypeDef*)LPC_UART4; NVIC_SetPriority(UART4_IRQn, 1); } else if (p_rx == P0_3) { _uart = LPC_UART0; NVIC_SetPriority(UART0_IRQn, 1); } else if (p_rx == P0_16 || p_rx == P2_1 || p_rx == P3_17) { _uart = (LPC_UART_TypeDef*)LPC_UART1; NVIC_SetPriority(UART1_IRQn, 1); } else if (p_rx == P0_11 || p_rx == P2_9 || p_rx == P4_23) { _uart = LPC_UART2; NVIC_SetPriority(UART2_IRQn, 1); } #elif defined(TARGET_LPC11UXX) if (p_rx == p10) { _uart = LPC_USART; NVIC_SetPriority(UART_IRQn, 1); } #elif defined(TARGET_LPC11XX) // LPC1114 support by Stanly Chen if (p_rx == P1_6) { _uart = (LPC_UART_TypeDef*)UART_0; NVIC_SetPriority(UART_IRQn, 1); } #endif _dmx.baud(250000); _dmx.format(8, Serial::None, 2); _dmx.attach(this, &DMX::int_rx, Serial::RxIrq); // timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN); } void DMX::put (int addr, int data) { if (addr < 0 || addr >= DMX_SIZE) return; data_tx[addr] = data; } void DMX::put (unsigned char *buf, int addr, int len) { if (addr < 0 || addr >= DMX_SIZE) return; if (len > DMX_SIZE - addr) len = DMX_SIZE - addr; memcpy(&data_tx[addr], buf, len); } int DMX::get (int addr) { if (addr < 0 || addr >= DMX_SIZE) return -1; return data_rx[addr]; } void DMX::get (unsigned char *buf, int addr, int len) { if (addr < 0 || addr >= DMX_SIZE) return; if (len > DMX_SIZE - addr) len = DMX_SIZE - addr; memcpy(buf, &data_rx[addr], len); } void DMX::int_timer () { switch (mode_tx) { 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); break; case DMX_MODE_BREAK: // Mark After Break timeout01.detach(); _uart->LCR &= ~(1 << 6); mode_tx = DMX_MODE_MAB; timeout01.attach_us(this, &DMX::int_timer, time_mab); break; case DMX_MODE_MAB: // Start code timeout01.detach(); addr_tx = 0; mode_tx = DMX_MODE_DATA; #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; } } 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 _dmx.putc(data_tx[addr_tx]); #endif addr_tx ++; } else { _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 } } } void DMX::int_rx () { int flg, dat; flg = _uart->LSR; #ifdef DMX_UART_DIRECT dat = _uart->RBR; #else dat = _dmx.getc(); #endif 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; } mode_rx = DMX_MODE_BREAK; return; } if (mode_rx == DMX_MODE_BREAK) { // Start Code 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; } } else if (mode_rx == DMX_MODE_DATA) { // Data data_rx[addr_rx] = dat; addr_rx ++; if (addr_rx >= DMX_SIZE) { 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); } } void DMX::stop () { _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 () { int i; for (i = 0; i < DMX_SIZE; i ++) { data_tx[i] = 0; data_rx[i] = 0; } } int DMX::isReceived (){ int r = is_received; is_received = 0; return r; } int DMX::isSent () { int r = is_sent; is_sent = 0; return r; } unsigned char *DMX::getRxBuffer () { return data_rx; } unsigned char *DMX::getTxBuffer () { return data_tx; } int DMX::setTimingParameters (int breaktime, int mab, int mbb) { if (breaktime < 88 || breaktime > 1000000) return -1; if (mab < 8 || mab > 1000000) return -1; if (mbb < 0 || mbb > 1000000) return -1; time_break = breaktime; time_mab = mab; time_mbb = mbb; return 0; }