|
5 | 5 | #include <util/delay.h>
|
6 | 6 |
|
7 | 7 |
|
8 |
| - |
9 |
| - |
10 | 8 | uint8_t dmxBuffer[DMX_NUM_UNIVERSES][DMX_UNIVERSE_SIZE];
|
11 | 9 |
|
12 | 10 | uint8_t* getUniverseBuffer(uint8_t universe) {
|
13 | 11 | return dmxBuffer[universe];
|
14 | 12 | }
|
15 | 13 |
|
16 | 14 |
|
17 |
| - |
18 | 15 | enum DMX_STATE {
|
19 | 16 | DMX_IDLE,
|
20 | 17 | DMX_BREAK,
|
21 | 18 | DMX_START,
|
22 | 19 | DMX_RUN
|
23 | 20 | };
|
24 | 21 |
|
| 22 | +typedef struct DMX_PORT { |
| 23 | + PORT_t* PORT; |
| 24 | + uint8_t PIN; |
| 25 | + register8_t* PIN_CTRL; |
| 26 | + USART_t* USART; |
| 27 | + uint8_t UNIVERSE; |
| 28 | + uint8_t OUTPUT_PORT; |
| 29 | + enum DMX_STATE TX_STATE; |
| 30 | + uint16_t TX_POSITION; |
25 | 31 |
|
26 |
| -enum DMX_STATE dmx0state = DMX_IDLE; |
27 |
| -enum DMX_STATE dmx1state = DMX_IDLE; |
28 |
| -enum DMX_STATE dmx2state = DMX_IDLE; |
29 |
| -enum DMX_STATE dmx3state = DMX_IDLE; |
30 |
| -uint16_t dmx0ch = 0; |
31 |
| -uint16_t dmx1ch = 0; |
32 |
| -uint16_t dmx2ch = 0; |
33 |
| -uint16_t dmx3ch = 0; |
| 32 | +} DMX_t; |
| 33 | + |
| 34 | + |
| 35 | +volatile DMX_t dmxPorts[DMX_NUM_UNIVERSES]; |
34 | 36 |
|
35 | 37 |
|
36 | 38 | #define DMX_BAUD_BSCALE 0 // vorher 0b1001 -> -1
|
37 | 39 | #define DMX_BAUD_RESET_BSEL 15 // 125k BAUD @32Mhz, used for RESET
|
38 | 40 | #define DMX_BAUD_NORMAL_BSEL 7 // 250k BAUD @32Mhz
|
39 | 41 |
|
40 |
| -#define UART0 USARTD0 |
| 42 | +void setupDMXPort(DMX_t* PORT) { |
| 43 | + PORT->PORT->DIRSET = 1 << PORT->PIN; // Pin 3 -> UART 0 TX |
| 44 | + *PORT->PIN_CTRL = PORT_INVEN_bm; |
41 | 45 |
|
42 |
| -void setupDMXPort(USART_t* uart) { |
43 |
| - uart->BAUDCTRLB = DMX_BAUD_BSCALE << 4; |
44 |
| - uart->BAUDCTRLA = DMX_BAUD_RESET_BSEL; |
| 46 | + PORT->USART->BAUDCTRLB = DMX_BAUD_BSCALE << 4; |
| 47 | + PORT->USART->BAUDCTRLA = DMX_BAUD_RESET_BSEL; |
45 | 48 |
|
46 |
| - uart->CTRLA = USART_TXCINTLVL_gm; // TX Highest INT Level |
47 |
| - uart->CTRLC = USART_SBMODE_bm | USART_CHSIZE_8BIT_gc; //2 StopBits, 8 DataBits |
| 49 | + PORT->USART->CTRLA = USART_TXCINTLVL_gm; // TX Highest INT Level |
| 50 | + PORT->USART->CTRLC = USART_SBMODE_bm | USART_CHSIZE_8BIT_gc; //2 StopBits, 8 DataBits |
48 | 51 |
|
49 |
| - uart->CTRLB = USART_TXEN_bm; //Enable TX |
| 52 | + PORT->USART->CTRLB = USART_TXEN_bm; //Enable TX |
50 | 53 | }
|
51 | 54 |
|
52 | 55 | void setupDMX(void) {
|
53 |
| - //DMX 1 |
54 |
| - PORTC.DIRSET = PIN3_bm; // Pin 3 -> UART 0 TX |
55 |
| - PORTC.PIN3CTRL = PORT_INVEN_bm; |
56 |
| - setupDMXPort(&USARTC0); |
57 |
| - |
58 |
| - //DMX 2 |
59 |
| - PORTC.DIRSET = PIN7_bm; // Pin 3 -> UART 0 TX |
60 |
| - PORTC.PIN7CTRL = PORT_INVEN_bm; |
61 |
| - setupDMXPort(&USARTC1); |
62 |
| - |
63 |
| - |
64 |
| - //DMX 3 |
65 |
| - PORTD.DIRSET = PIN3_bm; // Pin 3 -> UART 0 TX |
66 |
| - PORTD.PIN3CTRL = PORT_INVEN_bm; |
67 |
| - setupDMXPort(&USARTD0); |
68 |
| - |
69 |
| - //DMX 4 |
70 |
| - PORTE.DIRSET = PIN3_bm; // Pin 3 -> UART 0 TX |
71 |
| - PORTE.PIN3CTRL = PORT_INVEN_bm; |
72 |
| - setupDMXPort(&USARTE0); |
| 56 | + dmxPorts[0].PORT = &PORTC; |
| 57 | + dmxPorts[0].PIN = 3; |
| 58 | + dmxPorts[0].PIN_CTRL = &PORTC.PIN3CTRL; |
| 59 | + dmxPorts[0].USART = &USARTC0; |
| 60 | + dmxPorts[0].UNIVERSE = 0; |
| 61 | + dmxPorts[0].OUTPUT_PORT = 1; |
| 62 | + dmxPorts[0].TX_STATE = DMX_IDLE; |
| 63 | + |
| 64 | + dmxPorts[1].PORT = &PORTC; |
| 65 | + dmxPorts[1].PIN = 7; |
| 66 | + dmxPorts[1].PIN_CTRL = &PORTC.PIN7CTRL; |
| 67 | + dmxPorts[1].USART = &USARTC1; |
| 68 | + dmxPorts[1].UNIVERSE = 1; |
| 69 | + dmxPorts[1].OUTPUT_PORT = 2; |
| 70 | + dmxPorts[1].TX_STATE = DMX_IDLE; |
| 71 | + |
| 72 | + dmxPorts[2].PORT = &PORTD; |
| 73 | + dmxPorts[2].PIN = 3; |
| 74 | + dmxPorts[2].PIN_CTRL = &PORTD.PIN3CTRL; |
| 75 | + dmxPorts[2].USART = &USARTD0; |
| 76 | + dmxPorts[2].UNIVERSE = 2; |
| 77 | + dmxPorts[2].OUTPUT_PORT = 3; |
| 78 | + dmxPorts[2].TX_STATE = DMX_IDLE; |
| 79 | + |
| 80 | + dmxPorts[3].PORT = &PORTE; |
| 81 | + dmxPorts[3].PIN = 3; |
| 82 | + dmxPorts[3].PIN_CTRL = &PORTE.PIN3CTRL; |
| 83 | + dmxPorts[3].USART = &USARTE0; |
| 84 | + dmxPorts[3].UNIVERSE = 3; |
| 85 | + dmxPorts[3].OUTPUT_PORT = 4; |
| 86 | + dmxPorts[3].TX_STATE = DMX_IDLE; |
| 87 | + |
| 88 | + |
| 89 | + for(uint8_t i=0; i < DMX_NUM_UNIVERSES; i++) { |
| 90 | + setupDMXPort(&dmxPorts[i]); |
| 91 | + } |
73 | 92 | }
|
74 | 93 |
|
75 | 94 |
|
76 |
| -void startDMX_TX(void) { |
77 |
| - if(dmx0state == DMX_IDLE) { |
78 |
| - //Set Baud |
79 |
| - UART0.BAUDCTRLA = DMX_BAUD_RESET_BSEL; |
80 |
| - UART0.BAUDCTRLB = DMX_BAUD_BSCALE << 4; |
| 95 | +void startDMX_TX(void) { |
| 96 | + for(uint8_t i=0; i < DMX_NUM_UNIVERSES; i++) { |
| 97 | + if(dmxPorts[i].TX_STATE == DMX_IDLE) { |
| 98 | + //Set Baud |
| 99 | + dmxPorts[i].USART->BAUDCTRLA = DMX_BAUD_RESET_BSEL; |
| 100 | + dmxPorts[i].USART->BAUDCTRLB = DMX_BAUD_BSCALE << 4; |
81 | 101 |
|
82 |
| - //Send Break Byte |
83 |
| - UART0.DATA = 0x00; |
| 102 | + //Send Break Byte |
| 103 | + dmxPorts[i].USART->DATA = 0x00; |
84 | 104 |
|
85 |
| - dmx0state = DMX_START; |
| 105 | + dmxPorts[i].TX_STATE = DMX_START; |
| 106 | + } |
86 | 107 | }
|
87 | 108 | }
|
88 | 109 |
|
89 |
| -ISR(USARTD0_TXC_vect) //Transimission complete |
90 |
| -{ |
91 |
| - |
92 |
| - switch(dmx0state) { |
| 110 | +/** |
| 111 | + * Handle DMX Tx Interrupt |
| 112 | + */ |
| 113 | +void txISR(DMX_t* PORT) { |
| 114 | + switch(PORT->TX_STATE) { |
93 | 115 | case DMX_START:
|
94 | 116 | //Change Baudrate
|
95 |
| - UART0.BAUDCTRLA = DMX_BAUD_NORMAL_BSEL; |
96 |
| - UART0.BAUDCTRLB = DMX_BAUD_BSCALE << 4; |
| 117 | + PORT->USART->BAUDCTRLA = DMX_BAUD_NORMAL_BSEL; |
| 118 | + PORT->USART->BAUDCTRLB = DMX_BAUD_BSCALE << 4; |
97 | 119 |
|
98 | 120 | //SEND START Byte
|
99 |
| - UART0.DATA = 0x00; |
100 |
| - |
101 |
| - |
102 |
| - dmx0ch = 0; |
103 |
| - dmx0state = DMX_RUN; |
| 121 | + PORT->USART->DATA = 0x00; |
104 | 122 |
|
| 123 | + PORT->TX_POSITION = 0; |
| 124 | + PORT->TX_STATE = DMX_RUN; |
105 | 125 | break;
|
106 | 126 | case DMX_RUN:
|
107 |
| - UART0.DATA = dmxBuffer[0][dmx0ch++]; |
| 127 | + PORT->USART->DATA = dmxBuffer[PORT->UNIVERSE][PORT->TX_POSITION++]; |
108 | 128 |
|
109 |
| - if(dmx0ch >= 512) { |
110 |
| - dmx0state = DMX_IDLE; |
| 129 | + if(PORT->TX_POSITION >= 512) { |
| 130 | + PORT->TX_STATE = DMX_IDLE; |
111 | 131 | }
|
112 | 132 | break;
|
113 | 133 |
|
114 | 134 | }
|
115 | 135 | }
|
| 136 | + |
| 137 | +ISR(USARTC0_TXC_vect) //Transimission complete |
| 138 | +{ |
| 139 | + txISR(&dmxPorts[0]); |
| 140 | +} |
| 141 | + |
| 142 | +ISR(USARTC1_TXC_vect) //Transimission complete |
| 143 | +{ |
| 144 | + txISR(&dmxPorts[1]); |
| 145 | +} |
| 146 | + |
| 147 | +ISR(USARTD0_TXC_vect) //Transimission complete |
| 148 | +{ |
| 149 | + txISR(&dmxPorts[2]); |
| 150 | +} |
| 151 | + |
| 152 | +ISR(USARTE0_TXC_vect) //Transimission complete |
| 153 | +{ |
| 154 | + txISR(&dmxPorts[3]); |
| 155 | +} |
0 commit comments