Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of DMX by
DMX.cpp
00001 /* 00002 * DMX512 send/recv library 00003 * Copyright (c) 2013 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 DMX::DMX (PinName p_tx, PinName p_rx) : _dmx(p_tx, p_rx, 250000) { 00015 clear(); 00016 // mode_tx = DMX_MODE_BEGIN; 00017 mode_tx = DMX_MODE_STOP; 00018 mode_rx = DMX_MODE_BEGIN; 00019 is_received = 0; 00020 is_sent = 0; 00021 time_break = DMX_TIME_BREAK; 00022 time_mab = DMX_TIME_MAB; 00023 time_mbb = DMX_TIME_MBB; 00024 00025 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) 00026 if (p_rx == P0_3) { 00027 _uart = (LPC_UART_TypeDef*)LPC_UART0; 00028 NVIC_SetPriority(UART0_IRQn, 1); 00029 } else 00030 if (p_rx == p14) { 00031 _uart = (LPC_UART_TypeDef*)LPC_UART1; 00032 NVIC_SetPriority(UART1_IRQn, 1); 00033 } else 00034 if (p_rx == p27) { 00035 _uart = LPC_UART2; 00036 NVIC_SetPriority(UART2_IRQn, 1); 00037 } else 00038 if (p_rx == p10) { 00039 _uart = LPC_UART3; 00040 NVIC_SetPriority(UART3_IRQn, 1); 00041 } 00042 #elif defined(TARGET_LPC4088) 00043 if (p_rx == p10 || p_rx == P0_26 || p_rx == P4_29) { 00044 _uart = LPC_UART3; 00045 NVIC_SetPriority(UART3_IRQn, 1); 00046 } else 00047 if (p_rx == p31) { 00048 _uart = (LPC_UART_TypeDef*)LPC_UART4; 00049 NVIC_SetPriority(UART4_IRQn, 1); 00050 } else 00051 if (p_rx == P0_3) { 00052 _uart = LPC_UART0; 00053 NVIC_SetPriority(UART0_IRQn, 1); 00054 } else 00055 if (p_rx == P0_16 || p_rx == P2_1 || p_rx == P3_17) { 00056 _uart = (LPC_UART_TypeDef*)LPC_UART1; 00057 NVIC_SetPriority(UART1_IRQn, 1); 00058 } else 00059 if (p_rx == P0_11 || p_rx == P2_9 || p_rx == P4_23) { 00060 _uart = LPC_UART2; 00061 NVIC_SetPriority(UART2_IRQn, 1); 00062 } 00063 #elif defined(TARGET_LPC11UXX) 00064 if (p_rx == p10) { 00065 _uart = LPC_USART; 00066 NVIC_SetPriority(UART_IRQn, 1); 00067 } 00068 #elif defined(TARGET_LPC11XX) 00069 // LPC1114 support by Stanly Chen 00070 if (p_rx == P1_6) { 00071 _uart = (LPC_UART_TypeDef*)UART_0; 00072 NVIC_SetPriority(UART_IRQn, 1); 00073 } 00074 #elif defined(TARGET_NUCLEO_F303K8) 00075 if (p_rx == PA_10 || p_rx == PB_7) { 00076 _uart = (USART_TypeDef*) USART1; 00077 NVIC_SetPriority(USART1_IRQn, 1); 00078 } else 00079 if (p_rx == PA_3 || p_rx == PB_4) { 00080 _uart = (USART_TypeDef*) USART2; 00081 NVIC_SetPriority(USART2_IRQn, 1); 00082 } 00083 #endif 00084 00085 _dmx.format(8, Serial::None, 2); 00086 _dmx.attach(callback(this, &DMX::int_rx), Serial::RxIrq); 00087 00088 // timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN); 00089 } 00090 00091 void DMX::put (int addr, int data) { 00092 if (addr < 0 || addr >= DMX_SIZE) return; 00093 data_tx[addr] = data; 00094 } 00095 00096 void DMX::put (unsigned char *buf, int addr, int len) { 00097 if (addr < 0 || addr >= DMX_SIZE) return; 00098 if (len > DMX_SIZE - addr) len = DMX_SIZE - addr; 00099 memcpy(&data_tx[addr], buf, len); 00100 } 00101 00102 int DMX::get (int addr) { 00103 if (addr < 0 || addr >= DMX_SIZE) return -1; 00104 return data_rx[addr]; 00105 } 00106 00107 void DMX::get (unsigned char *buf, int addr, int len) { 00108 if (addr < 0 || addr >= DMX_SIZE) return; 00109 if (len > DMX_SIZE - addr) len = DMX_SIZE - addr; 00110 memcpy(buf, &data_rx[addr], len); 00111 } 00112 00113 void DMX::int_timer () { 00114 00115 switch (mode_tx) { 00116 case DMX_MODE_BEGIN: 00117 // Break Time 00118 timeout01.detach(); 00119 #if defined(TARGET_STM) 00120 // TODO: I didn't need to send anything over DMX, so this is not implemented 00121 // If you wish to find out how to interface with USART on a low level, check 00122 // http://www.keil.com/dd/docs/datashts/st/stm32f3xx/dm00043574.pdf 00123 #else 00124 _uart->LCR |= (1 << 6); 00125 #endif 00126 mode_tx = DMX_MODE_BREAK; 00127 timeout01.attach_us(callback(this, &DMX::int_timer), time_break); 00128 break; 00129 00130 case DMX_MODE_BREAK: 00131 // Mark After Break 00132 timeout01.detach(); 00133 #if defined(TARGET_STM) 00134 // TODO see above 00135 #else 00136 _uart->LCR &= ~(1 << 6); 00137 #endif 00138 mode_tx = DMX_MODE_MAB; 00139 timeout01.attach_us(callback(this, &DMX::int_timer), time_mab); 00140 break; 00141 00142 case DMX_MODE_MAB: 00143 // Start code 00144 timeout01.detach(); 00145 addr_tx = 0; 00146 mode_tx = DMX_MODE_DATA; 00147 _dmx.attach(callback(this, &DMX::int_tx), Serial::TxIrq); 00148 #ifdef DMX_UART_DIRECT 00149 while(!(_uart->LSR & (1<<5))); 00150 _uart->THR = DMX_START_CODE; 00151 #else 00152 _dmx.putc(DMX_START_CODE); 00153 #endif 00154 break; 00155 } 00156 } 00157 00158 void DMX::int_tx () { 00159 // Data 00160 if (mode_tx == DMX_MODE_DATA) { 00161 if (addr_tx < DMX_SIZE) { 00162 #ifdef DMX_UART_DIRECT 00163 _uart->THR = (uint8_t)data_tx[addr_tx]; 00164 #else 00165 _dmx.putc(data_tx[addr_tx]); 00166 #endif 00167 addr_tx ++; 00168 } else { 00169 _dmx.attach(0, Serial::TxIrq); 00170 mode_tx = DMX_MODE_BEGIN; 00171 is_sent = 1; 00172 timeout01.attach_us(callback(this, &DMX::int_timer), time_mbb); 00173 } 00174 } 00175 } 00176 00177 void DMX::int_rx () { 00178 int flg, dat; 00179 00180 #ifdef TARGET_STM 00181 dat = _dmx.getc(); 00182 flg = (_uart->ISR & (USART_FLAG_FE | USART_ISR_IDLE)) == (USART_FLAG_FE | USART_ISR_IDLE); 00183 if (flg) { 00184 _uart->ICR = USART_ICR_FECF; 00185 } 00186 #else 00187 flg = _uart->LSR & ((1 << 7)|(1 << 3)|(1 << 4)); 00188 #ifdef DMX_UART_DIRECT 00189 dat = _uart->RBR; 00190 #else 00191 dat = _dmx.getc(); 00192 #endif 00193 #endif 00194 00195 if (flg) { 00196 // Break Time 00197 if (addr_rx >= 24 && mode_rx == DMX_MODE_DATA) { 00198 on_received(); 00199 } 00200 mode_rx = DMX_MODE_BREAK; 00201 return; 00202 } 00203 00204 if (mode_rx == DMX_MODE_BREAK) { 00205 00206 // Start Code 00207 if (dat == DMX_START_CODE) { 00208 addr_rx = 0; 00209 mode_rx = DMX_MODE_DATA; 00210 } else { 00211 mode_rx = DMX_MODE_ERROR; 00212 } 00213 00214 } else 00215 if (mode_rx == DMX_MODE_DATA) { 00216 00217 // Data 00218 data_rx_working[addr_rx] = dat; 00219 addr_rx ++; 00220 00221 if (addr_rx >= DMX_SIZE) { 00222 on_received(); 00223 mode_rx = DMX_MODE_BEGIN; 00224 } 00225 } 00226 } 00227 00228 void DMX::start () { 00229 if (mode_tx == DMX_MODE_STOP) { 00230 mode_tx = DMX_MODE_BEGIN; 00231 is_sent = 0; 00232 timeout01.attach_us(callback(this, &DMX::int_timer), time_mbb); 00233 } 00234 } 00235 00236 void DMX::stop () { 00237 _dmx.attach(0, Serial::TxIrq); 00238 timeout01.detach(); 00239 mode_tx = DMX_MODE_STOP; 00240 } 00241 00242 void DMX::clear () { 00243 memset(data_rx, 0, sizeof(data_rx)); 00244 memset(data_tx, 0, sizeof(data_rx)); 00245 memset(data_rx_working, 0, sizeof(data_rx_working)); 00246 } 00247 00248 int DMX::isReceived (){ 00249 int r = is_received; 00250 is_received = 0; 00251 return r; 00252 } 00253 00254 int DMX::isSent () { 00255 int r = is_sent; 00256 is_sent = 0; 00257 return r; 00258 } 00259 00260 unsigned char *DMX::getRxBuffer () { 00261 return data_rx; 00262 } 00263 00264 unsigned char *DMX::getTxBuffer () { 00265 return data_tx; 00266 } 00267 00268 int DMX::setTimingParameters (int breaktime, int mab, int mbb) { 00269 if (breaktime < 88 || breaktime > 1000000) return -1; 00270 if (mab < 8 || mab > 1000000) return -1; 00271 if (mbb < 0 || mbb > 1000000) return -1; 00272 00273 time_break = breaktime; 00274 time_mab = mab; 00275 time_mbb = mbb; 00276 return 0; 00277 } 00278 00279 void DMX::attach(void (*function)(void)) { 00280 on_rx.attach(function); 00281 } 00282 00283 void DMX::on_received() { 00284 memcpy(data_rx, data_rx_working, sizeof(data_rx_working)); 00285 is_received = 1; 00286 on_rx.call(); 00287 }
Generated on Wed Jul 20 2022 05:54:08 by
1.7.2
