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

Need to update the UART references to the K46Z. The KE02 Sub-Family Reference Manual provides us with the required information.

The modifications are wrapped with the target for the K46: For example, defined(TARGET_KL46Z)

Committer:
rosienej
Date:
Fri Mar 27 17:51:07 2015 +0000
Revision:
21:59c200304b47
Parent:
20:b1942f266f49
rx_int update

Who changed what in which revision?

UserRevisionLine numberNew 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
rosienej 20:b1942f266f49 14 DMX::DMX (PinName p_tx, PinName p_rx) : _dmx(p_tx, p_rx)
rosienej 20:b1942f266f49 15 {
okini3939 0:cbff6bf41542 16
okini3939 12:1f176eee2d28 17 clear();
okini3939 4:dd0544c80096 18 // mode_tx = DMX_MODE_BEGIN;
okini3939 4:dd0544c80096 19 mode_tx = DMX_MODE_STOP;
okini3939 0:cbff6bf41542 20 mode_rx = DMX_MODE_BEGIN;
okini3939 0:cbff6bf41542 21 is_recived = 0;
okini3939 0:cbff6bf41542 22 is_sent = 0;
okini3939 0:cbff6bf41542 23
okini3939 5:72039cd4c874 24 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 11:cb132e066057 25 if (p_rx == P0_3) {
rosienej 20:b1942f266f49 26 _uart = (LPC_UART_TypeDef*)LPC_UART0;
rosienej 20:b1942f266f49 27 NVIC_SetPriority(UART0_IRQn, 1);
rosienej 20:b1942f266f49 28 } else if (p_rx == p14) {
rosienej 20:b1942f266f49 29 _uart = (LPC_UART_TypeDef*)LPC_UART1;
rosienej 20:b1942f266f49 30 NVIC_SetPriority(UART1_IRQn, 1);
rosienej 20:b1942f266f49 31 } else if (p_rx == p27) {
rosienej 20:b1942f266f49 32 _uart = LPC_UART2;
rosienej 20:b1942f266f49 33 NVIC_SetPriority(UART2_IRQn, 1);
rosienej 20:b1942f266f49 34 } else if (p_rx == p10) {
rosienej 20:b1942f266f49 35 _uart = LPC_UART3;
rosienej 20:b1942f266f49 36 NVIC_SetPriority(UART3_IRQn, 1);
okini3939 0:cbff6bf41542 37 }
rosienej 16:84a017ef96f8 38 #elif defined(TARGET_KL46Z)
rosienej 20:b1942f266f49 39 /**
rosienej 20:b1942f266f49 40 Need to associate the _uart private variable with the user selected pin.
rosienej 20:b1942f266f49 41 Hook the interrupt pin.
rosienej 20:b1942f266f49 42 */
rosienej 20:b1942f266f49 43 if ((p_rx == PTE21) || (p_rx == PTA1)) {
rosienej 20:b1942f266f49 44 _uart = (UARTLP_Type *)UART0;
rosienej 20:b1942f266f49 45 NVIC_SetPriority(UART0_IRQn, 1);
rosienej 20:b1942f266f49 46 } else if (p_rx == PTE1) {
rosienej 20:b1942f266f49 47 _uart = (UARTLP_Type *)UART1;
rosienej 20:b1942f266f49 48 NVIC_SetPriority(UART1_IRQn, 1);
rosienej 20:b1942f266f49 49 } else if ((p_rx == PTE23) || (p_rx == PTE17)) {
rosienej 20:b1942f266f49 50 _uart = (UARTLP_Type *)UART2;
rosienej 20:b1942f266f49 51 NVIC_SetPriority(UART2_IRQn, 1);
rosienej 20:b1942f266f49 52 }
rosienej 20:b1942f266f49 53
okini3939 13:9841af9ac344 54 #elif defined(TARGET_LPC4088)
okini3939 13:9841af9ac344 55 if (p_rx == p10) {
rosienej 20:b1942f266f49 56 _uart = LPC_UART3;
rosienej 20:b1942f266f49 57 NVIC_SetPriority(UART3_IRQn, 1);
rosienej 20:b1942f266f49 58 } else if (p_rx == p31) {
rosienej 20:b1942f266f49 59 _uart = (LPC_UART_TypeDef*)LPC_UART4;
rosienej 20:b1942f266f49 60 NVIC_SetPriority(UART4_IRQn, 1);
okini3939 13:9841af9ac344 61 }
okini3939 15:4ea4a31c7609 62 #elif defined(TARGET_LPC11UXX)
okini3939 5:72039cd4c874 63 if (p_rx == p10) {
rosienej 20:b1942f266f49 64 _uart = LPC_USART;
rosienej 20:b1942f266f49 65 NVIC_SetPriority(UART_IRQn, 1);
okini3939 5:72039cd4c874 66 }
stanly88 10:b748aab8404c 67 #elif defined(TARGET_LPC11XX)
okini3939 11:cb132e066057 68 // LPC1114 support by Stanly Chen
stanly88 10:b748aab8404c 69 if (p_rx == P1_6) {
rosienej 20:b1942f266f49 70 _uart = (LPC_UART_TypeDef*)UART_0;
rosienej 20:b1942f266f49 71 NVIC_SetPriority(UART_IRQn, 1);
stanly88 10:b748aab8404c 72 }
okini3939 5:72039cd4c874 73 #endif
okini3939 0:cbff6bf41542 74
okini3939 5:72039cd4c874 75 _dmx.baud(250000);
okini3939 5:72039cd4c874 76 _dmx.format(8, Serial::None, 2);
okini3939 5:72039cd4c874 77 _dmx.attach(this, &DMX::int_rx, Serial::RxIrq);
okini3939 0:cbff6bf41542 78
okini3939 4:dd0544c80096 79 // timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN);
okini3939 0:cbff6bf41542 80 }
okini3939 0:cbff6bf41542 81
rosienej 20:b1942f266f49 82 void DMX::put (int addr, int data)
rosienej 20:b1942f266f49 83 {
okini3939 6:9e7b4eeac6ec 84 if (addr < 0 || addr >= DMX_SIZE) return;
okini3939 6:9e7b4eeac6ec 85 data_tx[addr] = data;
okini3939 0:cbff6bf41542 86 }
okini3939 0:cbff6bf41542 87
rosienej 20:b1942f266f49 88 void DMX::put (unsigned char *buf, int addr, int len)
rosienej 20:b1942f266f49 89 {
okini3939 6:9e7b4eeac6ec 90 if (addr < 0 || addr >= DMX_SIZE) return;
okini3939 6:9e7b4eeac6ec 91 if (len > DMX_SIZE - addr) len = DMX_SIZE - addr;
okini3939 6:9e7b4eeac6ec 92 memcpy(&data_tx[addr], buf, len);
okini3939 6:9e7b4eeac6ec 93 }
okini3939 6:9e7b4eeac6ec 94
rosienej 20:b1942f266f49 95 int DMX::get (int addr)
rosienej 20:b1942f266f49 96 {
okini3939 6:9e7b4eeac6ec 97 if (addr < 0 || addr >= DMX_SIZE) return -1;
okini3939 6:9e7b4eeac6ec 98 return data_rx[addr];
okini3939 6:9e7b4eeac6ec 99 }
okini3939 6:9e7b4eeac6ec 100
rosienej 20:b1942f266f49 101 void DMX::get (unsigned char *buf, int addr, int len)
rosienej 20:b1942f266f49 102 {
okini3939 6:9e7b4eeac6ec 103 if (addr < 0 || addr >= DMX_SIZE) return;
okini3939 6:9e7b4eeac6ec 104 if (len > DMX_SIZE - addr) len = DMX_SIZE - addr;
okini3939 6:9e7b4eeac6ec 105 memcpy(buf, &data_rx[addr], len);
okini3939 0:cbff6bf41542 106 }
okini3939 0:cbff6bf41542 107
rosienej 20:b1942f266f49 108 void DMX::int_timer ()
rosienej 20:b1942f266f49 109 {
okini3939 0:cbff6bf41542 110
okini3939 0:cbff6bf41542 111 switch (mode_tx) {
rosienej 20:b1942f266f49 112 case DMX_MODE_BEGIN:
rosienej 20:b1942f266f49 113 // Break Time
rosienej 20:b1942f266f49 114 timeout01.detach();
rosienej 20:b1942f266f49 115 #if defined(TARGET_KL46Z)
rosienej 20:b1942f266f49 116 /// Chapter 31.2 of the Freescale KE02 Sub-Famely Reference
rosienej 20:b1942f266f49 117 /// UARTx_C2 page 553 enable the transmitter and reciever
rosienej 20:b1942f266f49 118 /// Sending a break we write a one, then write a zero..... This sets send break bit
rosienej 16:84a017ef96f8 119 _uart->C2 |= UART_C2_SBK_MASK | UART_C2_TE_MASK | UART_C2_RE_MASK;
rosienej 20:b1942f266f49 120 #else
rosienej 20:b1942f266f49 121 /// Bit 6 in the LCR enables the break signal.....
rosienej 16:84a017ef96f8 122 _uart->LCR |= (1 << 6);
rosienej 20:b1942f266f49 123 #endif
rosienej 20:b1942f266f49 124 mode_tx = DMX_MODE_BREAK;
rosienej 20:b1942f266f49 125 timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BREAK);
rosienej 20:b1942f266f49 126 break;
okini3939 0:cbff6bf41542 127
rosienej 20:b1942f266f49 128 case DMX_MODE_BREAK:
rosienej 20:b1942f266f49 129 // Mark After Break
rosienej 20:b1942f266f49 130 timeout01.detach();
rosienej 20:b1942f266f49 131 #if defined(TARGET_KL46Z)
rosienej 20:b1942f266f49 132 /// This sets the break charcter to zero to send the break.
rosienej 20:b1942f266f49 133 _uart->C2 &= ~UART_C2_SBK_MASK;
rosienej 20:b1942f266f49 134 #else
rosienej 20:b1942f266f49 135 _uart->LCR &= ~(1 << 6);
rosienej 20:b1942f266f49 136 #endif
rosienej 20:b1942f266f49 137 mode_tx = DMX_MODE_MAB;
rosienej 20:b1942f266f49 138 timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_MAB);
rosienej 20:b1942f266f49 139 break;
okini3939 0:cbff6bf41542 140
rosienej 20:b1942f266f49 141 case DMX_MODE_MAB:
rosienej 20:b1942f266f49 142 // Start code
rosienej 20:b1942f266f49 143 timeout01.detach();
rosienej 20:b1942f266f49 144 addr_tx = 0;
rosienej 20:b1942f266f49 145 mode_tx = DMX_MODE_DATA;
rosienej 20:b1942f266f49 146 _dmx.attach(this, &DMX::int_tx, Serial::TxIrq);
okini3939 2:d7677060f8eb 147 #ifdef DMX_UART_DIRECT
rosienej 20:b1942f266f49 148
rosienej 20:b1942f266f49 149
rosienej 20:b1942f266f49 150 #if defined(TARGET_KL46Z)
rosienej 20:b1942f266f49 151 /// Check the TDRE (Transmit Data Register Empty) flag... page 555
rosienej 20:b1942f266f49 152 /// The data is placed in D on the Freescale
rosienej 20:b1942f266f49 153 while(!(_uart->S1 & UART_S1_TDRE_MASK));
rosienej 20:b1942f266f49 154 _uart->D = DMX_START_CODE; // Freescale
okini3939 2:d7677060f8eb 155 #else
rosienej 20:b1942f266f49 156 /// Bit 5 of the LSR indicates the THR (Transmit Holding Register) is empty
rosienej 20:b1942f266f49 157 while(!(_uart->LSR & (1<<5)));
rosienej 20:b1942f266f49 158 _uart->THR = DMX_START_CODE;
okini3939 2:d7677060f8eb 159 #endif
rosienej 20:b1942f266f49 160 #else
rosienej 20:b1942f266f49 161 _dmx.putc(DMX_START_CODE);
rosienej 20:b1942f266f49 162 #endif
rosienej 20:b1942f266f49 163 break;
okini3939 0:cbff6bf41542 164 }
okini3939 0:cbff6bf41542 165 }
okini3939 0:cbff6bf41542 166
rosienej 20:b1942f266f49 167 void DMX::int_tx ()
rosienej 20:b1942f266f49 168 {
okini3939 0:cbff6bf41542 169 // Data
okini3939 0:cbff6bf41542 170 if (mode_tx == DMX_MODE_DATA) {
okini3939 0:cbff6bf41542 171 if (addr_tx < DMX_SIZE) {
okini3939 1:f0d988e15810 172 #ifdef DMX_UART_DIRECT
rosienej 20:b1942f266f49 173
rosienej 20:b1942f266f49 174 #if defined(TARGET_KL46Z)
rosienej 16:84a017ef96f8 175 _uart->D = (uint8_t)data_tx[addr_tx]; // Freescale
rosienej 20:b1942f266f49 176 #else
okini3939 8:d4a45bba41d2 177 _uart->THR = (uint8_t)data_tx[addr_tx];
rosienej 20:b1942f266f49 178 #endif
okini3939 0:cbff6bf41542 179 #else
okini3939 5:72039cd4c874 180 _dmx.putc(data_tx[addr_tx]);
okini3939 0:cbff6bf41542 181 #endif
okini3939 0:cbff6bf41542 182 addr_tx ++;
okini3939 0:cbff6bf41542 183 } else {
okini3939 5:72039cd4c874 184 _dmx.attach(0, Serial::TxIrq);
okini3939 0:cbff6bf41542 185 mode_tx = DMX_MODE_BEGIN;
okini3939 0:cbff6bf41542 186 is_sent = 1;
okini3939 0:cbff6bf41542 187 timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN);
okini3939 0:cbff6bf41542 188 }
okini3939 0:cbff6bf41542 189 }
okini3939 0:cbff6bf41542 190 }
okini3939 0:cbff6bf41542 191
rosienej 20:b1942f266f49 192 void DMX::int_rx ()
rosienej 20:b1942f266f49 193 {
okini3939 0:cbff6bf41542 194 int flg, dat;
rosienej 16:84a017ef96f8 195 int tmp1,tmp2;
rosienej 20:b1942f266f49 196 #if defined(TARGET_KL46Z)
rosienej 18:6303931e4102 197 /// looking for (7)erroneous data,(3) Framming Error, (4) Break
rosienej 16:84a017ef96f8 198 tmp1 = (_uart->S1 & (UART_S1_NF_MASK|UART_S1_FE_MASK)); // NF,FE
rosienej 16:84a017ef96f8 199 tmp2 = (_uart->S2 & UART_S2_LBKDIF_MASK); //LBKDIF
rosienej 21:59c200304b47 200 flg = (tmp1<<2) | tmp2;
rosienej 20:b1942f266f49 201 #else
rosienej 20:b1942f266f49 202 flg = _uart->LSR;
rosienej 20:b1942f266f49 203 #endif
rosienej 20:b1942f266f49 204
okini3939 1:f0d988e15810 205 #ifdef DMX_UART_DIRECT
rosienej 20:b1942f266f49 206 #if defined(TARGET_KL46Z)
rosienej 16:84a017ef96f8 207 dat = _uart->D; // Freescale
rosienej 20:b1942f266f49 208 #else
okini3939 8:d4a45bba41d2 209 dat = _uart->RBR;
rosienej 20:b1942f266f49 210 #endif
rosienej 20:b1942f266f49 211
rosienej 20:b1942f266f49 212
okini3939 1:f0d988e15810 213 #else
okini3939 5:72039cd4c874 214 dat = _dmx.getc();
okini3939 1:f0d988e15810 215 #endif
okini3939 0:cbff6bf41542 216
okini3939 0:cbff6bf41542 217 if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) {
okini3939 0:cbff6bf41542 218 // Break Time
okini3939 15:4ea4a31c7609 219 if (addr_rx >= 24 && mode_rx == DMX_MODE_DATA) {
okini3939 0:cbff6bf41542 220 is_recived = 1;
okini3939 0:cbff6bf41542 221 }
okini3939 0:cbff6bf41542 222 mode_rx = DMX_MODE_BREAK;
okini3939 0:cbff6bf41542 223 return;
okini3939 0:cbff6bf41542 224 }
okini3939 0:cbff6bf41542 225
okini3939 0:cbff6bf41542 226 if (mode_rx == DMX_MODE_BREAK) {
okini3939 0:cbff6bf41542 227
okini3939 0:cbff6bf41542 228 // Start Code
okini3939 9:e687f321c428 229 if (dat == DMX_START_CODE) {
okini3939 0:cbff6bf41542 230 addr_rx = 0;
okini3939 0:cbff6bf41542 231 mode_rx = DMX_MODE_DATA;
okini3939 0:cbff6bf41542 232 } else {
okini3939 0:cbff6bf41542 233 mode_rx = DMX_MODE_ERROR;
okini3939 0:cbff6bf41542 234 }
okini3939 0:cbff6bf41542 235
rosienej 20:b1942f266f49 236 } else if (mode_rx == DMX_MODE_DATA) {
okini3939 0:cbff6bf41542 237
okini3939 0:cbff6bf41542 238 // Data
okini3939 0:cbff6bf41542 239 data_rx[addr_rx] = dat;
okini3939 0:cbff6bf41542 240 addr_rx ++;
okini3939 0:cbff6bf41542 241
okini3939 0:cbff6bf41542 242 if (addr_rx >= DMX_SIZE) {
okini3939 0:cbff6bf41542 243 is_recived = 1;
okini3939 0:cbff6bf41542 244 mode_rx = DMX_MODE_BEGIN;
okini3939 0:cbff6bf41542 245 }
okini3939 0:cbff6bf41542 246 }
okini3939 0:cbff6bf41542 247 }
okini3939 0:cbff6bf41542 248
rosienej 20:b1942f266f49 249 void DMX::start ()
rosienej 20:b1942f266f49 250 {
okini3939 4:dd0544c80096 251 if (mode_tx == DMX_MODE_STOP) {
okini3939 4:dd0544c80096 252 mode_tx = DMX_MODE_BEGIN;
okini3939 4:dd0544c80096 253 is_sent = 0;
okini3939 4:dd0544c80096 254 timeout01.attach_us(this, &DMX::int_timer, DMX_TIME_BETWEEN);
okini3939 4:dd0544c80096 255 }
okini3939 4:dd0544c80096 256 }
okini3939 4:dd0544c80096 257
rosienej 20:b1942f266f49 258 void DMX::stop ()
rosienej 20:b1942f266f49 259 {
okini3939 5:72039cd4c874 260 _dmx.attach(0, Serial::TxIrq);
okini3939 3:2eb66b4d99bd 261 timeout01.detach();
okini3939 4:dd0544c80096 262 mode_tx = DMX_MODE_STOP;
okini3939 3:2eb66b4d99bd 263 }
okini3939 12:1f176eee2d28 264
rosienej 20:b1942f266f49 265 void DMX::clear ()
rosienej 20:b1942f266f49 266 {
okini3939 12:1f176eee2d28 267 int i;
okini3939 12:1f176eee2d28 268
okini3939 12:1f176eee2d28 269 for (i = 0; i < DMX_SIZE; i ++) {
okini3939 12:1f176eee2d28 270 data_tx[i] = 0;
okini3939 12:1f176eee2d28 271 data_rx[i] = 0;
okini3939 12:1f176eee2d28 272 }
okini3939 12:1f176eee2d28 273 }