1 | #define F_CPU 12000000
|
2 | #define DMX_BAUD 250000
|
3 | #define DMX_LOST_TIMEOUT 500
|
4 | #define DMX_BAUD_BREAK 80000
|
5 |
|
6 | #include <avr/io.h>
|
7 | #include <avr/interrupt.h>
|
8 | #include <avr/pgmspace.h>
|
9 | #include <avr/eeprom.h>
|
10 | #include <util/delay.h>
|
11 | #include <stdlib.h>
|
12 | #include <string.h>
|
13 | #include "rf22.h"
|
14 |
|
15 | volatile unsigned char dmx_buffer[514];
|
16 | volatile unsigned char dmx_tmp_buffer[33];
|
17 | volatile unsigned char new_dmx_data = 0;
|
18 |
|
19 | volatile unsigned int dmx_lost = DMX_LOST_TIMEOUT;
|
20 |
|
21 |
|
22 | #define TRANSMIT_BLOCKS 16 //1 Block 32Channels max.16 Blocks 512Channels
|
23 | #define TRANSMIT_REPEAT 64
|
24 |
|
25 | //############################################################################
|
26 | //DMX Senderoutine
|
27 | ISR (USART_TX_vect)
|
28 | //############################################################################
|
29 | {
|
30 | static unsigned int dmx_channel_tx_count = 1;
|
31 | static unsigned char dmx_tx_state = 0;
|
32 |
|
33 | switch (dmx_tx_state)
|
34 | {
|
35 | case (0):
|
36 | UBRR0 = (F_CPU / (DMX_BAUD_BREAK * 16L) - 1);
|
37 | UDR0 = 0; //RESET Frame
|
38 | dmx_tx_state = 1;
|
39 | break;
|
40 |
|
41 | case (1):
|
42 | UBRR0 = (F_CPU / (DMX_BAUD * 16L) - 1);
|
43 | UDR0 = 0; //Start Byte
|
44 | dmx_tx_state = 2;
|
45 | break;
|
46 |
|
47 | case (2):
|
48 | _delay_us(10);
|
49 | //Ausgabe des Zeichens
|
50 | UDR0 = dmx_buffer[dmx_channel_tx_count];
|
51 | dmx_channel_tx_count++;
|
52 |
|
53 | if(dmx_channel_tx_count == 512)
|
54 | {
|
55 | dmx_channel_tx_count = 1;
|
56 | dmx_tx_state = 0;
|
57 | }
|
58 | break;
|
59 | }
|
60 | }
|
61 |
|
62 |
|
63 | //############################################################################
|
64 | //DMX Empfangsroutine (RS485)
|
65 | ISR (USART_RX_vect)
|
66 | //############################################################################
|
67 | {
|
68 | static unsigned int dmx_channel_rx_count = 0;
|
69 | static unsigned char dmx_valid = 0;
|
70 | unsigned char tmp = 0;
|
71 |
|
72 | tmp = UDR0;
|
73 |
|
74 | if(UCSR0A&(1<<FE0))
|
75 | {
|
76 | if(dmx_channel_rx_count > 1)
|
77 | {
|
78 | dmx_lost = 0;
|
79 | }
|
80 | dmx_channel_rx_count = 0;
|
81 | dmx_buffer[0] = tmp;
|
82 |
|
83 | if(dmx_buffer[0] == 0)
|
84 | {
|
85 | dmx_valid = 1;
|
86 | dmx_channel_rx_count++;
|
87 | }
|
88 | else
|
89 | {
|
90 | dmx_valid = 0;
|
91 | }
|
92 | return;
|
93 | }
|
94 |
|
95 | if(dmx_valid)
|
96 | {
|
97 | if(dmx_buffer[dmx_channel_rx_count] != tmp)
|
98 | {
|
99 | dmx_buffer[dmx_channel_rx_count] = tmp;
|
100 | new_dmx_data = TRANSMIT_REPEAT;
|
101 | }
|
102 |
|
103 | if(dmx_channel_rx_count < 514)
|
104 | {
|
105 | dmx_channel_rx_count++;
|
106 | }
|
107 | return;
|
108 | }
|
109 | }
|
110 |
|
111 | //############################################################################
|
112 | //Hier wird die Zeit gez‰hlt (Tick 1ms)
|
113 | ISR (TIMER2_COMPA_vect)
|
114 | //############################################################################
|
115 | {
|
116 | if(dmx_lost<DMX_LOST_TIMEOUT)
|
117 | {
|
118 | dmx_lost++;
|
119 | }
|
120 | }
|
121 |
|
122 | //############################################################################
|
123 | //Hauptprogramm DMX FUNK ‹BERTRAGUNG
|
124 | int main(void)
|
125 | //############################################################################
|
126 | {
|
127 | unsigned int tmp;
|
128 | unsigned char packet_cnt = 0;
|
129 | unsigned long counter = 0;
|
130 | DDRB |= (1<<PB0); //LED PORT Output
|
131 | DDRD |= (1<<PD3); //Direction RS485 RX/TX
|
132 |
|
133 | PORTB |= (1<<0); //LED ON
|
134 |
|
135 | //#############################################################
|
136 | DDRC &= ~(1<<PC2); //M‰useklavier PINs als Eingang
|
137 | DDRC &= ~(1<<PC3);
|
138 | DDRC &= ~(1<<PC4);
|
139 | DDRC &= ~(1<<PC5);
|
140 |
|
141 | PORTC |= (1<<PC2); //M‰useklavier PULL UP einschalten
|
142 | PORTC |= (1<<PC3);
|
143 | PORTC |= (1<<PC4);
|
144 | PORTC |= (1<<PC5);
|
145 | //#############################################################
|
146 |
|
147 |
|
148 | PORTC |= (1<<PC0); //Pullup (Receiver/Transmitter)
|
149 | for(unsigned long b = 0;b<100000;b++){;asm("nop");};
|
150 |
|
151 | rf22_init();
|
152 |
|
153 | //___________________________________________
|
154 | // Hier könnte das Problem liegen!!
|
155 |
|
156 |
|
157 | if ( ( !(PINC & (1<<PC2)) ) && (PINC & (1<<PC3)) && (PINC & (1<<PC4)) && (PINC & (1<<PC5)) ) // PINC2 eingeschaltet, 3, 4, 5 = 1; nicht eingeschaltet
|
158 | {
|
159 | rf22_setfreq(RF22FREQ(430.0)); // Frequenz z.B. jetzt 430 MHz
|
160 | }
|
161 |
|
162 | if ( (PINC & (1<<PC2)) && ( !(PINC & (1<<PC3)) ) && (PINC & (1<<PC4)) && (PINC & (1<<PC5)) ) // PINC3 eingeschaltet, 2, 4, 5 = 1; nicht eingeschaltet
|
163 | {
|
164 | rf22_setfreq(RF22FREQ(440.0)); // Frequenz z.B. jetzt 440 MHz
|
165 | }
|
166 |
|
167 | //___________________________________________
|
168 |
|
169 |
|
170 |
|
171 | rf22_rxmode();
|
172 |
|
173 |
|
174 | if(PINC & (1<<PC0)) //Module als Sender oder Empf‰nger
|
175 | {
|
176 | PORTD &= ~(1<<PD3); //TX RS485
|
177 |
|
178 | //Init usart DMX-BUS
|
179 | UBRR0 = (F_CPU / (DMX_BAUD * 16L) - 1);
|
180 | UCSR0B|=(1 << RXEN0 | 1<< RXCIE0);
|
181 | UCSR0C|=(1<<USBS0); //USBS0 2 Stop bits
|
182 | sei();//Globale Interrupts Enable
|
183 |
|
184 | //Timer2 Timecounter f¸r DMX Ausfall Kabel
|
185 | TCCR2A |= (1<<WGM21);
|
186 | TCCR2B |= (1<<CS22|1<<CS21|1<<CS20);
|
187 | TIMSK2 |= (1<<OCIE2A);
|
188 | OCR2A = F_CPU/1024/1000 - 1; //Tick Time
|
189 |
|
190 | while(1)
|
191 | {
|
192 | if(new_dmx_data > 0)
|
193 | {
|
194 | new_dmx_data--;
|
195 | //512 Kan‰le werden zu je 32Bytes a 16 Packete versendet
|
196 | memcpy((unsigned char*)&dmx_tmp_buffer[1],(unsigned char *)&dmx_buffer[(packet_cnt*32)],32);
|
197 | dmx_tmp_buffer[0] = packet_cnt;
|
198 | packet_cnt++;
|
199 |
|
200 | if(packet_cnt == TRANSMIT_BLOCKS)
|
201 | {
|
202 | packet_cnt = 0;
|
203 | }
|
204 |
|
205 | rf22_sendpacket(dmx_tmp_buffer,33); //Packetcounter und 32DMX Bytes
|
206 | }
|
207 |
|
208 | //Abfrage ob DMX Packete via Kabel empfangen wurden
|
209 | if(dmx_lost==DMX_LOST_TIMEOUT)
|
210 | {
|
211 | PORTB &=~(1<<0); //LED AUS NO DMX
|
212 | }
|
213 | else
|
214 | {
|
215 | PORTB |= (1<<0); //LED AN DMX OK
|
216 | }
|
217 | }
|
218 | }
|
219 | else
|
220 | {
|
221 | PORTD |= (1<<PD3); //RX RS485
|
222 |
|
223 | //Timer2 Timecounter f¸r DMX Ausfall Funk
|
224 | TCCR2A |= (1<<WGM21);
|
225 | TCCR2B |= (1<<CS22|1<<CS21|1<<CS20);
|
226 | TIMSK2 |= (1<<OCIE2A);
|
227 | OCR2A = F_CPU/1024/1000 - 1; //Tick Time
|
228 |
|
229 | //Init usart DMX-BUS
|
230 | UBRR0 = (F_CPU / (DMX_BAUD * 16L) - 1);
|
231 | DDRD |= (1<<PD1); //Output TXD Pin ATmega88
|
232 | UCSR0B|=(1<<TXEN0)|(1<<TXCIE0); // TXEN0 Transmitter enable / TXCIE0 TX complete interrupt enable
|
233 | UCSR0C|=(1<<USBS0); //USBS0 2 Stop bits
|
234 | sei();//Globale Interrupts Enable
|
235 | UDR0 = 0;//Start DMX
|
236 |
|
237 | while(1)
|
238 | {
|
239 | //Warte bis Packet empfangen wurde
|
240 | while(PIND&(1<<2))
|
241 | {
|
242 | if(dmx_lost == DMX_LOST_TIMEOUT)
|
243 | {
|
244 | PORTB &= ~(1<<0); //Status LED aus
|
245 | counter++;
|
246 | if(counter >1000000)
|
247 | {
|
248 | PORTB |= (1<<0);
|
249 | for(unsigned a = 0;a<5000;a++){;asm("nop");};
|
250 | PORTB &= ~(1<<0);
|
251 | counter = 0;
|
252 | }
|
253 | }
|
254 | else
|
255 | {
|
256 | PORTB |= (1<<0); //Status LED an
|
257 | counter = 0;
|
258 | }
|
259 | }
|
260 |
|
261 | tmp = rf22_getpacket(dmx_tmp_buffer); //Packetcounter und 32DMX Bytes
|
262 |
|
263 | //wurden alle Bytes empfangen?
|
264 | if(tmp == 33)
|
265 | {
|
266 | dmx_lost= 0;
|
267 | //512 Kan‰le werden zu je 32Bytes a 16 Packete empfangen
|
268 | packet_cnt = dmx_tmp_buffer[0];
|
269 | memcpy((unsigned char*)&dmx_buffer[(packet_cnt*32)],(unsigned char *)&dmx_tmp_buffer[1],32);
|
270 | }
|
271 | }
|
272 | }
|
273 | }
|