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

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

DMX512 send/recv library

DMX512 is protocol for lighting.

調光プロトコル DMX512 を送受信するライブラリです。

see: http://mbed.org/users/okini3939/notebook/dmx512/

LPC1114 support is thanks to Stanly Chen

DMX.cpp

Committer:
okini3939
Date:
2012-06-26
Revision:
0:cbff6bf41542
Child:
1:f0d988e15810

File content as of revision 0:cbff6bf41542:

/*
 * DMX512 send/recv library
 * Copyright (c) 2011 Hiroshi Suga
 * Released under the MIT License: http://mbed.org/license/mit
 */

/** @file DMX.cpp
 * @brief DMX512 send/recv
 */

#include "mbed.h"
#include "DMX.h"

DMX::DMX (PinName p_tx, PinName p_rx) : dmx(p_tx, p_rx) {
    int i;

    for (i = 0; i < DMX_SIZE; i ++) {
        data_tx[i] = 0;
        data_rx[i] = 0;
    }
    mode_tx = DMX_MODE_BEGIN;
    mode_rx = DMX_MODE_BEGIN;
    is_recived = 0;
    is_sent = 0;

    if (p_tx == p9) {
      uart_lcr = &LPC_UART3->LCR;
      uart_thr = &LPC_UART3->THR;
    } else
    if (p_tx == p13) {
      uart_lcr = &LPC_UART1->LCR;
      uart_thr = &LPC_UART1->THR;
    } else
    if (p_tx == p28) {
      uart_lcr = &LPC_UART2->LCR;
      uart_thr = &LPC_UART2->THR;
    }
    if (p_rx == p10) {
      uart_lsr = &LPC_UART3->LSR;
      uart_rbr = &LPC_UART3->RBR;
      NVIC_SetPriority(UART3_IRQn, 1);
    } else
    if (p_rx == p14) {
      uart_lsr = &LPC_UART1->LSR;
      uart_rbr = &LPC_UART1->RBR;
      NVIC_SetPriority(UART1_IRQn, 1);
    } else
    if (p_rx == p27) {
      uart_lsr = &LPC_UART2->LSR;
      uart_rbr = &LPC_UART2->RBR;
      NVIC_SetPriority(UART2_IRQn, 1);
    }

    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 ch, int data) {
    data_tx[ch] = data;
}

int DMX::get (int ch) {
    return data_rx[ch];
}

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);
        dmx.putc(0);
        break;
    }
}

void DMX::int_tx () {
    // Data
    if (mode_tx == DMX_MODE_DATA) {
        if (addr_tx < DMX_SIZE) {
#ifdef DMX_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;
    dat = dmx.getc();

    if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) {
        // Break Time
        if (addr_rx > 0) {
            is_recived = 1;
        }
        mode_rx = DMX_MODE_BREAK;
        return;
    }

    if (mode_rx == DMX_MODE_BREAK) {

        // Start Code
        if (dat == 0) {
            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;
        }
    }
}