DMX512 send/recv library with STM32 slave support originally from http://mbed.org/users/okini3939/notebook/dmx512
Fork of DMX by
DMX.cpp
- Committer:
- Ingram
- Date:
- 2016-05-31
- Revision:
- 20:908740273e88
- Parent:
- 19:6534f3ffdfec
- Child:
- 21:36276a92303f
File content as of revision 20:908740273e88:
/* * DMX512 send/recv library * Copyright (c) 2013 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) : _dmx(p_tx, p_rx) { clear(); // mode_tx = DMX_MODE_BEGIN; mode_tx = DMX_MODE_STOP; mode_rx = DMX_MODE_BEGIN; is_received = 0; is_sent = 0; time_break = DMX_TIME_BREAK; time_mab = DMX_TIME_MAB; time_mbb = DMX_TIME_MBB; #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); } #elif defined(TARGET_NUCLEO_F303K8) if (p_rx == PA_10 || p_rx == PB_7) { _uart = (USART_TypeDef*) USART1; NVIC_SetPriority(USART1_IRQn, 1); } else if (p_rx == PA_3 || p_rx == PB_4) { _uart = (USART_TypeDef*) USART2; NVIC_SetPriority(USART2_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(); #if defined(TARGET_STM) // TODO: I didn't need to send anything over DMX, so this is not implemented // If you wish to find out how to interface with USART on a low level, check // http://www.keil.com/dd/docs/datashts/st/stm32f3xx/dm00043574.pdf #else _uart->LCR |= (1 << 6); #endif mode_tx = DMX_MODE_BREAK; timeout01.attach_us(this, &DMX::int_timer, time_break); break; case DMX_MODE_BREAK: // Mark After Break timeout01.detach(); #if defined(TARGET_STM) // TODO see above #else _uart->LCR &= ~(1 << 6); #endif 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; _dmx.attach(this, &DMX::int_tx, Serial::TxIrq); #ifdef DMX_UART_DIRECT while(!(_uart->LSR & (1<<5))); _uart->THR = DMX_START_CODE; #else _dmx.putc(DMX_START_CODE); #endif break; } } void DMX::int_tx () { // Data if (mode_tx == DMX_MODE_DATA) { if (addr_tx < DMX_SIZE) { #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); mode_tx = DMX_MODE_BEGIN; is_sent = 1; timeout01.attach_us(this, &DMX::int_timer, time_mbb); } } } void DMX::int_rx () { int flg, dat; #ifdef TARGET_STM dat = _dmx.getc(); flg = (_uart->ISR & (USART_FLAG_FE | USART_ISR_IDLE)) == (USART_FLAG_FE | USART_ISR_IDLE); if (flg) { _uart->ICR = USART_ICR_FECF; } #else flg = _uart->LSR & ((1 << 7)|(1 << 3)|(1 << 4)); #ifdef DMX_UART_DIRECT dat = _uart->RBR; #else dat = _dmx.getc(); #endif #endif if (flg) { // Break Time if (addr_rx >= 24 && mode_rx == DMX_MODE_DATA) { on_received(); } 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; } else { mode_rx = DMX_MODE_ERROR; } } else if (mode_rx == DMX_MODE_DATA) { // Data data_rx_working[addr_rx] = dat; addr_rx ++; if (addr_rx >= DMX_SIZE) { on_received(); mode_rx = DMX_MODE_BEGIN; } } } void DMX::start () { if (mode_tx == DMX_MODE_STOP) { 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; } void DMX::clear () { memset(data_rx, 0, sizeof(data_rx)); memset(data_tx, 0, sizeof(data_rx)); memset(data_rx_working, 0, sizeof(data_rx_working)); } 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; } void DMX::attach(void (*function)(void)) { on_rx.attach(function); } void DMX::on_received() { memcpy(data_rx, data_rx_working, sizeof(data_rx_working)); is_received = 1; on_rx.call(); }