DMX512 send/recv library with STM32 slave support originally from http://mbed.org/users/okini3939/notebook/dmx512
Fork of DMX by
DMX.cpp
- Committer:
- okini3939
- Date:
- 2014-01-24
- Revision:
- 13:9841af9ac344
- Parent:
- 12:1f176eee2d28
- Child:
- 15:4ea4a31c7609
File content as of revision 13:9841af9ac344:
/* * 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_recived = 0; is_sent = 0; #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) { _uart = LPC_UART3; NVIC_SetPriority(UART3_IRQn, 1); } else if (p_rx == p31) { _uart = (LPC_UART_TypeDef*)LPC_UART4; NVIC_SetPriority(UART4_IRQn, 1); } #elif defined(TARGET_LPC11U24) 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(); _uart->LCR |= (1 << 6); mode_tx = DMX_MODE_BREAK; timeout01.attach_us(this, &DMX::int_timer, DMX_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, DMX_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, DMX_TIME_BETWEEN); } } } 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 (addr_rx >= 24) { is_recived = 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; } 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_recived = 1; 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, DMX_TIME_BETWEEN); } } void DMX::stop () { _dmx.attach(0, Serial::TxIrq); timeout01.detach(); mode_tx = DMX_MODE_STOP; } void DMX::clear () { int i; for (i = 0; i < DMX_SIZE; i ++) { data_tx[i] = 0; data_rx[i] = 0; } }