An initial port to the FRDM-K46Z based on the the following: https://developer.mbed.org/users/okini3939/notebook/dmx512/

Dependents:   FRDM-Dowser

Fork of DMX by Suga koubou

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DMX.cpp Source File

DMX.cpp

Go to the documentation of this file.
00001 /*
00002  * DMX512 send/recv library
00003  * Copyright (c) 2013 Hiroshi Suga
00004  * Released under the MIT License: http://mbed.org/license/mit
00005  */
00006 
00007 /** @file
00008  * @brief DMX512 send/recv
00009  */
00010 
00011 #include "mbed.h"
00012 #include "DMX.h"
00013 
00014 DMX::DMX (PinName p_tx, PinName p_rx) : _dmx(p_tx, p_rx)
00015 {
00016 
00017     clear();
00018 //    mode_tx = DMX_MODE_BEGIN;
00019     mode_tx = DMX_MODE_STOP;
00020     mode_rx = DMX_MODE_BEGIN;
00021     is_recived = 0;
00022     is_sent = 0;
00023 
00024 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00025     if (p_rx == P0_3) {
00026         _uart = (LPC_UART_TypeDef*)LPC_UART0;
00027         NVIC_SetPriority(UART0_IRQn, 1);
00028     } else if (p_rx == p14) {
00029         _uart = (LPC_UART_TypeDef*)LPC_UART1;
00030         NVIC_SetPriority(UART1_IRQn, 1);
00031     } else if (p_rx == p27) {
00032         _uart = LPC_UART2;
00033         NVIC_SetPriority(UART2_IRQn, 1);
00034     } else if (p_rx == p10) {
00035         _uart = LPC_UART3;
00036         NVIC_SetPriority(UART3_IRQn, 1);
00037     }
00038 #elif defined(TARGET_KL46Z)
00039     /**
00040         Need to associate the _uart private variable with the user selected pin.
00041         Hook the interrupt pin.
00042     */
00043     if ((p_rx == PTE21) || (p_rx == PTA1)) {
00044         _uart = (UARTLP_Type *)UART0;
00045         NVIC_SetPriority(UART0_IRQn, 1);
00046     } else if (p_rx == PTE1) {
00047         _uart = (UARTLP_Type *)UART1;
00048         NVIC_SetPriority(UART1_IRQn, 1);
00049     } else if ((p_rx == PTE23) || (p_rx == PTE17)) {
00050         _uart = (UARTLP_Type *)UART2;
00051         NVIC_SetPriority(UART2_IRQn, 1);
00052     }
00053 
00054 #elif defined(TARGET_LPC4088)
00055     if (p_rx == p10) {
00056         _uart = LPC_UART3;
00057         NVIC_SetPriority(UART3_IRQn, 1);
00058     } else if (p_rx == p31) {
00059         _uart = (LPC_UART_TypeDef*)LPC_UART4;
00060         NVIC_SetPriority(UART4_IRQn, 1);
00061     }
00062 #elif defined(TARGET_LPC11UXX)
00063     if (p_rx == p10) {
00064         _uart = LPC_USART;
00065         NVIC_SetPriority(UART_IRQn, 1);
00066     }
00067 #elif defined(TARGET_LPC11XX)
00068     // LPC1114 support by Stanly Chen
00069     if (p_rx == P1_6) {
00070         _uart = (LPC_UART_TypeDef*)UART_0;
00071         NVIC_SetPriority(UART_IRQn, 1);
00072     }
00073 #endif
00074 
00075     _dmx.baud(250000);
00076     _dmx.format(8, Serial::None, 2);
00077     _dmx.attach(this, &DMX::int_rx , Serial::RxIrq);
00078 
00079 //    timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN);
00080 }
00081 
00082 void DMX::put (int addr, int data)
00083 {
00084     if (addr < 0 || addr >= DMX_SIZE) return;
00085     data_tx[addr] = data;
00086 }
00087 
00088 void DMX::put (unsigned char *buf, int addr, int len)
00089 {
00090     if (addr < 0 || addr >= DMX_SIZE) return;
00091     if (len > DMX_SIZE - addr) len = DMX_SIZE - addr;
00092     memcpy(&data_tx[addr], buf, len);
00093 }
00094 
00095 int DMX::get (int addr)
00096 {
00097     if (addr < 0 || addr >= DMX_SIZE) return -1;
00098     return data_rx[addr];
00099 }
00100 
00101 void DMX::get (unsigned char *buf, int addr, int len)
00102 {
00103     if (addr < 0 || addr >= DMX_SIZE) return;
00104     if (len > DMX_SIZE - addr) len = DMX_SIZE - addr;
00105     memcpy(buf, &data_rx[addr], len);
00106 }
00107 
00108 void DMX::int_timer  ()
00109 {
00110 
00111     switch (mode_tx) {
00112         case DMX_MODE_BEGIN:
00113             // Break Time
00114             timeout01.detach();
00115 #if defined(TARGET_KL46Z)
00116             /// Chapter 31.2  of the Freescale KE02 Sub-Famely Reference
00117             /// UARTx_C2 page 553 enable the transmitter and reciever
00118             ///  Sending a break we write a one, then write a zero.....  This sets send break bit
00119             _uart->C2 |= UART_C2_SBK_MASK | UART_C2_TE_MASK | UART_C2_RE_MASK;
00120 #else
00121             /// Bit 6 in the LCR enables the break signal.....
00122             _uart->LCR |= (1 << 6);
00123 #endif
00124             mode_tx = DMX_MODE_BREAK;
00125             timeout01.attach_us(this, &DMX::int_timer , DMX_TIME_BREAK);
00126             break;
00127 
00128         case DMX_MODE_BREAK:
00129             // Mark After Break
00130             timeout01.detach();
00131 #if defined(TARGET_KL46Z)
00132             /// This sets the break charcter to zero to send the break.
00133             _uart->C2 &= ~UART_C2_SBK_MASK;
00134 #else
00135             _uart->LCR &= ~(1 << 6);
00136 #endif
00137             mode_tx = DMX_MODE_MAB;
00138             timeout01.attach_us(this, &DMX::int_timer , DMX_TIME_MAB);
00139             break;
00140 
00141         case DMX_MODE_MAB:
00142             // Start code
00143             timeout01.detach();
00144             addr_tx = 0;
00145             mode_tx = DMX_MODE_DATA;
00146             _dmx.attach(this, &DMX::int_tx, Serial::TxIrq);
00147 #ifdef DMX_UART_DIRECT
00148 
00149 
00150 #if defined(TARGET_KL46Z)
00151             /// Check the TDRE (Transmit Data Register Empty) flag... page 555
00152             /// The data is placed in D on the Freescale
00153             while(!(_uart->S1 & UART_S1_TDRE_MASK));
00154             _uart->D = DMX_START_CODE; // Freescale
00155 #else
00156             /// Bit 5 of the LSR indicates the THR (Transmit Holding Register) is empty
00157             while(!(_uart->LSR & (1<<5)));
00158             _uart->THR = DMX_START_CODE;
00159 #endif
00160 #else
00161             _dmx.putc(DMX_START_CODE);
00162 #endif
00163             break;
00164     }
00165 }
00166 
00167 void DMX::int_tx ()
00168 {
00169     // Data
00170     if (mode_tx == DMX_MODE_DATA) {
00171         if (addr_tx < DMX_SIZE) {
00172 #ifdef DMX_UART_DIRECT
00173 
00174 #if defined(TARGET_KL46Z)
00175             _uart->D = (uint8_t)data_tx[addr_tx]; // Freescale
00176 #else
00177             _uart->THR = (uint8_t)data_tx[addr_tx];
00178 #endif
00179 #else
00180             _dmx.putc(data_tx[addr_tx]);
00181 #endif
00182             addr_tx ++;
00183         } else {
00184             _dmx.attach(0, Serial::TxIrq);
00185             mode_tx = DMX_MODE_BEGIN;
00186             is_sent = 1;
00187             timeout01.attach_us(this, &DMX::int_timer , DMX_TIME_BETWEEN);
00188         }
00189     }
00190 }
00191 
00192 void DMX::int_rx  ()
00193 {
00194     int flg, dat;
00195     int tmp1,tmp2;
00196 #if defined(TARGET_KL46Z)
00197     /// looking for (7)erroneous data,(3) Framming Error, (4) Break
00198     tmp1 = (_uart->S1 & (UART_S1_NF_MASK|UART_S1_FE_MASK));         // NF,FE
00199     tmp2 = (_uart->S2 & UART_S2_LBKDIF_MASK);         //LBKDIF
00200     flg = (tmp1<<2) | tmp2;
00201 #else
00202     flg = _uart->LSR;
00203 #endif
00204 
00205 #ifdef DMX_UART_DIRECT
00206 #if defined(TARGET_KL46Z)
00207     dat = _uart->D;  // Freescale
00208 #else
00209     dat = _uart->RBR;
00210 #endif
00211 
00212 
00213 #else
00214     dat = _dmx.getc();
00215 #endif
00216 
00217     if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) {
00218         // Break Time
00219         if (addr_rx >= 24 && mode_rx == DMX_MODE_DATA) {
00220             is_recived = 1;
00221         }
00222         mode_rx = DMX_MODE_BREAK;
00223         return;
00224     }
00225 
00226     if (mode_rx == DMX_MODE_BREAK) {
00227 
00228         // Start Code
00229         if (dat == DMX_START_CODE) {
00230             addr_rx = 0;
00231             mode_rx = DMX_MODE_DATA;
00232         } else {
00233             mode_rx = DMX_MODE_ERROR;
00234         }
00235 
00236     } else if (mode_rx == DMX_MODE_DATA) {
00237 
00238         // Data
00239         data_rx[addr_rx] = dat;
00240         addr_rx ++;
00241 
00242         if (addr_rx >= DMX_SIZE) {
00243             is_recived = 1;
00244             mode_rx = DMX_MODE_BEGIN;
00245         }
00246     }
00247 }
00248 
00249 void DMX::start ()
00250 {
00251     if (mode_tx == DMX_MODE_STOP) {
00252         mode_tx = DMX_MODE_BEGIN;
00253         is_sent = 0;
00254         timeout01.attach_us(this, &DMX::int_timer , DMX_TIME_BETWEEN);
00255     }
00256 }
00257 
00258 void DMX::stop ()
00259 {
00260     _dmx.attach(0, Serial::TxIrq);
00261     timeout01.detach();
00262     mode_tx = DMX_MODE_STOP;
00263 }
00264 
00265 void DMX::clear ()
00266 {
00267     int i;
00268 
00269     for (i = 0; i < DMX_SIZE; i ++) {
00270         data_tx[i] = 0;
00271         data_rx[i] = 0;
00272     }
00273 }