19 typedef struct { |
19 typedef struct { |
20 uint8_t calibration; // AVR Chip calibration byte written by avrdude |
20 uint8_t calibration; // AVR Chip calibration byte written by avrdude |
21 uint8_t initialized; // if 0xff, reset config to defaults on first boot |
21 uint8_t initialized; // if 0xff, reset config to defaults on first boot |
22 uint8_t slot; |
22 uint8_t slot; |
23 uint8_t light; |
23 uint8_t light; |
|
24 uint8_t brake; |
|
25 uint8_t accel; |
24 uint8_t program; // 0xff = inactive ; programming mode active on slot X |
26 uint8_t program; // 0xff = inactive ; programming mode active on slot X |
25 } config_t; |
27 } config_t; |
26 config_t EEMEM eeconfig = {0,0,0,0xff,0}; |
28 config_t EEMEM eeconfig = {0,0xff,0,0,15,15,0}; |
27 config_t config; |
29 config_t config; |
28 |
30 |
29 volatile uint16_t data = 0; |
31 volatile uint16_t data = 0; |
30 volatile uint8_t data_len = 0; |
32 volatile uint8_t data_len = 0; |
31 volatile uint8_t bitbuf_len = 0; |
33 volatile uint8_t bitbuf_len = 0; |
32 volatile uint16_t bitbuf = 0; |
34 volatile uint16_t bitbuf = 0; |
33 volatile uint8_t car_speed[MAX_SLOTS]; |
35 volatile uint8_t car_speed[MAX_SLOTS]; |
34 volatile uint8_t car_switch[MAX_SLOTS]; |
36 volatile uint8_t car_switch[MAX_SLOTS]; |
|
37 volatile uint8_t car_act[MAX_SLOTS]; |
35 |
38 |
36 volatile uint8_t car_timeout[MAX_SLOTS]; |
39 volatile uint8_t car_timeout[MAX_SLOTS]; |
37 volatile uint8_t timeout = 0; |
40 volatile uint8_t timeout = 0; |
38 volatile uint8_t brake_timeout = 0; |
41 volatile uint8_t brake_timeout = 0; |
39 |
42 |
48 // der liest dann alle 50µs den Zustand ein und schreibt das |
51 // der liest dann alle 50µs den Zustand ein und schreibt das |
49 // empfangene Bit in den Puffer |
52 // empfangene Bit in den Puffer |
50 bitbuf = 0; // init |
53 bitbuf = 0; // init |
51 bitbuf_len = 0b10000000; // init 1 pulse received |
54 bitbuf_len = 0b10000000; // init 1 pulse received |
52 |
55 |
53 TCNT2 = 10; |
56 //TCNT2 = 10; |
|
57 TCNT2 = 9; |
54 TIMSK |= _BV(OCIE2); //enable timer2 interrupt |
58 TIMSK |= _BV(OCIE2); //enable timer2 interrupt |
55 } |
59 } |
56 |
60 |
57 ISR ( TIMER2_COMP_vect ) { |
61 ISR ( TIMER2_COMP_vect ) { |
|
62 // TCNT2 = 0; |
58 uint8_t clock; |
63 uint8_t clock; |
59 uint8_t state; |
64 uint8_t state; |
60 uint8_t state2; |
65 uint8_t state2; |
61 if ((bitbuf_len & 0b10000000) == 0) clock = 0; else clock = 0xff; |
66 if ((bitbuf_len & 0b10000000) == 0) clock = 0; else clock = 0xff; |
62 if ((bitbuf_len & 0b01000000) == 0) state = 0; else state = 0xff; |
67 if ((bitbuf_len & 0b01000000) == 0) state = 0; else state = 0xff; |
140 eeprom_write_block( &config, &eeconfig, sizeof(config_t) ); |
141 eeprom_write_block( &config, &eeconfig, sizeof(config_t) ); |
141 } |
142 } |
142 |
143 |
143 |
144 |
144 void brake_on(void) { |
145 void brake_on(void) { |
|
146 OCR1A = (int) ((float)0xff * (float)((float)config.brake / (float)15)); |
145 LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on |
147 LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on |
146 DDRB |= _BV(1); // PB1 PWM Output enable |
148 DDRB |= _BV(1); // PB1 PWM Output enable |
147 brake_timeout = BRAKE_OFF_TIMEOUT; |
149 brake_timeout = BRAKE_OFF_TIMEOUT; |
148 } |
150 } |
149 |
151 |
150 void brake_off(void) { |
152 void brake_off(void) { |
|
153 OCR1A = 0; |
151 LIGHT_PORT &= ~_BV(LIGHT_BRAKE); // brake light off |
154 LIGHT_PORT &= ~_BV(LIGHT_BRAKE); // brake light off |
152 DDRB &= ~_BV(1); // PB1 PWM Output disable |
155 DDRB &= ~_BV(1); // PB1 PWM Output disable |
153 brake_timeout = 0; |
156 brake_timeout = 0; |
154 } |
157 } |
155 |
158 |
231 // and set at BOTTOM. Clock Prescaler is 1. |
236 // and set at BOTTOM. Clock Prescaler is 1. |
232 |
237 |
233 |
238 |
234 //OCR1A = 63; // Dutycycle of OC1A = 25% |
239 //OCR1A = 63; // Dutycycle of OC1A = 25% |
235 //OCR1B = 127; // Dutycycle of OC1B = 50% |
240 //OCR1B = 127; // Dutycycle of OC1B = 50% |
236 OCR1A = 0xff; // brake PWM! |
241 OCR1A = 0; // brake PWM! |
237 OCR1B = 0; // Motor drive PWM |
242 OCR1B = 0; // Motor drive PWM |
238 DDRB &= ~_BV(2); // PB2 PWM Output disable |
243 DDRB &= ~_BV(2); // PB2 PWM Output disable |
239 DDRB &= ~_BV(1); // PB1 PWM Output disable |
244 DDRB &= ~_BV(1); // PB1 PWM Output disable |
240 |
245 |
241 // configure TIMER0 to overflow every 10ms at 4 MHz |
246 // configure TIMER0 to overflow every 10ms at 4 MHz |
264 } |
269 } |
265 timeout = 0; |
270 timeout = 0; |
266 } |
271 } |
267 |
272 |
268 |
273 |
|
274 float my_accel; |
269 my_switch = car_switch[config.slot]; // initialize |
275 my_switch = car_switch[config.slot]; // initialize |
270 my_speed = car_speed[config.slot]; // initialize |
276 my_speed = car_speed[config.slot]; // initialize |
|
277 my_accel = (float)config.accel / (float)15; |
271 |
278 |
272 while (1) { |
279 while (1) { |
273 // main loop |
280 // main loop |
274 |
281 |
275 if (brake_timeout == 1) brake_off(); |
282 if (brake_timeout == 1) brake_off(); |
276 |
283 |
277 if (my_speed != car_speed[config.slot]) { |
284 if (my_speed != car_speed[config.slot]) { |
278 my_speed = car_speed[config.slot]; |
285 my_speed = car_speed[config.slot]; |
279 OCR1B = (int) ((float)0xff * (float)((float)my_speed / (float)15)); |
286 OCR1B = (int) ((float)0xff * (float)((float)my_speed / (float)15) * my_accel ); |
280 if (my_speed == 0) { |
287 if (my_speed == 0) { |
281 DDRB &= ~_BV(2); // PB2 PWM Output disable |
288 DDRB &= ~_BV(2); // PB2 PWM Output disable |
282 brake_on(); |
289 brake_on(); |
283 } else { |
290 } else { |
284 brake_off(); |
291 brake_off(); |