This is a fork for okini3939's great DMX library with added support for the EA LPC4088 QuickStart mbed-enabled board. I have added support and tested the 3 UARTs which are accessible on the DIP pins. This forked of okini3939's library was created in the hopes a pull request could be accepted and re-integrated into the library. Important Note: To use the special UART on "pins 41" (rx) and "pin 42" (tx) you must access them by their port names, which are P0_3 (rx) and P0_2 (tx), because the symbols p41 and p42 do not exist in the mbed world (yet).
Fork of DMX by
DMX.cpp@13:197c0fea0c62, 2013-12-02 (annotated)
- Committer:
- robodude
- Date:
- Mon Dec 02 06:49:25 2013 +0000
- Revision:
- 13:197c0fea0c62
- Parent:
- 12:1f176eee2d28
Tested and added support for EA LPC4088 QuickStart mbed.
Who changed what in which revision?
User | Revision | Line number | New 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 | |
okini3939 | 5:72039cd4c874 | 14 | DMX::DMX (PinName p_tx, PinName p_rx) : _dmx(p_tx, p_rx) { |
okini3939 | 0:cbff6bf41542 | 15 | |
okini3939 | 12:1f176eee2d28 | 16 | clear(); |
okini3939 | 4:dd0544c80096 | 17 | // mode_tx = DMX_MODE_BEGIN; |
okini3939 | 4:dd0544c80096 | 18 | mode_tx = DMX_MODE_STOP; |
okini3939 | 0:cbff6bf41542 | 19 | mode_rx = DMX_MODE_BEGIN; |
okini3939 | 0:cbff6bf41542 | 20 | is_recived = 0; |
okini3939 | 0:cbff6bf41542 | 21 | is_sent = 0; |
okini3939 | 0:cbff6bf41542 | 22 | |
okini3939 | 5:72039cd4c874 | 23 | #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) |
okini3939 | 11:cb132e066057 | 24 | if (p_rx == P0_3) { |
okini3939 | 11:cb132e066057 | 25 | _uart = (LPC_UART_TypeDef*)LPC_UART0; |
okini3939 | 11:cb132e066057 | 26 | NVIC_SetPriority(UART0_IRQn, 1); |
okini3939 | 0:cbff6bf41542 | 27 | } else |
okini3939 | 0:cbff6bf41542 | 28 | if (p_rx == p14) { |
okini3939 | 8:d4a45bba41d2 | 29 | _uart = (LPC_UART_TypeDef*)LPC_UART1; |
okini3939 | 0:cbff6bf41542 | 30 | NVIC_SetPriority(UART1_IRQn, 1); |
okini3939 | 0:cbff6bf41542 | 31 | } else |
okini3939 | 0:cbff6bf41542 | 32 | if (p_rx == p27) { |
okini3939 | 8:d4a45bba41d2 | 33 | _uart = LPC_UART2; |
okini3939 | 0:cbff6bf41542 | 34 | NVIC_SetPriority(UART2_IRQn, 1); |
okini3939 | 11:cb132e066057 | 35 | } else |
okini3939 | 11:cb132e066057 | 36 | if (p_rx == p10) { |
okini3939 | 11:cb132e066057 | 37 | _uart = LPC_UART3; |
okini3939 | 11:cb132e066057 | 38 | NVIC_SetPriority(UART3_IRQn, 1); |
okini3939 | 0:cbff6bf41542 | 39 | } |
robodude | 13:197c0fea0c62 | 40 | #elif defined(TARGET_LPC4088) |
robodude | 13:197c0fea0c62 | 41 | // EA LPC4088 QuickStart Board mbed support by Robbie King |
robodude | 13:197c0fea0c62 | 42 | if (p_rx == P0_3) { // P0_3 ==> mbed "pin 41" on the EA LPC4088 QuickStart Board |
robodude | 13:197c0fea0c62 | 43 | _uart = (LPC_UART_TypeDef*)LPC_UART0; |
robodude | 13:197c0fea0c62 | 44 | NVIC_SetPriority(UART0_IRQn, 1); |
robodude | 13:197c0fea0c62 | 45 | } else |
robodude | 13:197c0fea0c62 | 46 | if (p_rx == p31) { |
robodude | 13:197c0fea0c62 | 47 | _uart = (LPC_UART_TypeDef*)LPC_UART4; |
robodude | 13:197c0fea0c62 | 48 | NVIC_SetPriority(UART4_IRQn, 1); |
robodude | 13:197c0fea0c62 | 49 | } else |
robodude | 13:197c0fea0c62 | 50 | if (p_rx == p10) { |
robodude | 13:197c0fea0c62 | 51 | _uart = LPC_UART3; |
robodude | 13:197c0fea0c62 | 52 | NVIC_SetPriority(UART3_IRQn, 1); |
robodude | 13:197c0fea0c62 | 53 | } |
okini3939 | 5:72039cd4c874 | 54 | #elif defined(TARGET_LPC11U24) |
okini3939 | 5:72039cd4c874 | 55 | if (p_rx == p10) { |
okini3939 | 8:d4a45bba41d2 | 56 | _uart = LPC_USART; |
okini3939 | 5:72039cd4c874 | 57 | NVIC_SetPriority(UART_IRQn, 1); |
okini3939 | 5:72039cd4c874 | 58 | } |
stanly88 | 10:b748aab8404c | 59 | #elif defined(TARGET_LPC11XX) |
okini3939 | 11:cb132e066057 | 60 | // LPC1114 support by Stanly Chen |
stanly88 | 10:b748aab8404c | 61 | if (p_rx == P1_6) { |
stanly88 | 10:b748aab8404c | 62 | _uart = (LPC_UART_TypeDef*) UART_0; |
stanly88 | 10:b748aab8404c | 63 | NVIC_SetPriority(UART_IRQn, 1); |
stanly88 | 10:b748aab8404c | 64 | } |
okini3939 | 5:72039cd4c874 | 65 | #endif |
okini3939 | 0:cbff6bf41542 | 66 | |
okini3939 | 5:72039cd4c874 | 67 | _dmx.baud(250000); |
okini3939 | 5:72039cd4c874 | 68 | _dmx.format(8, Serial::None, 2); |
okini3939 | 5:72039cd4c874 | 69 | _dmx.attach(this, &DMX::int_rx, Serial::RxIrq); |
okini3939 | 0:cbff6bf41542 | 70 | |
okini3939 | 4:dd0544c80096 | 71 | // timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN); |
okini3939 | 0:cbff6bf41542 | 72 | } |
okini3939 | 0:cbff6bf41542 | 73 | |
okini3939 | 6:9e7b4eeac6ec | 74 | void DMX::put (int addr, int data) { |
okini3939 | 6:9e7b4eeac6ec | 75 | if (addr < 0 || addr >= DMX_SIZE) return; |
okini3939 | 6:9e7b4eeac6ec | 76 | data_tx[addr] = data; |
okini3939 | 0:cbff6bf41542 | 77 | } |
okini3939 | 0:cbff6bf41542 | 78 | |
okini3939 | 6:9e7b4eeac6ec | 79 | void DMX::put (unsigned char *buf, int addr, int len) { |
okini3939 | 6:9e7b4eeac6ec | 80 | if (addr < 0 || addr >= DMX_SIZE) return; |
okini3939 | 6:9e7b4eeac6ec | 81 | if (len > DMX_SIZE - addr) len = DMX_SIZE - addr; |
okini3939 | 6:9e7b4eeac6ec | 82 | memcpy(&data_tx[addr], buf, len); |
okini3939 | 6:9e7b4eeac6ec | 83 | } |
okini3939 | 6:9e7b4eeac6ec | 84 | |
okini3939 | 6:9e7b4eeac6ec | 85 | int DMX::get (int addr) { |
okini3939 | 6:9e7b4eeac6ec | 86 | if (addr < 0 || addr >= DMX_SIZE) return -1; |
okini3939 | 6:9e7b4eeac6ec | 87 | return data_rx[addr]; |
okini3939 | 6:9e7b4eeac6ec | 88 | } |
okini3939 | 6:9e7b4eeac6ec | 89 | |
okini3939 | 6:9e7b4eeac6ec | 90 | void DMX::get (unsigned char *buf, int addr, int len) { |
okini3939 | 6:9e7b4eeac6ec | 91 | if (addr < 0 || addr >= DMX_SIZE) return; |
okini3939 | 6:9e7b4eeac6ec | 92 | if (len > DMX_SIZE - addr) len = DMX_SIZE - addr; |
okini3939 | 6:9e7b4eeac6ec | 93 | memcpy(buf, &data_rx[addr], len); |
okini3939 | 0:cbff6bf41542 | 94 | } |
okini3939 | 0:cbff6bf41542 | 95 | |
okini3939 | 0:cbff6bf41542 | 96 | void DMX::int_timer () { |
okini3939 | 0:cbff6bf41542 | 97 | |
okini3939 | 0:cbff6bf41542 | 98 | switch (mode_tx) { |
okini3939 | 0:cbff6bf41542 | 99 | case DMX_MODE_BEGIN: |
okini3939 | 0:cbff6bf41542 | 100 | // Break Time |
okini3939 | 0:cbff6bf41542 | 101 | timeout01.detach(); |
okini3939 | 8:d4a45bba41d2 | 102 | _uart->LCR |= (1 << 6); |
okini3939 | 0:cbff6bf41542 | 103 | mode_tx = DMX_MODE_BREAK; |
okini3939 | 0:cbff6bf41542 | 104 | timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BREAK); |
okini3939 | 0:cbff6bf41542 | 105 | break; |
okini3939 | 0:cbff6bf41542 | 106 | |
okini3939 | 0:cbff6bf41542 | 107 | case DMX_MODE_BREAK: |
okini3939 | 0:cbff6bf41542 | 108 | // Mark After Break |
okini3939 | 0:cbff6bf41542 | 109 | timeout01.detach(); |
okini3939 | 8:d4a45bba41d2 | 110 | _uart->LCR &= ~(1 << 6); |
okini3939 | 0:cbff6bf41542 | 111 | mode_tx = DMX_MODE_MAB; |
okini3939 | 0:cbff6bf41542 | 112 | timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_MAB); |
okini3939 | 0:cbff6bf41542 | 113 | break; |
okini3939 | 0:cbff6bf41542 | 114 | |
okini3939 | 0:cbff6bf41542 | 115 | case DMX_MODE_MAB: |
okini3939 | 0:cbff6bf41542 | 116 | // Start code |
okini3939 | 0:cbff6bf41542 | 117 | timeout01.detach(); |
okini3939 | 0:cbff6bf41542 | 118 | addr_tx = 0; |
okini3939 | 0:cbff6bf41542 | 119 | mode_tx = DMX_MODE_DATA; |
okini3939 | 5:72039cd4c874 | 120 | _dmx.attach(this, &DMX::int_tx, Serial::TxIrq); |
okini3939 | 2:d7677060f8eb | 121 | #ifdef DMX_UART_DIRECT |
okini3939 | 9:e687f321c428 | 122 | while(!(_uart->LSR & (1<<5))); |
okini3939 | 9:e687f321c428 | 123 | _uart->THR = DMX_START_CODE; |
okini3939 | 2:d7677060f8eb | 124 | #else |
okini3939 | 9:e687f321c428 | 125 | _dmx.putc(DMX_START_CODE); |
okini3939 | 2:d7677060f8eb | 126 | #endif |
okini3939 | 0:cbff6bf41542 | 127 | break; |
okini3939 | 0:cbff6bf41542 | 128 | } |
okini3939 | 0:cbff6bf41542 | 129 | } |
okini3939 | 0:cbff6bf41542 | 130 | |
okini3939 | 0:cbff6bf41542 | 131 | void DMX::int_tx () { |
okini3939 | 0:cbff6bf41542 | 132 | // Data |
okini3939 | 0:cbff6bf41542 | 133 | if (mode_tx == DMX_MODE_DATA) { |
okini3939 | 0:cbff6bf41542 | 134 | if (addr_tx < DMX_SIZE) { |
okini3939 | 1:f0d988e15810 | 135 | #ifdef DMX_UART_DIRECT |
okini3939 | 8:d4a45bba41d2 | 136 | _uart->THR = (uint8_t)data_tx[addr_tx]; |
okini3939 | 0:cbff6bf41542 | 137 | #else |
okini3939 | 5:72039cd4c874 | 138 | _dmx.putc(data_tx[addr_tx]); |
okini3939 | 0:cbff6bf41542 | 139 | #endif |
okini3939 | 0:cbff6bf41542 | 140 | addr_tx ++; |
okini3939 | 0:cbff6bf41542 | 141 | } else { |
okini3939 | 5:72039cd4c874 | 142 | _dmx.attach(0, Serial::TxIrq); |
okini3939 | 0:cbff6bf41542 | 143 | mode_tx = DMX_MODE_BEGIN; |
okini3939 | 0:cbff6bf41542 | 144 | is_sent = 1; |
okini3939 | 0:cbff6bf41542 | 145 | timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN); |
okini3939 | 0:cbff6bf41542 | 146 | } |
okini3939 | 0:cbff6bf41542 | 147 | } |
okini3939 | 0:cbff6bf41542 | 148 | } |
okini3939 | 0:cbff6bf41542 | 149 | |
okini3939 | 0:cbff6bf41542 | 150 | void DMX::int_rx () { |
okini3939 | 0:cbff6bf41542 | 151 | int flg, dat; |
okini3939 | 0:cbff6bf41542 | 152 | |
okini3939 | 8:d4a45bba41d2 | 153 | flg = _uart->LSR; |
okini3939 | 1:f0d988e15810 | 154 | #ifdef DMX_UART_DIRECT |
okini3939 | 8:d4a45bba41d2 | 155 | dat = _uart->RBR; |
okini3939 | 1:f0d988e15810 | 156 | #else |
okini3939 | 5:72039cd4c874 | 157 | dat = _dmx.getc(); |
okini3939 | 1:f0d988e15810 | 158 | #endif |
okini3939 | 0:cbff6bf41542 | 159 | |
okini3939 | 0:cbff6bf41542 | 160 | if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) { |
okini3939 | 0:cbff6bf41542 | 161 | // Break Time |
okini3939 | 8:d4a45bba41d2 | 162 | if (addr_rx >= 24) { |
okini3939 | 0:cbff6bf41542 | 163 | is_recived = 1; |
okini3939 | 0:cbff6bf41542 | 164 | } |
okini3939 | 0:cbff6bf41542 | 165 | mode_rx = DMX_MODE_BREAK; |
okini3939 | 0:cbff6bf41542 | 166 | return; |
okini3939 | 0:cbff6bf41542 | 167 | } |
okini3939 | 0:cbff6bf41542 | 168 | |
okini3939 | 0:cbff6bf41542 | 169 | if (mode_rx == DMX_MODE_BREAK) { |
okini3939 | 0:cbff6bf41542 | 170 | |
okini3939 | 0:cbff6bf41542 | 171 | // Start Code |
okini3939 | 9:e687f321c428 | 172 | if (dat == DMX_START_CODE) { |
okini3939 | 0:cbff6bf41542 | 173 | addr_rx = 0; |
okini3939 | 0:cbff6bf41542 | 174 | mode_rx = DMX_MODE_DATA; |
okini3939 | 0:cbff6bf41542 | 175 | } else { |
okini3939 | 0:cbff6bf41542 | 176 | mode_rx = DMX_MODE_ERROR; |
okini3939 | 0:cbff6bf41542 | 177 | } |
okini3939 | 0:cbff6bf41542 | 178 | |
okini3939 | 0:cbff6bf41542 | 179 | } else |
okini3939 | 0:cbff6bf41542 | 180 | if (mode_rx == DMX_MODE_DATA) { |
okini3939 | 0:cbff6bf41542 | 181 | |
okini3939 | 0:cbff6bf41542 | 182 | // Data |
okini3939 | 0:cbff6bf41542 | 183 | data_rx[addr_rx] = dat; |
okini3939 | 0:cbff6bf41542 | 184 | addr_rx ++; |
okini3939 | 0:cbff6bf41542 | 185 | |
okini3939 | 0:cbff6bf41542 | 186 | if (addr_rx >= DMX_SIZE) { |
okini3939 | 0:cbff6bf41542 | 187 | is_recived = 1; |
okini3939 | 0:cbff6bf41542 | 188 | mode_rx = DMX_MODE_BEGIN; |
okini3939 | 0:cbff6bf41542 | 189 | } |
okini3939 | 0:cbff6bf41542 | 190 | } |
okini3939 | 0:cbff6bf41542 | 191 | } |
okini3939 | 0:cbff6bf41542 | 192 | |
okini3939 | 4:dd0544c80096 | 193 | void DMX::start () { |
okini3939 | 4:dd0544c80096 | 194 | if (mode_tx == DMX_MODE_STOP) { |
okini3939 | 4:dd0544c80096 | 195 | mode_tx = DMX_MODE_BEGIN; |
okini3939 | 4:dd0544c80096 | 196 | is_sent = 0; |
okini3939 | 4:dd0544c80096 | 197 | timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN); |
okini3939 | 4:dd0544c80096 | 198 | } |
okini3939 | 4:dd0544c80096 | 199 | } |
okini3939 | 4:dd0544c80096 | 200 | |
okini3939 | 4:dd0544c80096 | 201 | void DMX::stop () { |
okini3939 | 5:72039cd4c874 | 202 | _dmx.attach(0, Serial::TxIrq); |
okini3939 | 3:2eb66b4d99bd | 203 | timeout01.detach(); |
okini3939 | 4:dd0544c80096 | 204 | mode_tx = DMX_MODE_STOP; |
okini3939 | 3:2eb66b4d99bd | 205 | } |
okini3939 | 12:1f176eee2d28 | 206 | |
okini3939 | 12:1f176eee2d28 | 207 | void DMX::clear () { |
okini3939 | 12:1f176eee2d28 | 208 | int i; |
okini3939 | 12:1f176eee2d28 | 209 | |
okini3939 | 12:1f176eee2d28 | 210 | for (i = 0; i < DMX_SIZE; i ++) { |
okini3939 | 12:1f176eee2d28 | 211 | data_tx[i] = 0; |
okini3939 | 12:1f176eee2d28 | 212 | data_rx[i] = 0; |
okini3939 | 12:1f176eee2d28 | 213 | } |
okini3939 | 12:1f176eee2d28 | 214 | } |