Add support new target MCU: LPC1114FN28 or LPC11XX

Fork of DMX by Suga koubou

DMX.cpp

Committer:
okini3939
Date:
2013-03-29
Revision:
9:e687f321c428
Parent:
8:d4a45bba41d2
Child:
10:b748aab8404c

File content as of revision 9:e687f321c428:

/*
 * 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) {
    int i;

    for (i = 0; i < DMX_SIZE; i ++) {
        data_tx[i] = 0;
        data_rx[i] = 0;
    }
//    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 == p10) {
      _uart = LPC_UART3;
      NVIC_SetPriority(UART3_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);
    }
#elif defined(TARGET_LPC11U24)
    if (p_rx == p10) {
      _uart = LPC_USART;
      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;
}