car004f/main.c

changeset 149
1c3425af9aa0
parent 148
08cb88614d69
child 151
0e71b51c83a5
equal deleted inserted replaced
148:08cb88614d69 149:1c3425af9aa0
17 #define PULSE_BIT PD2 17 #define PULSE_BIT PD2
18 18
19 typedef struct { 19 typedef struct {
20 uint8_t slot; 20 uint8_t slot;
21 uint8_t light; 21 uint8_t light;
22 unsigned program:1; // programming mode active 22 uint8_t program; // 0xff = inactive ; programming mode active on slot X
23 uint8_t initialized;
23 } config_t; 24 } config_t;
24 25 config_t EEMEM eeconfig = {0,0,0xff,0};
26 config_t config;
25 27
26 volatile uint16_t data = 0; 28 volatile uint16_t data = 0;
27 volatile uint8_t data_len = 0; 29 volatile uint8_t data_len = 0;
28 volatile uint8_t bitbuf_len = 0; 30 volatile uint8_t bitbuf_len = 0;
29 volatile uint16_t bitbuf = 0; 31 volatile uint16_t bitbuf = 0;
34 volatile uint8_t brake_timeout = 0; 36 volatile uint8_t brake_timeout = 0;
35 37
36 38
37 uint8_t my_switch; 39 uint8_t my_switch;
38 uint8_t my_speed; 40 uint8_t my_speed;
39 config_t config;
40 41
41 ISR ( INT0_vect ) { 42 ISR ( INT0_vect ) {
42 GICR &= ~_BV(INT0) ; // Disable INT0 43 GICR &= ~_BV(INT0) ; // Disable INT0
43 // Startsignal erkannt, ab hier den Timer2 starten, 44 // Startsignal erkannt, ab hier den Timer2 starten,
44 // der liest dann alle 50µs den Zustand ein und schreibt das 45 // der liest dann alle 50µs den Zustand ein und schreibt das
118 #define IR_LED 3 119 #define IR_LED 3
119 120
120 #define BRAKE_PORT PORTB 121 #define BRAKE_PORT PORTB
121 #define BRAKE 0 122 #define BRAKE 0
122 123
123 #define LIGHT_MODES 1 // anzahl der lichtmodi (ohne den modus "aus") 124 #define LIGHT_MODES 1 // anzahl der lichtmodi (ohne den modus "aus")
124 125 #define BRAKE_OFF_TIMEOUT 60 // value * 10ms
126
127 #define CAR_DEBUG 1
128 #define EE_CONFIG_ADDR 64
125 129
126 void config_save(void) { 130 void config_save(void) {
127 eeprom_write_block( (void*)&config, 0, sizeof(config) ); 131 eeprom_write_block( &config, &eeconfig, sizeof(config_t) );
128 } 132 }
129 133
130 134
131 void brake_on(void) { 135 void brake_on(void) {
132 LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on 136 LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on
133 BRAKE_PORT |= _BV(BRAKE); // brake on 137 BRAKE_PORT |= _BV(BRAKE); // brake on
134 brake_timeout = 50; 138 brake_timeout = BRAKE_OFF_TIMEOUT;
135 } 139 }
136 140
137 void brake_off(void) { 141 void brake_off(void) {
138 LIGHT_PORT &= ~_BV(LIGHT_BRAKE); // brake light off 142 LIGHT_PORT &= ~_BV(LIGHT_BRAKE); // brake light off
139 BRAKE_PORT &= ~_BV(BRAKE); // brake off 143 BRAKE_PORT &= ~_BV(BRAKE); // brake off
140 brake_timeout = 0; 144 brake_timeout = 0;
141 } 145 }
142 146
147 uint8_t scan_id(void) {
148 uint8_t temp;
149 timeout = 1;
150 // scan for any key press and assign to that controller
151 while (car_speed[config.slot] == 0) {
152 for (uint8_t i=0; i<6; i++) {
153 if (car_switch[i] == 1) {
154 // wait for second key press within timeout period to assign successfully
155 brake_timeout = 0xff;
156 temp = car_switch[i];
157 while (brake_timeout > 1) {
158 if (temp != car_switch[i]) {
159 temp = car_switch[i];
160 if (temp == 1) {
161 config.slot = i;
162 return 1;
163 }
164 }
165 // toggle lights if timeout
166 if (timeout == 1) {
167 LIGHT_PORT ^= _BV(LIGHT_FRONT);
168 timeout = 5;
169 }
170 }
171 return 0;
172 }
173 }
174 // toggle lights if timeout
175 if (timeout == 1) {
176 LIGHT_PORT ^= _BV(LIGHT_FRONT);
177 timeout = 10;
178 }
179 }
180 return 0;
181 }
182
143 int main(void) 183 int main(void)
144 { 184 {
185 uint8_t temp;
186
145 // setup data bit timer2 187 // setup data bit timer2
146 TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match 188 TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match
147 OCR2 = TIMER2_50US; 189 OCR2 = TIMER2_50US;
148 190
149 191
154 196
155 197
156 DDR(LIGHT_PORT) |= _BV(LIGHT_FRONT) | _BV(LIGHT_BRAKE); 198 DDR(LIGHT_PORT) |= _BV(LIGHT_FRONT) | _BV(LIGHT_BRAKE);
157 DDR(BRAKE_PORT) |= _BV(BRAKE); 199 DDR(BRAKE_PORT) |= _BV(BRAKE);
158 200
159 // config (from eeprom!)
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. 201 TCCR1A = (1<<WGM10)|(1<<COM1A1) // Set up the two Control registers of Timer1.
164 |(1<<COM1B1); // Wave Form Generation is Fast PWM 8 Bit, 202 |(1<<COM1B1); // Wave Form Generation is Fast PWM 8 Bit,
165 203
166 TCCR1B = (1<<WGM12)|(1<<CS10); // OC1A and OC1B are cleared on compare match 204 TCCR1B = (1<<WGM12)|(1<<CS10); // OC1A and OC1B are cleared on compare match
167 // and set at BOTTOM. Clock Prescaler is 1. 205 // and set at BOTTOM. Clock Prescaler is 1.
169 207
170 //OCR1A = 63; // Dutycycle of OC1A = 25% 208 //OCR1A = 63; // Dutycycle of OC1A = 25%
171 //OCR1B = 127; // Dutycycle of OC1B = 50% 209 //OCR1B = 127; // Dutycycle of OC1B = 50%
172 OCR1A = 0; 210 OCR1A = 0;
173 OCR1B = 0; 211 OCR1B = 0;
212 DDRB &= ~_BV(2); // PB2 PWM Output disable
174 213
175 // configure TIMER0 to overflow every 10ms at 4 MHz 214 // configure TIMER0 to overflow every 10ms at 4 MHz
176 TIMSK = _BV(TOIE0); // Timer0 Overflow INT erlauben 215 TIMSK = _BV(TOIE0); // Timer0 Overflow INT erlauben
177 TCNT0 = 100; // TIMER0 vorladen mit 100 216 TCNT0 = 100; // TIMER0 vorladen mit 100
178 TCCR0 = _BV(CS02) ; // Vorteiler auf 256, ab hier läuft der TIMER0 217 TCCR0 = _BV(CS02) ; // Vorteiler auf 256, ab hier läuft der TIMER0
179 218
180 sei(); 219 sei();
181 220
182 221 // config (from eeprom!)
183 config.slot = 1; 222 eeprom_read_block( &config, &eeconfig, sizeof(config_t) );
223
224
225 #ifdef CAR_DEBUG
226 if (config.initialized == 0) {
227 LIGHT_PORT &= ~_BV(LIGHT_FRONT);
228 for (temp = 0; temp <= config.slot; temp++) {
229 LIGHT_PORT ^= _BV(LIGHT_FRONT);
230 _delay_ms(250);
231 LIGHT_PORT ^= _BV(LIGHT_FRONT);
232 _delay_ms(250);
233 }
234 }
235 #endif
236
237
238
239 if (config.initialized != 0) {
240 config.slot = 0;
241 config.light = 0;
242 config.program = 0;
243 config.initialized = 0;
244 config_save();
245 }
246
247 if ((config.program != 0xff) || (config.slot > 5 )) {
248 temp = scan_id();
249 config.program = 0xff;
250 config_save();
251 if (temp == 1) {
252 // acknowledge with the engine
253 OCR1B = 25;
254 DDRB &= ~_BV(2); // PB2 PWM Output disable
255 for (temp = 0xff; temp > 0; temp--) {
256 DDRB ^= _BV(2); // PB2 PWM Output toggle
257 _delay_ms(5); // 50 hz
258 DDRB ^= _BV(2); // PB2 PWM Output toggle
259 _delay_ms(15); // 50 hz
260 }
261
262 }
263 timeout = 0;
264 }
265
184 266
185 while (1) { 267 while (1) {
186 // main loop 268 // main loop
187 269
188 if (brake_timeout == 1) { 270 if (brake_timeout == 1) brake_off();
189 DDRB &= ~_BV(2); // PB2 PWM Output disable
190 brake_off();
191 }
192 271
193 if (my_speed != car_speed[config.slot]) { 272 if (my_speed != car_speed[config.slot]) {
194 my_speed = car_speed[config.slot]; 273 my_speed = car_speed[config.slot];
195 OCR1B = (int) ((float)0xff * (float)((float)my_speed / (float)15)); 274 OCR1B = (int) ((float)0xff * (float)((float)my_speed / (float)15));
196 if (my_speed == 0) { 275 if (my_speed == 0) {
207 if (my_switch != car_switch[config.slot]) { 286 if (my_switch != car_switch[config.slot]) {
208 my_switch = car_switch[config.slot]; 287 my_switch = car_switch[config.slot];
209 if (my_switch != 0) { 288 if (my_switch != 0) {
210 // cycle light 289 // cycle light
211 if (config.light == LIGHT_MODES) config.light = 0; else config.light++; 290 if (config.light == LIGHT_MODES) config.light = 0; else config.light++;
291 if (timeout > 1) {
292 // zweiter Tastendruck, Program Mode im EEPROM setzen
293 config.program = 1; // TODO: hier muss der slot rein welcher doppelclicked wurde (natuerlich dann auch nicht in der Lichtschaltelogik abfragen!)
294 } else {
295 // erster Tastendruck, timeout setzen
296 timeout = 80;
297 }
298 config_save();
212 } 299 }
213 } 300 }
214 } 301 }
215 302
216 switch (config.light) { 303 switch (config.light) {
221 LIGHT_PORT |= _BV(LIGHT_FRONT); // switch lights on 308 LIGHT_PORT |= _BV(LIGHT_FRONT); // switch lights on
222 break; 309 break;
223 } 310 }
224 311
225 312
226 /* 313 // timeout reset
227 _delay_ms(100); 314 timeout = 0;
228 _delay_ms(100);
229 */
230
231
232
233 } // main loop end 315 } // main loop end
234 }; 316 };
235 317

mercurial