An initial port to the FRDM-K46Z based on the the following: https://developer.mbed.org/users/okini3939/notebook/dmx512/
Fork of DMX by
DMX.cpp
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 }
Generated on Sun Jul 24 2022 00:08:43 by 1.7.2