45 unsigned pitlane_limit:4; // 4bits speedlimit |
45 unsigned pitlane_limit:4; // 4bits speedlimit |
46 unsigned trackswitch:1; // 1bit bool |
46 unsigned trackswitch:1; // 1bit bool |
47 unsigned canrefuel:1; // 1bit bool |
47 unsigned canrefuel:1; // 1bit bool |
48 unsigned unlimitedfuel:1; // 1bit bool |
48 unsigned unlimitedfuel:1; // 1bit bool |
49 unsigned trackchange:1; // 1bit bool |
49 unsigned trackchange:1; // 1bit bool |
50 uint16_t jumpstart_time, laps, fuel; |
50 uint16_t jumpstart_time, fuel; |
|
51 uint8_t laps; |
51 u32 lap_time_start, lap_time; |
52 u32 lap_time_start, lap_time; |
52 } cardata; |
53 } cardata; |
53 |
54 |
54 static char s[8]; |
55 static char s[8]; |
55 static uint8_t countdown, countdown_loops; |
56 static uint8_t countdown, countdown_loops; |
63 |
64 |
64 extern uint8_t btn_start = _BV(SW_START); |
65 extern uint8_t btn_start = _BV(SW_START); |
65 extern uint8_t old_start = _BV(SW_START); |
66 extern uint8_t old_start = _BV(SW_START); |
66 |
67 |
67 // todo: pack as bit structure: |
68 // todo: pack as bit structure: |
68 uint8_t liveinfo = 0; |
69 |
69 uint8_t fuel_enabled = 1; |
70 typedef struct { |
70 uint8_t pitlane_finishline = 0; |
71 unsigned fuel_enabled:1; |
|
72 unsigned pitlane_finishline:1; |
|
73 unsigned liveinfo:6; |
|
74 } switches_s; |
|
75 switches_s switches; |
71 |
76 |
72 volatile u32 sysclk; |
77 volatile u32 sysclk; |
73 volatile uint8_t sysclk_packettimer = 0; |
78 volatile uint8_t sysclk_packettimer = 0; |
74 volatile cardata slot[MAX_SLOTS]; |
79 volatile cardata slot[MAX_SLOTS]; |
75 |
80 |
153 uint8_t type = (data & 0b111); |
158 uint8_t type = (data & 0b111); |
154 if (type == 4) { |
159 if (type == 4) { |
155 // pitlane response |
160 // pitlane response |
156 if (status == 5) { |
161 if (status == 5) { |
157 slot[car].canrefuel = 1; |
162 slot[car].canrefuel = 1; |
158 if (pitlane_finishline) slot[car].laps++; |
163 if (switches.pitlane_finishline) slot[car].laps++; |
159 } |
164 } |
160 if (status == 6) for (data=0; data<MAX_SLOTS; data++) slot[data].canrefuel = 0; |
165 if (status == 6) for (data=0; data<MAX_SLOTS; data++) slot[data].canrefuel = 0; |
161 if (status == 7) slot[car].canrefuel = 0; |
166 if (status == 7) slot[car].canrefuel = 0; |
162 } |
167 } |
163 RS232_puts("RW:"); |
168 RS232_puts("RW:"); |
257 slot[buffer[1]-'0'].speedminimum = tmp; |
262 slot[buffer[1]-'0'].speedminimum = tmp; |
258 RS232_puts_p(ok); |
263 RS232_puts_p(ok); |
259 break; |
264 break; |
260 |
265 |
261 case 'F': // set fuel enabled |
266 case 'F': // set fuel enabled |
262 fuel_enabled = buffer[1]-'0'; |
267 switches.fuel_enabled = buffer[1]-'0'; |
263 if (buffer[2] == ':') { |
268 if (buffer[2] == ':') { |
264 // convert fuel divisor |
269 // convert fuel divisor |
265 buffer[0] = '0'; // atoi expects zeros! |
270 buffer[0] = '0'; // atoi expects zeros! |
266 buffer[1] = '0'; |
271 buffer[1] = '0'; |
267 buffer[2] = '0'; |
272 buffer[2] = '0'; |
276 } |
281 } |
277 RS232_puts_p(ok); |
282 RS232_puts_p(ok); |
278 break; |
283 break; |
279 |
284 |
280 case '*': // set live information |
285 case '*': // set live information |
281 liveinfo = buffer[1]-'0'; |
286 switches.liveinfo = buffer[1]-'0'; |
282 RS232_puts_p(ok); |
287 RS232_puts_p(ok); |
283 break; |
288 break; |
284 |
289 |
285 case 'X': // set Pitlane act as finish line |
290 case 'X': // set Pitlane act as finish line |
286 // this can be used if pitlane exit comes after finish line while pitlane entry is before finish line |
291 // this can be used if pitlane exit comes after finish line while pitlane entry is before finish line |
287 pitlane_finishline = buffer[1]-'0'; |
292 switches.pitlane_finishline = buffer[1]-'0'; |
288 RS232_puts_p(ok); |
293 RS232_puts_p(ok); |
289 break; |
294 break; |
290 |
295 |
291 |
296 |
292 case '#': // remote start button press |
297 case '#': // remote start button press |
419 tmp |= (0b1000000000 | (controller << 6)); |
424 tmp |= (0b1000000000 | (controller << 6)); |
420 // FUEL BIT GETS SET WHEN FUEL == 0, |
425 // FUEL BIT GETS SET WHEN FUEL == 0, |
421 // THIS REQUIRES PHYSICAL CAR FUEL LEVEL SET TO ZERO BEFORE! |
426 // THIS REQUIRES PHYSICAL CAR FUEL LEVEL SET TO ZERO BEFORE! |
422 if ( ((PIN(SW_FUEL_PORT) & _BV(SW_FUEL)) != 0) | (slot[controller].fuel == 0)) tmp |= 1; |
427 if ( ((PIN(SW_FUEL_PORT) & _BV(SW_FUEL)) != 0) | (slot[controller].fuel == 0)) tmp |= 1; |
423 if (insert_queue(tmp, 9)) { |
428 if (insert_queue(tmp, 9)) { |
424 if ((fuel_enabled) && (slot[controller].unlimitedfuel == 0)) { |
429 if ((switches.fuel_enabled) && (slot[controller].unlimitedfuel == 0)) { |
425 if ((speed != 0) && (fuel_divisor > 0)) { |
430 if ((speed != 0) && (fuel_divisor > 0)) { |
426 // do the fuel calculation, regardless if fuel logic active or not |
431 // do the fuel calculation, regardless if fuel logic active or not |
427 tmp = (uint8_t)(((slot[controller].accel * speed) + 1) / fuel_divisor); |
432 tmp = (uint8_t)(((slot[controller].accel * speed) + 1) / fuel_divisor); |
428 if (tmp == 0) tmp = 1; |
433 if (tmp == 0) tmp = 1; |
429 if (slot[controller].fuel > 0) { |
434 if (slot[controller].fuel > 0) { |
596 } car1 = 0; |
601 } car1 = 0; |
597 |
602 |
598 } |
603 } |
599 |
604 |
600 void slot_liveinfo(uint8_t idx) { |
605 void slot_liveinfo(uint8_t idx) { |
601 if (liveinfo == 0) return; |
606 if (switches.liveinfo == 0) return; |
602 |
607 |
603 if (liveinfo == 1) { |
608 if (switches.liveinfo == 1) { |
604 // increment packet counter, if == 10 output some live info |
609 // increment packet counter, if == 10 output some live info |
605 if (slot[idx].seccnt == 10) { |
610 if (slot[idx].seccnt == 10) { |
606 // output current fuel status |
611 // output current fuel status |
607 RS232_putc('F'); |
612 RS232_putc('F'); |
608 RS232_putc(':'); |
613 RS232_putc(':'); |
614 ultoa(sysclk.value, s, 16); |
619 ultoa(sysclk.value, s, 16); |
615 RS232_puts(s); |
620 RS232_puts(s); |
616 RS232_putc('\n'); |
621 RS232_putc('\n'); |
617 slot[idx].seccnt = 0; |
622 slot[idx].seccnt = 0; |
618 } else slot[idx].seccnt++; |
623 } else slot[idx].seccnt++; |
619 } else if ( (liveinfo - 2) == idx ) { |
624 } else if ( (switches.liveinfo - 2) == idx ) { |
620 // output controller status LIVEINFO-2 for remote learning |
625 // output controller status LIVEINFO-2 for remote learning |
621 RS232_putc('L'); |
626 RS232_putc('L'); |
622 RS232_putc('N'); |
627 RS232_putc('N'); |
623 RS232_putc(':'); |
628 RS232_putc(':'); |
624 itoa(slot[idx].speed, s, 16); |
629 itoa(slot[idx].speed, s, 16); |