DMX512 send/recv library with STM32 slave support originally from http://mbed.org/users/okini3939/notebook/dmx512

Fork of DMX by Suga koubou

Committer:
Ingram
Date:
Sat Mar 04 10:24:03 2017 +0000
Revision:
21:36276a92303f
Parent:
20:908740273e88
Remove deprecations

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:cbff6bf41542 1 /*
okini3939 0:cbff6bf41542 2 * DMX512 send/recv library
okini3939 6:9e7b4eeac6ec 3 * Copyright (c) 2013 Hiroshi Suga
okini3939 0:cbff6bf41542 4 * Released under the MIT License: http://mbed.org/license/mit
okini3939 0:cbff6bf41542 5 */
okini3939 0:cbff6bf41542 6
okini3939 7:16d6874076dd 7 /** @file
okini3939 0:cbff6bf41542 8 * @brief DMX512 send/recv
okini3939 0:cbff6bf41542 9 */
okini3939 0:cbff6bf41542 10
okini3939 0:cbff6bf41542 11 #include "mbed.h"
okini3939 0:cbff6bf41542 12 #include "DMX.h"
okini3939 0:cbff6bf41542 13
Ingram 21:36276a92303f 14 DMX::DMX (PinName p_tx, PinName p_rx) : _dmx(p_tx, p_rx, 250000) {
okini3939 12:1f176eee2d28 15 clear();
okini3939 4:dd0544c80096 16 // mode_tx = DMX_MODE_BEGIN;
okini3939 4:dd0544c80096 17 mode_tx = DMX_MODE_STOP;
okini3939 0:cbff6bf41542 18 mode_rx = DMX_MODE_BEGIN;
okini3939 18:69d65ca92bcc 19 is_received = 0;
okini3939 18:69d65ca92bcc 20 is_sent = 0;
okini3939 18:69d65ca92bcc 21 time_break = DMX_TIME_BREAK;
okini3939 18:69d65ca92bcc 22 time_mab = DMX_TIME_MAB;
okini3939 18:69d65ca92bcc 23 time_mbb = DMX_TIME_MBB;
okini3939 0:cbff6bf41542 24
okini3939 5:72039cd4c874 25 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 11:cb132e066057 26 if (p_rx == P0_3) {
okini3939 11:cb132e066057 27 _uart = (LPC_UART_TypeDef*)LPC_UART0;
okini3939 11:cb132e066057 28 NVIC_SetPriority(UART0_IRQn, 1);
okini3939 0:cbff6bf41542 29 } else
okini3939 0:cbff6bf41542 30 if (p_rx == p14) {
okini3939 8:d4a45bba41d2 31 _uart = (LPC_UART_TypeDef*)LPC_UART1;
okini3939 0:cbff6bf41542 32 NVIC_SetPriority(UART1_IRQn, 1);
okini3939 0:cbff6bf41542 33 } else
okini3939 0:cbff6bf41542 34 if (p_rx == p27) {
okini3939 8:d4a45bba41d2 35 _uart = LPC_UART2;
okini3939 0:cbff6bf41542 36 NVIC_SetPriority(UART2_IRQn, 1);
okini3939 11:cb132e066057 37 } else
okini3939 11:cb132e066057 38 if (p_rx == p10) {
okini3939 11:cb132e066057 39 _uart = LPC_UART3;
okini3939 11:cb132e066057 40 NVIC_SetPriority(UART3_IRQn, 1);
okini3939 0:cbff6bf41542 41 }
okini3939 13:9841af9ac344 42 #elif defined(TARGET_LPC4088)
okini3939 16:4eeb749806e5 43 if (p_rx == p10 || p_rx == P0_26 || p_rx == P4_29) {
okini3939 13:9841af9ac344 44 _uart = LPC_UART3;
okini3939 13:9841af9ac344 45 NVIC_SetPriority(UART3_IRQn, 1);
okini3939 13:9841af9ac344 46 } else
okini3939 13:9841af9ac344 47 if (p_rx == p31) {
okini3939 13:9841af9ac344 48 _uart = (LPC_UART_TypeDef*)LPC_UART4;
okini3939 13:9841af9ac344 49 NVIC_SetPriority(UART4_IRQn, 1);
okini3939 16:4eeb749806e5 50 } else
okini3939 16:4eeb749806e5 51 if (p_rx == P0_3) {
okini3939 16:4eeb749806e5 52 _uart = LPC_UART0;
okini3939 16:4eeb749806e5 53 NVIC_SetPriority(UART0_IRQn, 1);
okini3939 16:4eeb749806e5 54 } else
okini3939 16:4eeb749806e5 55 if (p_rx == P0_16 || p_rx == P2_1 || p_rx == P3_17) {
okini3939 16:4eeb749806e5 56 _uart = (LPC_UART_TypeDef*)LPC_UART1;
okini3939 16:4eeb749806e5 57 NVIC_SetPriority(UART1_IRQn, 1);
okini3939 16:4eeb749806e5 58 } else
okini3939 16:4eeb749806e5 59 if (p_rx == P0_11 || p_rx == P2_9 || p_rx == P4_23) {
okini3939 16:4eeb749806e5 60 _uart = LPC_UART2;
okini3939 16:4eeb749806e5 61 NVIC_SetPriority(UART2_IRQn, 1);
okini3939 13:9841af9ac344 62 }
okini3939 15:4ea4a31c7609 63 #elif defined(TARGET_LPC11UXX)
okini3939 5:72039cd4c874 64 if (p_rx == p10) {
okini3939 8:d4a45bba41d2 65 _uart = LPC_USART;
okini3939 5:72039cd4c874 66 NVIC_SetPriority(UART_IRQn, 1);
okini3939 5:72039cd4c874 67 }
stanly88 10:b748aab8404c 68 #elif defined(TARGET_LPC11XX)
okini3939 11:cb132e066057 69 // LPC1114 support by Stanly Chen
stanly88 10:b748aab8404c 70 if (p_rx == P1_6) {
okini3939 13:9841af9ac344 71 _uart = (LPC_UART_TypeDef*)UART_0;
stanly88 10:b748aab8404c 72 NVIC_SetPriority(UART_IRQn, 1);
stanly88 10:b748aab8404c 73 }
Ingram 19:6534f3ffdfec 74 #elif defined(TARGET_NUCLEO_F303K8)
Ingram 19:6534f3ffdfec 75 if (p_rx == PA_10 || p_rx == PB_7) {
Ingram 19:6534f3ffdfec 76 _uart = (USART_TypeDef*) USART1;
Ingram 19:6534f3ffdfec 77 NVIC_SetPriority(USART1_IRQn, 1);
Ingram 19:6534f3ffdfec 78 } else
Ingram 19:6534f3ffdfec 79 if (p_rx == PA_3 || p_rx == PB_4) {
Ingram 19:6534f3ffdfec 80 _uart = (USART_TypeDef*) USART2;
Ingram 19:6534f3ffdfec 81 NVIC_SetPriority(USART2_IRQn, 1);
Ingram 19:6534f3ffdfec 82 }
okini3939 5:72039cd4c874 83 #endif
okini3939 0:cbff6bf41542 84
okini3939 5:72039cd4c874 85 _dmx.format(8, Serial::None, 2);
Ingram 21:36276a92303f 86 _dmx.attach(callback(this, &DMX::int_rx), Serial::RxIrq);
okini3939 0:cbff6bf41542 87
okini3939 4:dd0544c80096 88 // timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN);
okini3939 0:cbff6bf41542 89 }
okini3939 0:cbff6bf41542 90
okini3939 6:9e7b4eeac6ec 91 void DMX::put (int addr, int data) {
okini3939 6:9e7b4eeac6ec 92 if (addr < 0 || addr >= DMX_SIZE) return;
okini3939 6:9e7b4eeac6ec 93 data_tx[addr] = data;
okini3939 0:cbff6bf41542 94 }
okini3939 0:cbff6bf41542 95
okini3939 6:9e7b4eeac6ec 96 void DMX::put (unsigned char *buf, int addr, int len) {
okini3939 6:9e7b4eeac6ec 97 if (addr < 0 || addr >= DMX_SIZE) return;
okini3939 6:9e7b4eeac6ec 98 if (len > DMX_SIZE - addr) len = DMX_SIZE - addr;
okini3939 6:9e7b4eeac6ec 99 memcpy(&data_tx[addr], buf, len);
okini3939 6:9e7b4eeac6ec 100 }
okini3939 6:9e7b4eeac6ec 101
okini3939 6:9e7b4eeac6ec 102 int DMX::get (int addr) {
okini3939 6:9e7b4eeac6ec 103 if (addr < 0 || addr >= DMX_SIZE) return -1;
okini3939 6:9e7b4eeac6ec 104 return data_rx[addr];
okini3939 6:9e7b4eeac6ec 105 }
okini3939 6:9e7b4eeac6ec 106
okini3939 6:9e7b4eeac6ec 107 void DMX::get (unsigned char *buf, int addr, int len) {
okini3939 6:9e7b4eeac6ec 108 if (addr < 0 || addr >= DMX_SIZE) return;
okini3939 6:9e7b4eeac6ec 109 if (len > DMX_SIZE - addr) len = DMX_SIZE - addr;
okini3939 6:9e7b4eeac6ec 110 memcpy(buf, &data_rx[addr], len);
okini3939 0:cbff6bf41542 111 }
okini3939 0:cbff6bf41542 112
okini3939 0:cbff6bf41542 113 void DMX::int_timer () {
okini3939 0:cbff6bf41542 114
okini3939 0:cbff6bf41542 115 switch (mode_tx) {
okini3939 0:cbff6bf41542 116 case DMX_MODE_BEGIN:
okini3939 0:cbff6bf41542 117 // Break Time
okini3939 0:cbff6bf41542 118 timeout01.detach();
Ingram 19:6534f3ffdfec 119 #if defined(TARGET_STM)
Ingram 19:6534f3ffdfec 120 // TODO: I didn't need to send anything over DMX, so this is not implemented
Ingram 19:6534f3ffdfec 121 // If you wish to find out how to interface with USART on a low level, check
Ingram 19:6534f3ffdfec 122 // http://www.keil.com/dd/docs/datashts/st/stm32f3xx/dm00043574.pdf
Ingram 19:6534f3ffdfec 123 #else
Ingram 19:6534f3ffdfec 124 _uart->LCR |= (1 << 6);
Ingram 19:6534f3ffdfec 125 #endif
okini3939 0:cbff6bf41542 126 mode_tx = DMX_MODE_BREAK;
Ingram 21:36276a92303f 127 timeout01.attach_us(callback(this, &DMX::int_timer), time_break);
okini3939 0:cbff6bf41542 128 break;
okini3939 0:cbff6bf41542 129
okini3939 0:cbff6bf41542 130 case DMX_MODE_BREAK:
okini3939 0:cbff6bf41542 131 // Mark After Break
okini3939 0:cbff6bf41542 132 timeout01.detach();
Ingram 19:6534f3ffdfec 133 #if defined(TARGET_STM)
Ingram 19:6534f3ffdfec 134 // TODO see above
Ingram 19:6534f3ffdfec 135 #else
Ingram 19:6534f3ffdfec 136 _uart->LCR &= ~(1 << 6);
Ingram 19:6534f3ffdfec 137 #endif
okini3939 0:cbff6bf41542 138 mode_tx = DMX_MODE_MAB;
Ingram 21:36276a92303f 139 timeout01.attach_us(callback(this, &DMX::int_timer), time_mab);
okini3939 0:cbff6bf41542 140 break;
okini3939 0:cbff6bf41542 141
okini3939 0:cbff6bf41542 142 case DMX_MODE_MAB:
okini3939 0:cbff6bf41542 143 // Start code
okini3939 0:cbff6bf41542 144 timeout01.detach();
okini3939 0:cbff6bf41542 145 addr_tx = 0;
okini3939 0:cbff6bf41542 146 mode_tx = DMX_MODE_DATA;
Ingram 21:36276a92303f 147 _dmx.attach(callback(this, &DMX::int_tx), Serial::TxIrq);
okini3939 2:d7677060f8eb 148 #ifdef DMX_UART_DIRECT
okini3939 9:e687f321c428 149 while(!(_uart->LSR & (1<<5)));
okini3939 9:e687f321c428 150 _uart->THR = DMX_START_CODE;
okini3939 2:d7677060f8eb 151 #else
okini3939 9:e687f321c428 152 _dmx.putc(DMX_START_CODE);
okini3939 2:d7677060f8eb 153 #endif
okini3939 0:cbff6bf41542 154 break;
okini3939 0:cbff6bf41542 155 }
okini3939 0:cbff6bf41542 156 }
okini3939 0:cbff6bf41542 157
okini3939 0:cbff6bf41542 158 void DMX::int_tx () {
okini3939 0:cbff6bf41542 159 // Data
okini3939 0:cbff6bf41542 160 if (mode_tx == DMX_MODE_DATA) {
okini3939 0:cbff6bf41542 161 if (addr_tx < DMX_SIZE) {
okini3939 1:f0d988e15810 162 #ifdef DMX_UART_DIRECT
okini3939 8:d4a45bba41d2 163 _uart->THR = (uint8_t)data_tx[addr_tx];
okini3939 0:cbff6bf41542 164 #else
okini3939 5:72039cd4c874 165 _dmx.putc(data_tx[addr_tx]);
okini3939 0:cbff6bf41542 166 #endif
okini3939 0:cbff6bf41542 167 addr_tx ++;
okini3939 0:cbff6bf41542 168 } else {
okini3939 5:72039cd4c874 169 _dmx.attach(0, Serial::TxIrq);
okini3939 0:cbff6bf41542 170 mode_tx = DMX_MODE_BEGIN;
okini3939 0:cbff6bf41542 171 is_sent = 1;
Ingram 21:36276a92303f 172 timeout01.attach_us(callback(this, &DMX::int_timer), time_mbb);
okini3939 0:cbff6bf41542 173 }
okini3939 0:cbff6bf41542 174 }
okini3939 0:cbff6bf41542 175 }
okini3939 0:cbff6bf41542 176
okini3939 0:cbff6bf41542 177 void DMX::int_rx () {
okini3939 0:cbff6bf41542 178 int flg, dat;
okini3939 0:cbff6bf41542 179
Ingram 19:6534f3ffdfec 180 #ifdef TARGET_STM
Ingram 19:6534f3ffdfec 181 dat = _dmx.getc();
Ingram 19:6534f3ffdfec 182 flg = (_uart->ISR & (USART_FLAG_FE | USART_ISR_IDLE)) == (USART_FLAG_FE | USART_ISR_IDLE);
Ingram 19:6534f3ffdfec 183 if (flg) {
Ingram 19:6534f3ffdfec 184 _uart->ICR = USART_ICR_FECF;
Ingram 19:6534f3ffdfec 185 }
Ingram 19:6534f3ffdfec 186 #else
Ingram 19:6534f3ffdfec 187 flg = _uart->LSR & ((1 << 7)|(1 << 3)|(1 << 4));
Ingram 19:6534f3ffdfec 188 #ifdef DMX_UART_DIRECT
Ingram 19:6534f3ffdfec 189 dat = _uart->RBR;
Ingram 19:6534f3ffdfec 190 #else
Ingram 19:6534f3ffdfec 191 dat = _dmx.getc();
Ingram 19:6534f3ffdfec 192 #endif
Ingram 19:6534f3ffdfec 193 #endif
okini3939 0:cbff6bf41542 194
Ingram 19:6534f3ffdfec 195 if (flg) {
okini3939 0:cbff6bf41542 196 // Break Time
okini3939 15:4ea4a31c7609 197 if (addr_rx >= 24 && mode_rx == DMX_MODE_DATA) {
Ingram 20:908740273e88 198 on_received();
okini3939 0:cbff6bf41542 199 }
okini3939 0:cbff6bf41542 200 mode_rx = DMX_MODE_BREAK;
okini3939 0:cbff6bf41542 201 return;
okini3939 0:cbff6bf41542 202 }
okini3939 0:cbff6bf41542 203
okini3939 0:cbff6bf41542 204 if (mode_rx == DMX_MODE_BREAK) {
okini3939 0:cbff6bf41542 205
okini3939 0:cbff6bf41542 206 // Start Code
okini3939 9:e687f321c428 207 if (dat == DMX_START_CODE) {
okini3939 0:cbff6bf41542 208 addr_rx = 0;
okini3939 0:cbff6bf41542 209 mode_rx = DMX_MODE_DATA;
okini3939 0:cbff6bf41542 210 } else {
okini3939 0:cbff6bf41542 211 mode_rx = DMX_MODE_ERROR;
okini3939 0:cbff6bf41542 212 }
okini3939 0:cbff6bf41542 213
okini3939 0:cbff6bf41542 214 } else
okini3939 0:cbff6bf41542 215 if (mode_rx == DMX_MODE_DATA) {
okini3939 0:cbff6bf41542 216
okini3939 0:cbff6bf41542 217 // Data
Ingram 20:908740273e88 218 data_rx_working[addr_rx] = dat;
okini3939 0:cbff6bf41542 219 addr_rx ++;
okini3939 0:cbff6bf41542 220
okini3939 0:cbff6bf41542 221 if (addr_rx >= DMX_SIZE) {
Ingram 20:908740273e88 222 on_received();
okini3939 0:cbff6bf41542 223 mode_rx = DMX_MODE_BEGIN;
okini3939 0:cbff6bf41542 224 }
okini3939 0:cbff6bf41542 225 }
okini3939 0:cbff6bf41542 226 }
okini3939 0:cbff6bf41542 227
okini3939 4:dd0544c80096 228 void DMX::start () {
okini3939 4:dd0544c80096 229 if (mode_tx == DMX_MODE_STOP) {
okini3939 4:dd0544c80096 230 mode_tx = DMX_MODE_BEGIN;
okini3939 4:dd0544c80096 231 is_sent = 0;
Ingram 21:36276a92303f 232 timeout01.attach_us(callback(this, &DMX::int_timer), time_mbb);
okini3939 4:dd0544c80096 233 }
okini3939 4:dd0544c80096 234 }
okini3939 4:dd0544c80096 235
okini3939 4:dd0544c80096 236 void DMX::stop () {
okini3939 5:72039cd4c874 237 _dmx.attach(0, Serial::TxIrq);
okini3939 3:2eb66b4d99bd 238 timeout01.detach();
okini3939 4:dd0544c80096 239 mode_tx = DMX_MODE_STOP;
okini3939 3:2eb66b4d99bd 240 }
okini3939 12:1f176eee2d28 241
okini3939 12:1f176eee2d28 242 void DMX::clear () {
Ingram 20:908740273e88 243 memset(data_rx, 0, sizeof(data_rx));
Ingram 20:908740273e88 244 memset(data_tx, 0, sizeof(data_rx));
Ingram 20:908740273e88 245 memset(data_rx_working, 0, sizeof(data_rx_working));
okini3939 12:1f176eee2d28 246 }
okini3939 17:c9198630ba05 247
okini3939 18:69d65ca92bcc 248 int DMX::isReceived (){
okini3939 18:69d65ca92bcc 249 int r = is_received;
okini3939 18:69d65ca92bcc 250 is_received = 0;
okini3939 17:c9198630ba05 251 return r;
okini3939 17:c9198630ba05 252 }
okini3939 17:c9198630ba05 253
okini3939 17:c9198630ba05 254 int DMX::isSent () {
okini3939 17:c9198630ba05 255 int r = is_sent;
okini3939 17:c9198630ba05 256 is_sent = 0;
okini3939 17:c9198630ba05 257 return r;
okini3939 17:c9198630ba05 258 }
okini3939 17:c9198630ba05 259
okini3939 17:c9198630ba05 260 unsigned char *DMX::getRxBuffer () {
okini3939 17:c9198630ba05 261 return data_rx;
okini3939 17:c9198630ba05 262 }
okini3939 17:c9198630ba05 263
okini3939 17:c9198630ba05 264 unsigned char *DMX::getTxBuffer () {
okini3939 17:c9198630ba05 265 return data_tx;
okini3939 17:c9198630ba05 266 }
okini3939 18:69d65ca92bcc 267
okini3939 18:69d65ca92bcc 268 int DMX::setTimingParameters (int breaktime, int mab, int mbb) {
okini3939 18:69d65ca92bcc 269 if (breaktime < 88 || breaktime > 1000000) return -1;
okini3939 18:69d65ca92bcc 270 if (mab < 8 || mab > 1000000) return -1;
okini3939 18:69d65ca92bcc 271 if (mbb < 0 || mbb > 1000000) return -1;
okini3939 18:69d65ca92bcc 272
okini3939 18:69d65ca92bcc 273 time_break = breaktime;
okini3939 18:69d65ca92bcc 274 time_mab = mab;
okini3939 18:69d65ca92bcc 275 time_mbb = mbb;
okini3939 18:69d65ca92bcc 276 return 0;
okini3939 18:69d65ca92bcc 277 }
Ingram 20:908740273e88 278
Ingram 20:908740273e88 279 void DMX::attach(void (*function)(void)) {
Ingram 20:908740273e88 280 on_rx.attach(function);
Ingram 20:908740273e88 281 }
Ingram 20:908740273e88 282
Ingram 20:908740273e88 283 void DMX::on_received() {
Ingram 20:908740273e88 284 memcpy(data_rx, data_rx_working, sizeof(data_rx_working));
Ingram 20:908740273e88 285 is_received = 1;
Ingram 20:908740273e88 286 on_rx.call();
Ingram 20:908740273e88 287 }