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

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DMX.cpp Source File

DMX.cpp

Go to the documentation of this file.
00001 /*
00002  * DMX512, RDM send/recv library
00003  * Copyright (c) 2017 Hiroshi Suga
00004  * Released under the MIT License: http://mbed.org/license/mit
00005  */
00006 
00007 /** @file
00008  * @brief DMX512 send/recv
00009  */
00010 
00011 #include "mbed.h"
00012 #include "DMX.h"
00013 
00014 
00015 DMX::DMX (PinName p_tx, PinName p_rx, PinName p_xmit) : _dmx(p_tx, p_rx) {
00016 
00017     if (p_xmit == NC) {
00018         _xmit = NULL;
00019     } else {
00020         _xmit = new DigitalOut(p_xmit, XMIT_RX);
00021     }
00022     clear();
00023 //    mode_tx = DMX_MODE_BEGIN;
00024     mode_tx = DMX_MODE_STOP;
00025     mode_rx = DMX_MODE_BEGIN;
00026     is_received = 0;
00027     is_sent    = 0;
00028     memset(data_tx, 0, sizeof(data_tx));
00029     memset(data_rx, 0, sizeof(data_rx));
00030     time_break = DMX_TIME_BREAK;
00031     time_mab   = DMX_TIME_MAB;
00032     time_mbb   = DMX_TIME_MBB;
00033 
00034 #ifdef RDM_ENABLE
00035     mode_rdm = 0;
00036     rdm_mute = 0;
00037     rdm_msgcount = 0;
00038     rdm_transno = 0;
00039     cb_RdmParser = NULL;
00040     buf_uid_size = 0;
00041 #endif
00042 
00043 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00044     if (p_rx == P0_3) {
00045       _uart = (LPC_UART_TypeDef*)LPC_UART0;
00046       NVIC_SetPriority(UART0_IRQn, 1);
00047     } else
00048     if (p_rx == p14) {
00049       _uart = (LPC_UART_TypeDef*)LPC_UART1;
00050       NVIC_SetPriority(UART1_IRQn, 1);
00051     } else
00052     if (p_rx == p27) {
00053       _uart = LPC_UART2;
00054       NVIC_SetPriority(UART2_IRQn, 1);
00055     } else
00056     if (p_rx == p10) {
00057       _uart = LPC_UART3;
00058       NVIC_SetPriority(UART3_IRQn, 1);
00059     }
00060 #elif defined(TARGET_LPC4088)
00061     if (p_rx == p10 || p_rx == P0_26 || p_rx == P4_29) {
00062       _uart = LPC_UART3;
00063       NVIC_SetPriority(UART3_IRQn, 1);
00064     } else
00065     if (p_rx == p31) {
00066       _uart = (LPC_UART_TypeDef*)LPC_UART4;
00067       NVIC_SetPriority(UART4_IRQn, 1);
00068     } else
00069     if (p_rx == P0_3) {
00070       _uart = LPC_UART0;
00071       NVIC_SetPriority(UART0_IRQn, 1);
00072     } else
00073     if (p_rx == P0_16 || p_rx == P2_1 || p_rx == P3_17) {
00074       _uart = (LPC_UART_TypeDef*)LPC_UART1;
00075       NVIC_SetPriority(UART1_IRQn, 1);
00076     } else
00077     if (p_rx == P0_11 || p_rx == P2_9 || p_rx == P4_23) {
00078       _uart = LPC_UART2;
00079       NVIC_SetPriority(UART2_IRQn, 1);
00080     }
00081 #elif defined(TARGET_LPC11UXX)
00082     if (p_rx == p10) {
00083       _uart = LPC_USART;
00084       NVIC_SetPriority(UART_IRQn, 1);
00085     }
00086 #elif defined(TARGET_LPC11XX)
00087     // LPC1114 support by Stanly Chen
00088     if (p_rx == P1_6) {
00089       _uart = (LPC_UART_TypeDef*)UART_0;
00090       NVIC_SetPriority(UART_IRQn, 1);
00091     }
00092 #endif
00093 
00094     _dmx.baud(250000);
00095     _dmx.format(8, Serial::None, 2);
00096     _dmx.attach(this, &DMX::int_rx, Serial::RxIrq);
00097 
00098 //    timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN);
00099 }
00100 
00101 void DMX::put (int addr, int data) {
00102     if (addr < 0 || addr >= DMX_SIZE) return;
00103     data_tx[addr] = data;
00104 }
00105 
00106 void DMX::put (unsigned char *buf, int addr, int len) {
00107     if (addr < 0 || addr >= DMX_SIZE) return;
00108     if (len > DMX_SIZE - addr) len = DMX_SIZE - addr;
00109     memcpy(&data_tx[addr], buf, len);
00110 }
00111 
00112 int DMX::get (int addr) {
00113     if (addr < 0 || addr >= DMX_SIZE) return -1;
00114     return data_rx[addr];
00115 }
00116 
00117 void DMX::get (unsigned char *buf, int addr, int len) {
00118     if (addr < 0 || addr >= DMX_SIZE) return;
00119     if (len > DMX_SIZE - addr) len = DMX_SIZE - addr;
00120     memcpy(buf, &data_rx[addr], len);
00121 }
00122 
00123 void DMX::int_timer () {
00124 
00125     switch (mode_tx) {
00126     case DMX_MODE_BEGIN:
00127         // Break Time
00128         timeout01.detach();
00129 #ifdef RDM_ENABLE
00130         if (mode_rdm && _xmit) _xmit->write(XMIT_TX);
00131 #endif
00132         _uart->LCR |= (1 << 6);
00133         mode_tx = DMX_MODE_BREAK;
00134         timeout01.attach_us(this, &DMX::int_timer, time_break);
00135         break;
00136 
00137     case DMX_MODE_BREAK:
00138         // Mark After Break
00139         timeout01.detach();
00140         _uart->LCR &= ~(1 << 6);
00141         mode_tx = DMX_MODE_MAB;
00142         timeout01.attach_us(this, &DMX::int_timer, time_mab);
00143         break;
00144 
00145     case DMX_MODE_MAB:
00146         // Start code
00147         timeout01.detach();
00148         addr_tx = 0;
00149         mode_tx = DMX_MODE_DATA;
00150 #ifdef DMX_UART_DIRECT
00151         while(!(_uart->LSR & (1<<5)));
00152 #ifdef RDM_ENABLE
00153         if (mode_rdm) {
00154             _uart->THR = RDM_START_CODE;
00155         } else {
00156             _uart->THR = DMX_START_CODE;
00157         }
00158 #else
00159         _uart->THR = DMX_START_CODE;
00160 #endif // RDM_ENABLE
00161 #else
00162 #ifdef RDM_ENABLE
00163         if (mode_rdm) {
00164             _dmx.putc(RDM_START_CODE);
00165         } else {
00166             _dmx.putc(DMX_START_CODE);
00167         }
00168 #else
00169         _dmx.putc(DMX_START_CODE);
00170 #endif // RDM_ENABLE
00171 #endif
00172         _dmx.attach(this, &DMX::int_tx, Serial::TxIrq);
00173         break;
00174     }
00175 }
00176 
00177 void DMX::int_tx () {
00178     // Data
00179     if (mode_tx == DMX_MODE_DATA) {
00180 #ifdef RDM_ENABLE
00181         if (mode_rdm && addr_tx < data_rdm[1] + 1) {
00182             // RDM data
00183             _dmx.putc(data_rdm[addr_tx]);
00184             addr_tx ++;
00185         } else
00186         if (!mode_rdm && addr_tx < DMX_SIZE) {
00187 #else
00188         if (addr_tx < DMX_SIZE) {
00189 #endif // RDM_ENABLE
00190             // DMX data
00191 #ifdef DMX_UART_DIRECT
00192             _uart->THR = (uint8_t)data_tx[addr_tx];
00193 #else
00194             _dmx.putc(data_tx[addr_tx]);
00195 #endif
00196             addr_tx ++;
00197         } else {
00198             _dmx.attach(0, Serial::TxIrq); // disable
00199             mode_tx = DMX_MODE_BEGIN;
00200             is_sent = 1;
00201 #ifdef RDM_ENABLE
00202             if (mode_rdm) {
00203                 if (_xmit) _xmit->write(XMIT_RX);
00204                 mode_rdm = 0;
00205                 mode_tx = DMX_MODE_STOP;
00206             } else {
00207                 timeout01.attach_us(this, &DMX::int_timer, time_mbb);
00208             }
00209 #else
00210             timeout01.attach_us(this, &DMX::int_timer, time_mbb);
00211 #endif // RDM_ENABLE
00212         }
00213     }
00214 }
00215 
00216 void DMX::int_rx () {
00217     int flg, dat;
00218 
00219     flg = _uart->LSR;
00220 #ifdef DMX_UART_DIRECT
00221     dat = _uart->RBR;
00222 #else
00223     dat = _dmx.getc();
00224 #endif
00225 
00226     if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) {
00227         // Break Time
00228         if (is_rdm_received) {
00229             return;
00230         } else
00231         if (addr_rx >= 24 && mode_rx == DMX_MODE_DATA) {
00232             is_received = 1;
00233         }
00234         mode_rx = DMX_MODE_BREAK;
00235         return;
00236     }
00237 
00238     if (mode_rx == DMX_MODE_BREAK) {
00239 
00240         // Start Code
00241         if (dat == DMX_START_CODE) {
00242             addr_rx = 0;
00243             mode_rx = DMX_MODE_DATA;
00244 #ifdef RDM_ENABLE
00245         } else
00246         if (dat == RDM_START_CODE) {
00247             addr_rx = 0;
00248             mode_rx = DMX_MODE_RDM;
00249 #endif
00250         } else {
00251             mode_rx = DMX_MODE_ERROR;
00252         }
00253 
00254     } else
00255     if (mode_rx == DMX_MODE_DATA) {
00256 
00257         // Data
00258         data_rx[addr_rx] = dat;
00259         addr_rx ++;
00260 
00261         if (addr_rx >= DMX_SIZE) {
00262             is_received = 1;
00263             mode_rx = DMX_MODE_BEGIN;
00264         }
00265 
00266 #ifdef RDM_ENABLE
00267     } else
00268     if (mode_rx == DMX_MODE_RDM) {
00269 
00270         // Rdm
00271         data_rx[addr_rx] = dat;
00272         addr_rx ++;
00273 
00274         if (addr_rx >= 2 && addr_rx >= data_rx[1] + 1) {
00275             is_rdm_received = 1;
00276             mode_rx = DMX_MODE_BEGIN;
00277         } else
00278         if (addr_rx >= sizeof(data_rdm)) {
00279             mode_rx = DMX_MODE_ERROR;
00280         }
00281 #endif
00282     }
00283 }
00284 
00285 void DMX::start () {
00286     if (mode_tx == DMX_MODE_STOP) {
00287 #ifdef RDM_ENABLE
00288         if (_xmit) _xmit->write(XMIT_TX);
00289 #endif
00290         mode_tx = DMX_MODE_BEGIN;
00291         is_sent = 0;
00292         timeout01.attach_us(this, &DMX::int_timer, time_mbb);
00293     }
00294 }
00295 
00296 void DMX::stop () {
00297     _dmx.attach(0, Serial::TxIrq);
00298     timeout01.detach();
00299     mode_tx = DMX_MODE_STOP;
00300 #ifdef RDM_ENABLE
00301     if (_xmit) _xmit->write(XMIT_RX);
00302 #endif
00303 }
00304 
00305 void DMX::clear () {
00306     int i;
00307 
00308     for (i = 0; i < DMX_SIZE; i ++) {
00309         data_tx[i] = 0;
00310         data_rx[i] = 0;
00311     }
00312 }
00313 
00314 int DMX::isReceived (){
00315     int r = is_received;
00316     is_received = 0;
00317     return r;
00318 }
00319 
00320 int DMX::isSent () {
00321     int r = is_sent;
00322     is_sent = 0;
00323     return r;
00324 }
00325 
00326 unsigned char *DMX::getRxBuffer () {
00327     return data_rx;
00328 }
00329 
00330 unsigned char *DMX::getTxBuffer () {
00331     return data_tx;
00332 }
00333 
00334 int DMX::setTimingParameters (int breaktime, int mab, int mbb) {
00335     if (breaktime < 88 || breaktime > 1000000) return -1;
00336     if (mab < 8 || mab > 1000000) return -1;
00337     if (mbb < 0 || mbb > 1000000) return -1;
00338 
00339     time_break = breaktime;
00340     time_mab   = mab;
00341     time_mbb   = mbb;
00342     return 0;
00343 }