24 uint16_t word[2]; // high, low word |
24 uint16_t word[2]; // high, low word |
25 uint8_t byte[4]; // all four bytes |
25 uint8_t byte[4]; // all four bytes |
26 } u32; |
26 } u32; |
27 |
27 |
28 #define MAX_SLOTS 6 |
28 #define MAX_SLOTS 6 |
|
29 #define FUEL_FULL 10000 |
29 typedef struct { |
30 typedef struct { |
30 unsigned speedlimit:4; // 4bits speedlimit |
31 unsigned speedlimit:4; // 4bits speedlimit |
31 unsigned speedminimum:4; // 4bits speedminimum |
32 unsigned speedminimum:4; // 4bits speedminimum |
|
33 unsigned seccnt:4; // 4 bits tenth seconds counter |
|
34 unsigned accel:4; // 4 bits last configured acceleration |
32 unsigned trackswitch:1; // 1bit bool |
35 unsigned trackswitch:1; // 1bit bool |
33 uint8_t fuel; |
36 uint16_t jumpstart_time, laps, fuel; |
34 uint16_t jumpstart_time, laps; |
|
35 u32 lap_time_start, lap_time; |
37 u32 lap_time_start, lap_time; |
36 } cardata; |
38 } cardata; |
37 |
39 |
38 static unsigned char s[8]; |
40 static char s[8]; |
39 static uint8_t countdown, countdown_loops; |
41 static uint8_t countdown, countdown_loops; |
40 uint8_t mode = 0; |
42 uint8_t mode = 0; |
41 // valid race modes: |
43 // valid race modes: |
42 // 0: free drive / idle |
44 // 0: free drive / idle |
43 // 1: waiting for countdown start |
45 // 1: waiting for countdown start |
175 RS232_putc('\n'); |
177 RS232_putc('\n'); |
176 } |
178 } |
177 |
179 |
178 } |
180 } |
179 |
181 |
180 int do_controller(uint8_t controller) { |
182 uint8_t do_controller(uint8_t controller) { |
181 // read controller X speed & encode controller data packet |
183 // read controller X speed & encode controller data packet |
182 uint16_t tmp = 0; |
184 uint16_t tmp = 0; |
|
185 uint8_t speed; |
183 uint8_t trackchange = 0xff; |
186 uint8_t trackchange = 0xff; |
184 |
187 |
185 if ( (PIN(SW_PACECAR_PORT) & _BV(SW_PACECAR)) == 0 ) { |
188 if ( (PIN(SW_PACECAR_PORT) & _BV(SW_PACECAR)) == 0 ) { |
186 // map controller 1+2 to 5+6 |
189 // map controller 1+2 to 5+6 |
187 if (controller == 4) tmp = ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) & 0x0F); |
190 if (controller == 4) tmp = ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) & 0x0F); |
188 if (controller == 5) tmp = ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) & 0x0F); |
191 if (controller == 5) tmp = ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) & 0x0F); |
189 if (controller == 4) trackchange = (PIN(CONTROLLER_PORT) & _BV(CONTROLLER1_SW)); |
192 if (controller == 4) trackchange = (PIN(CONTROLLER_PORT) & _BV(CONTROLLER1_SW)); |
190 if (controller == 5) trackchange = (PIN(CONTROLLER_PORT) & _BV(CONTROLLER2_SW)); |
193 if (controller == 5) trackchange = (PIN(CONTROLLER_PORT) & _BV(CONTROLLER2_SW)); |
|
194 speed = tmp; |
191 } else { |
195 } else { |
192 // read speeds |
196 // read speeds |
193 if ((controller == 0) && (mode!=1)) tmp = ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) & 0x0F); |
197 if ((controller == 0) && (mode!=1)) tmp = ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) & 0x0F); |
194 if ((controller == 1) && (mode!=1)) tmp = ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) & 0x0F); |
198 if ((controller == 1) && (mode!=1)) tmp = ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) & 0x0F); |
195 if ((controller == 2) && (mode!=1)) tmp = ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) & 0x0F); |
199 if ((controller == 2) && (mode!=1)) tmp = ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) & 0x0F); |
201 |
205 |
202 if (controller < 4) { |
206 if (controller < 4) { |
203 if (tmp < slot[controller].speedminimum) tmp = slot[controller].speedminimum; |
207 if (tmp < slot[controller].speedminimum) tmp = slot[controller].speedminimum; |
204 if ((mode == 2) && (tmp != 0)) { jumpstart(controller); tmp = 0; } |
208 if ((mode == 2) && (tmp != 0)) { jumpstart(controller); tmp = 0; } |
205 if (tmp > slot[controller].speedlimit) tmp = slot[controller].speedlimit; |
209 if (tmp > slot[controller].speedlimit) tmp = slot[controller].speedlimit; |
|
210 speed = tmp; |
206 tmp = tmp << 1; |
211 tmp = tmp << 1; |
207 } else { |
212 } else { |
208 if ((mode == 0) && (tmp < slot[controller].speedminimum)) tmp = slot[controller].speedminimum; |
213 if ((mode == 0) && (tmp < slot[controller].speedminimum)) tmp = slot[controller].speedminimum; |
209 if (tmp > slot[controller].speedlimit) tmp = slot[controller].speedlimit; |
214 if (tmp > slot[controller].speedlimit) tmp = slot[controller].speedlimit; |
|
215 speed = tmp; |
210 tmp = tmp << 1; |
216 tmp = tmp << 1; |
211 if (trackchange || slot[controller].trackswitch) tmp |= (1<<5); |
217 if (trackchange || slot[controller].trackswitch) tmp |= (1<<5); |
212 } |
218 } |
|
219 |
213 } |
220 } |
214 |
221 |
215 switch (controller) { |
222 switch (controller) { |
216 case 0: |
223 case 0: |
217 if (trackchange != 0) { |
224 if (trackchange != 0) { |
239 break; |
246 break; |
240 } |
247 } |
241 |
248 |
242 tmp |= (0b1000000000 | (controller << 6)); |
249 tmp |= (0b1000000000 | (controller << 6)); |
243 if ( (PIN(SW_FUEL_PORT) & _BV(SW_FUEL)) != 0) tmp |= 1; // benzinstand aktiv - tankmodusschalter |
250 if ( (PIN(SW_FUEL_PORT) & _BV(SW_FUEL)) != 0) tmp |= 1; // benzinstand aktiv - tankmodusschalter |
244 return insert_queue(tmp, 9); |
251 if (insert_queue(tmp, 9)) { |
|
252 if (speed != 0) { |
|
253 // do the fuel calculation, regardless if fuel logic active or not |
|
254 tmp = (uint8_t)(((slot[controller].accel * speed) + 1) / 25); |
|
255 if (tmp == 0) tmp = 1; |
|
256 if (slot[controller].fuel > 0) { |
|
257 // enough fuel left to decrement? |
|
258 if (slot[controller].fuel > tmp) { |
|
259 slot[controller].fuel -= tmp; // decrement fuel level |
|
260 } else slot[controller].fuel = 0; |
|
261 } |
|
262 } |
|
263 return 1; |
|
264 } else return 0; |
245 } |
265 } |
246 |
266 |
247 uint8_t mirror( uint8_t n ) { |
267 uint8_t mirror( uint8_t n ) { |
248 n = ((n >> 1) & 0x55) | ((n << 1) & 0xaa); |
268 n = ((n >> 1) & 0x55) | ((n << 1) & 0xaa); |
249 n = ((n >> 2) & 0x33) | ((n << 2) & 0xcc); |
269 n = ((n >> 2) & 0x33) | ((n << 2) & 0xcc); |
297 uint8_t i; |
317 uint8_t i; |
298 for (i=0; i<MAX_SLOTS; i++) { |
318 for (i=0; i<MAX_SLOTS; i++) { |
299 slot[i].speedlimit = 15; |
319 slot[i].speedlimit = 15; |
300 slot[i].speedminimum = 0; |
320 slot[i].speedminimum = 0; |
301 slot[i].trackswitch = 0; |
321 slot[i].trackswitch = 0; |
302 slot[i].fuel = 100; |
322 slot[i].fuel = FUEL_FULL; |
303 slot[i].jumpstart_time = 0; |
323 slot[i].jumpstart_time = 0; |
304 slot[i].laps = 0; |
324 slot[i].laps = 0; |
|
325 slot[i].seccnt = 0; |
|
326 slot[i].accel = 15; // full acceleration per default - TODO |
305 } |
327 } |
306 sysclk.value = 0; |
328 sysclk.value = 0; |
307 } |
329 } |
308 |
330 |
309 void countdown_progress(void) { |
331 void countdown_progress(void) { |
384 } |
406 } |
385 } |
407 } |
386 } car1 = 0; |
408 } car1 = 0; |
387 } |
409 } |
388 |
410 |
|
411 void slot_liveinfo(uint8_t idx) { |
|
412 // increment packet counter, if == 10 output some live info |
|
413 if (slot[idx].seccnt == 10) { |
|
414 // output current fuel status |
|
415 RS232_putc('F'); |
|
416 RS232_putc(':'); |
|
417 RS232_putc(idx + '0'); |
|
418 RS232_putc(':'); |
|
419 itoa(slot[idx].fuel, s, 16); |
|
420 RS232_puts(s); |
|
421 RS232_putc('\n'); |
|
422 |
|
423 slot[idx].seccnt = 0; |
|
424 } else slot[idx].seccnt++; |
|
425 } |
389 |
426 |
390 int main(void) |
427 int main(void) |
391 { |
428 { |
392 |
429 |
393 uint8_t packet_index = 1; |
430 uint8_t packet_index = 1; |
488 break; |
525 break; |
489 case 3: |
526 case 3: |
490 if (do_active()) packet_index++; |
527 if (do_active()) packet_index++; |
491 break; |
528 break; |
492 case 4: |
529 case 4: |
493 if (do_controller(0)) packet_index++; |
530 if (do_controller(0)) { packet_index++; |
|
531 slot_liveinfo(0); |
|
532 } |
494 break; |
533 break; |
495 case 5: |
534 case 5: |
496 if (do_controller(4)) packet_index++; |
535 if (do_controller(4)) { packet_index++; |
|
536 slot_liveinfo(4); |
|
537 } |
497 break; |
538 break; |
498 case 6: |
539 case 6: |
499 if (do_controller(1)) packet_index++; |
540 if (do_controller(1)) { packet_index++; |
|
541 slot_liveinfo(1); |
|
542 } |
500 break; |
543 break; |
501 case 7: |
544 case 7: |
502 if (do_controller(5)) packet_index++; |
545 if (do_controller(5)) { packet_index++; |
|
546 slot_liveinfo(5); |
|
547 } |
503 break; |
548 break; |
504 case 8: |
549 case 8: |
505 if (do_controller(2)) packet_index++; |
550 if (do_controller(2)) { packet_index++; |
|
551 slot_liveinfo(2); |
|
552 } |
506 break; |
553 break; |
507 case 9: |
554 case 9: |
508 if (do_active()) packet_index++; |
555 if (do_active()) packet_index++; |
509 break; |
556 break; |
510 case 10: |
557 case 10: |
511 if (do_controller(3)) packet_index = 1; |
558 if (do_controller(3)) { packet_index = 1; |
|
559 slot_liveinfo(3); |
|
560 } |
512 // last packet, so reset packet index |
561 // last packet, so reset packet index |
513 break; |
562 break; |
514 } |
563 } |
515 |
564 |
516 |
565 |