14 } |
14 } |
15 |
15 |
16 #define PULSE_PORT PORTD |
16 #define PULSE_PORT PORTD |
17 #define PULSE_BIT PD2 |
17 #define PULSE_BIT PD2 |
18 |
18 |
19 #define RESPONSE_PORT PORTC |
19 typedef struct { |
20 #define RESPONSE_PIN PC1 |
20 uint8_t slot; |
|
21 uint8_t light; |
|
22 unsigned program:1; // programming mode active |
|
23 } config_t; |
|
24 |
21 |
25 |
22 volatile uint16_t data = 0; |
26 volatile uint16_t data = 0; |
23 volatile uint8_t data_len = 0; |
27 volatile uint8_t data_len = 0; |
24 volatile uint8_t bitbuf_len = 0; |
28 volatile uint8_t bitbuf_len = 0; |
25 volatile uint16_t bitbuf = 0; |
29 volatile uint16_t bitbuf = 0; |
26 volatile uint8_t car_speed[8]; |
30 volatile uint8_t car_speed[8]; |
27 volatile uint8_t car_switch[8]; |
31 volatile uint8_t car_switch[8]; |
28 volatile uint8_t my_id; // Die ID des Autos! |
32 |
|
33 volatile uint8_t timeout = 0; |
|
34 volatile uint8_t brake_timeout = 0; |
|
35 |
29 |
36 |
30 uint8_t my_switch; |
37 uint8_t my_switch; |
31 uint8_t my_speed; |
38 uint8_t my_speed; |
32 uint8_t light_mode; |
39 config_t config; |
33 |
40 |
34 ISR ( INT0_vect ) { |
41 ISR ( INT0_vect ) { |
35 GICR &= ~_BV(INT0) ; // Disable INT0 |
42 GICR &= ~_BV(INT0) ; // Disable INT0 |
36 // Startsignal erkannt, ab hier den Timer2 starten, |
43 // Startsignal erkannt, ab hier den Timer2 starten, |
37 // der liest dann alle 50µs den Zustand ein und schreibt das |
44 // der liest dann alle 50µs den Zustand ein und schreibt das |
92 bitbuf_len &= ~_BV(6); // store new state |
99 bitbuf_len &= ~_BV(6); // store new state |
93 } |
100 } |
94 } |
101 } |
95 } |
102 } |
96 |
103 |
97 ISR (TIMER1_OVF_vect) { |
|
98 } |
|
99 |
|
100 ISR (INT1_vect) { |
104 ISR (INT1_vect) { |
|
105 } |
|
106 |
|
107 ISR (TIMER0_OVF_vect) { |
|
108 TCNT0 = 100; // TIMER0 vorladen mit 100 |
|
109 if (brake_timeout > 1) brake_timeout--; |
|
110 if (timeout > 1) timeout--; |
101 } |
111 } |
102 |
112 |
103 #define LIGHT_PORT PORTC |
113 #define LIGHT_PORT PORTC |
104 #define LIGHT_FRONT 2 |
114 #define LIGHT_FRONT 2 |
105 #define LIGHT_BRAKE 4 |
115 #define LIGHT_BRAKE 4 |
106 |
116 |
107 #define IR_PORT PORTB |
117 #define IR_PORT PORTB |
108 #define IR_LED 3 |
118 #define IR_LED 3 |
109 |
119 |
|
120 #define BRAKE_PORT PORTB |
|
121 #define BRAKE 0 |
110 |
122 |
111 #define LIGHT_MODES 1 // anzahl der lichtmodi (ohne den modus "aus") |
123 #define LIGHT_MODES 1 // anzahl der lichtmodi (ohne den modus "aus") |
112 |
124 |
113 |
125 |
|
126 void config_save(void) { |
|
127 eeprom_write_block( (void*)&config, 0, sizeof(config) ); |
|
128 } |
|
129 |
|
130 |
|
131 void brake_on(void) { |
|
132 LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on |
|
133 BRAKE_PORT |= _BV(BRAKE); // brake on |
|
134 brake_timeout = 50; |
|
135 } |
|
136 |
|
137 void brake_off(void) { |
|
138 LIGHT_PORT &= ~_BV(LIGHT_BRAKE); // brake light off |
|
139 BRAKE_PORT &= ~_BV(BRAKE); // brake off |
|
140 brake_timeout = 0; |
|
141 } |
114 |
142 |
115 int main(void) |
143 int main(void) |
116 { |
144 { |
117 uint8_t car0_state, car1_state; |
|
118 |
|
119 // setup data bit timer2 |
145 // setup data bit timer2 |
120 TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match |
146 TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match |
121 OCR2 = TIMER2_50US; |
147 OCR2 = TIMER2_50US; |
122 |
148 |
123 |
149 |
124 // enable both external interrupts |
150 // enable both external interrupts |
125 // int 0 = data RX |
151 // int 0 = data RX |
126 MCUCR = _BV(ISC00) | _BV(ISC01) | _BV(ISC10) | _BV(ISC11); // INT0/1 rising edge |
152 MCUCR = _BV(ISC00) | _BV(ISC01) | _BV(ISC10) | _BV(ISC11); // INT0/1 rising edge |
127 GICR = _BV(INT0) | _BV(INT1) ; // Enable INT0 + INT1 |
153 GICR = _BV(INT0) | _BV(INT1) ; // Enable INT0 + INT1 |
128 |
154 |
129 // oscillator calibration |
155 |
130 // atmega8@1mhz = 0xac |
156 DDR(LIGHT_PORT) |= _BV(LIGHT_FRONT) | _BV(LIGHT_BRAKE); |
131 // @4mhz = ca 0xa0 |
157 DDR(BRAKE_PORT) |= _BV(BRAKE); |
132 //OSCCAL = 0xa0; |
158 |
133 //OSCCAL = 0x9A; |
159 // config (from eeprom!) |
134 //OSCCAL = 0xa0; // internal oscillator @ 4 mhz.... doesnt work accurate! |
160 eeprom_read_block( (void*)&config, (const void*)0, sizeof(config) ); |
|
161 |
|
162 |
|
163 TCCR1A = (1<<WGM10)|(1<<COM1A1) // Set up the two Control registers of Timer1. |
|
164 |(1<<COM1B1); // Wave Form Generation is Fast PWM 8 Bit, |
|
165 |
|
166 TCCR1B = (1<<WGM12)|(1<<CS10); // OC1A and OC1B are cleared on compare match |
|
167 // and set at BOTTOM. Clock Prescaler is 1. |
|
168 |
|
169 |
|
170 //OCR1A = 63; // Dutycycle of OC1A = 25% |
|
171 //OCR1B = 127; // Dutycycle of OC1B = 50% |
|
172 OCR1A = 0; |
|
173 OCR1B = 0; |
|
174 |
|
175 // configure TIMER0 to overflow every 10ms at 4 MHz |
|
176 TIMSK = _BV(TOIE0); // Timer0 Overflow INT erlauben |
|
177 TCNT0 = 100; // TIMER0 vorladen mit 100 |
|
178 TCCR0 = _BV(CS02) ; // Vorteiler auf 256, ab hier läuft der TIMER0 |
|
179 |
135 sei(); |
180 sei(); |
136 |
181 |
137 DDR(LIGHT_PORT) |= (_BV(LIGHT_FRONT) | _BV(LIGHT_BRAKE)); |
182 |
138 |
183 config.slot = 1; |
139 //defaults (from eeprom!) |
|
140 my_id = 1; |
|
141 light_mode = 0; |
|
142 |
184 |
143 while (1) { |
185 while (1) { |
144 // main loop |
186 // main loop |
145 |
187 |
|
188 if (brake_timeout == 1) { |
|
189 DDRB &= ~_BV(2); // PB2 PWM Output disable |
|
190 brake_off(); |
|
191 } |
|
192 |
|
193 if (my_speed != car_speed[config.slot]) { |
|
194 my_speed = car_speed[config.slot]; |
|
195 OCR1B = (int) ((float)0xff * (float)((float)my_speed / (float)15)); |
|
196 if (my_speed == 0) { |
|
197 DDRB &= ~_BV(2); // PB2 PWM Output disable |
|
198 brake_on(); |
|
199 } else { |
|
200 brake_off(); |
|
201 DDRB |= _BV(2); // PB2 PWM Output enable |
|
202 } |
|
203 } |
|
204 |
146 // Light cycle if switch pressed without speed |
205 // Light cycle if switch pressed without speed |
147 if (my_speed == 0) { |
206 if (car_speed[config.slot] == 0) { |
148 if (my_switch != car_switch[my_id]) { |
207 if (my_switch != car_switch[config.slot]) { |
149 my_switch = car_switch[my_id]; |
208 my_switch = car_switch[config.slot]; |
150 if (my_switch != 0) { |
209 if (my_switch != 0) { |
151 // cycle light |
210 // cycle light |
152 if (light_mode == LIGHT_MODES) light_mode = 0; else light_mode++; |
211 if (config.light == LIGHT_MODES) config.light = 0; else config.light++; |
153 } |
212 } |
154 } |
213 } |
155 } |
214 } |
156 |
215 |
157 switch (light_mode) { |
216 switch (config.light) { |
158 case 0: |
217 case 0: |
159 LIGHT_PORT &= ~_BV(LIGHT_FRONT); // switch lights off |
218 LIGHT_PORT &= ~_BV(LIGHT_FRONT); // switch lights off |
160 break; |
219 break; |
161 case 1: |
220 case 1: |
162 LIGHT_PORT |= _BV(LIGHT_FRONT); // switch lights on |
221 LIGHT_PORT |= _BV(LIGHT_FRONT); // switch lights on |
163 break; |
222 break; |
164 } |
223 } |
165 |
224 |
|
225 |
|
226 /* |
166 _delay_ms(100); |
227 _delay_ms(100); |
167 LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on |
|
168 _delay_ms(100); |
228 _delay_ms(100); |
169 LIGHT_PORT &= ~_BV(LIGHT_BRAKE); // brake light off |
229 */ |
170 |
|
171 |
230 |
172 |
231 |
173 |
232 |
174 } // main loop end |
233 } // main loop end |
175 }; |
234 }; |