blackbox/main.c

changeset 139
7127e7082ee0
parent 126
0d6fbfaae49b
child 140
f910ad6ed0b6
equal deleted inserted replaced
138:a570dd24a413 139:7127e7082ee0
13 #include "main.h" 13 #include "main.h"
14 #include "lowlevel.h" 14 #include "lowlevel.h"
15 15
16 const char ok[] PROGMEM="OK\n"; 16 const char ok[] PROGMEM="OK\n";
17 const char busy[] PROGMEM="BUSY\n"; 17 const char busy[] PROGMEM="BUSY\n";
18 const char prepare[] PROGMEM="!RACE PREPARE\n"; 18
19 const char countdownstart[] PROGMEM="!COUNTDOWN\n"; 19 const char prepare[] PROGMEM="!PRE\n";
20 const char racestart[] PROGMEM="!RACE START\n"; 20 const char countdownstart[] PROGMEM="!SET\n";
21 21 const char racestart[] PROGMEM="!GO\n";
22 const char SHORTCUT[] PROGMEM="!SHORTCUT\n"; 22
23 const char PANIC[] PROGMEM="!PANIC\n"; 23 const char SHORTCUT[] PROGMEM="!OC\n";
24 const char PANIC[] PROGMEM="!STOP\n";
24 const char RESUME[] PROGMEM="!RESUME\n"; 25 const char RESUME[] PROGMEM="!RESUME\n";
25 26
26 typedef union { 27 typedef union {
27 uint32_t value; 28 uint32_t value;
28 uint16_t word[2]; // high, low word 29 uint16_t word[2]; // high, low word
29 uint8_t byte[4]; // all four bytes 30 uint8_t byte[4]; // all four bytes
30 } u32; 31 } u32;
32
33 typedef union {
34 uint16_t value;
35 uint8_t byte[2]; // all two bytes
36 } u16;
31 37
32 #define FUEL_FULL 10000 38 #define FUEL_FULL 10000
33 #define FUEL_JUMPSTART 5000 39 #define FUEL_JUMPSTART 5000
34 #define FUEL_DIV_DEFAULT 25 40 #define FUEL_DIV_DEFAULT 25
35 #define PITLANE_SPEEDLIMIT 10 41 #define PITLANE_SPEEDLIMIT 10
46 unsigned trackswitch:1; // 1bit bool 52 unsigned trackswitch:1; // 1bit bool
47 unsigned canrefuel:1; // 1bit bool 53 unsigned canrefuel:1; // 1bit bool
48 unsigned unlimitedfuel:1; // 1bit bool 54 unsigned unlimitedfuel:1; // 1bit bool
49 unsigned trackchange:1; // 1bit bool 55 unsigned trackchange:1; // 1bit bool
50 uint16_t jumpstart_time, fuel; 56 uint16_t jumpstart_time, fuel;
51 uint8_t laps; 57 uint16_t laps;
52 u32 lap_time_start, lap_time; 58 u32 lap_time_start, lap_time;
53 } cardata; 59 } cardata;
54 60
55 static char s[8]; 61 static char s[8];
56 static uint8_t countdown, countdown_loops; 62 static uint8_t countdown, countdown_loops;
163 if (switches.pitlane_finishline) slot[car].laps++; 169 if (switches.pitlane_finishline) slot[car].laps++;
164 } 170 }
165 if (status == 6) for (data=0; data<MAX_SLOTS; data++) slot[data].canrefuel = 0; 171 if (status == 6) for (data=0; data<MAX_SLOTS; data++) slot[data].canrefuel = 0;
166 if (status == 7) slot[car].canrefuel = 0; 172 if (status == 7) slot[car].canrefuel = 0;
167 } 173 }
174
175 /* Old ASCII Format:
168 RS232_puts("RW:"); 176 RS232_puts("RW:");
169 RS232_putc(car + '0'); 177 RS232_putc(car + '0');
170 RS232_putc(':'); 178 RS232_putc(':');
171 RS232_putc(type + '0'); 179 RS232_putc(type + '0');
172 RS232_putc(':'); 180 RS232_putc(':');
176 itoa(status, s, 16); 184 itoa(status, s, 16);
177 RS232_puts(s); 185 RS232_puts(s);
178 RS232_putc(':'); 186 RS232_putc(':');
179 ultoa(sysclk.value, s, 16); 187 ultoa(sysclk.value, s, 16);
180 RS232_puts(s); 188 RS232_puts(s);
189 RS232_putc('\n');
190 */
191
192 // New binary protocol: TODO: compress sender & status, car & type
193 RS232_puts("RW:\n");
194 RS232_putc(8); // 8 binary bytes following
195 RS232_putc(car);
196 RS232_putc(type);
197 RS232_putc(sender);
198 RS232_putc(status);
199 RS232_putc(sysclk.byte[3]);
200 RS232_putc(sysclk.byte[2]);
201 RS232_putc(sysclk.byte[1]);
202 RS232_putc(sysclk.byte[0]);
181 RS232_putc('\n'); 203 RS232_putc('\n');
182 } 204 }
183 205
184 int insert_queue(uint16_t tmp, uint8_t len) { 206 int insert_queue(uint16_t tmp, uint8_t len) {
185 if (transmit_buffer_queue == 0) { 207 if (transmit_buffer_queue == 0) {
216 } 238 }
217 } 239 }
218 240
219 ISR ( USART_RXC_vect ) { 241 ISR ( USART_RXC_vect ) {
220 uint8_t tmp; 242 uint8_t tmp;
243 u16 fuel, jumpstart_time;
221 char c = UDR; 244 char c = UDR;
222 245
223 // check for buffer overflow 246 // check for buffer overflow
224 if (buffer_len==sizeof(buffer)) { 247 if (buffer_len==sizeof(buffer)) {
225 buffer_len=0; 248 buffer_len=0;
300 break; 323 break;
301 324
302 case '+': // toggle panic mode 325 case '+': // toggle panic mode
303 RS232_puts_p(ok); 326 RS232_puts_p(ok);
304 if (mode != 0xff) { 327 if (mode != 0xff) {
305 mode = 0xff; 328 mode = 0xff;
306 RS232_puts_p(PANIC); 329 RS232_puts_p(PANIC);
307 } else { 330 } else {
308 mode = 0; 331 mode = 0;
309 RS232_puts_p(RESUME); 332 RS232_puts_p(RESUME);
310 } 333 }
311 break; 334 break;
312 335
313 case 'I': // get Information data (incl. important global parameter dump) 336 case 'I': // get Information data (incl. important global parameter dump)
337 // New binary protocol:
338 RS232_puts("V:");
314 RS232_puts(VERSION); 339 RS232_puts(VERSION);
315 RS232_putc(':'); 340 RS232_puts(":\n");
316 for (tmp=0;tmp<MAX_SLOTS;tmp++) RS232_putc(slot[tmp].speedlimit); // output speed limits 341 RS232_putc(6 * MAX_SLOTS); // binary bytes following
317 RS232_putc(':');
318 for (tmp=0;tmp<MAX_SLOTS;tmp++) RS232_putc(slot[tmp].speedminimum); // output minimum speed
319 RS232_putc(':');
320 for (tmp=0;tmp<MAX_SLOTS;tmp++) { 342 for (tmp=0;tmp<MAX_SLOTS;tmp++) {
321 itoa(slot[tmp].fuel, s, 16); 343 fuel.value = slot[tmp].fuel;
322 RS232_putc(s); // output fuel levels (0=empty, 100=full, 0xff=no fuel option) 344 jumpstart_time.value = slot[tmp].jumpstart_time;
323 RS232_putc(','); 345 RS232_putc(slot[tmp].speedlimit); // output speed limits
346 RS232_putc(slot[tmp].speedminimum); // output minimum speed
347 RS232_putc(fuel.byte[1]); // output fuel levels (0=empty, 100=full, 0xff=no fuel option)
348 RS232_putc(fuel.byte[0]); // output fuel levels (0=empty, 100=full, 0xff=no fuel option)
349 RS232_putc(jumpstart_time.byte[1]); // output jumpstart times
350 RS232_putc(jumpstart_time.byte[0]); // output jumpstart times
324 } 351 }
325 RS232_putc(':');
326 for (tmp=0;tmp<MAX_SLOTS;tmp++) {
327 itoa(slot[tmp].jumpstart_time, s, 16);
328 RS232_puts(s); // output jumpstart times
329 RS232_putc(',');
330 }
331 RS232_putc(':');
332 RS232_putc('\n'); 352 RS232_putc('\n');
333 break; 353 break;
334 354
335 } 355 }
336 356
481 if ((slot[2].speedminimum != 0) || ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) > 0)) tmp |= 0b10010001; 501 if ((slot[2].speedminimum != 0) || ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) > 0)) tmp |= 0b10010001;
482 if ((slot[3].speedminimum != 0) || ((getADC(CONTROLLER4_SPEED) / CONTROLLER_DIVISOR) > 0)) tmp |= 0b10001001; 502 if ((slot[3].speedminimum != 0) || ((getADC(CONTROLLER4_SPEED) / CONTROLLER_DIVISOR) > 0)) tmp |= 0b10001001;
483 if (slot[4].speedminimum != 0) tmp |= 0b10000101; 503 if (slot[4].speedminimum != 0) tmp |= 0b10000101;
484 if (slot[5].speedminimum != 0) tmp |= 0b10000011; 504 if (slot[5].speedminimum != 0) tmp |= 0b10000011;
485 } 505 }
486 // todo: wenn Daten enpfangen wurden hier eine Quittierung senden anstatt dem Active Word 506 // TODO: wenn Daten enpfangen wurden hier eine Quittierung senden anstatt dem Active Word
487 507
488 return insert_queue(tmp, 7); 508 return insert_queue(tmp, 7);
489 } 509 }
490 510
491 int do_pace_ghost(void) { 511 int do_pace_ghost(void) {
543 } 563 }
544 } 564 }
545 565
546 void check_cars(void) { 566 void check_cars(void) {
547 u32 clk, diff; 567 u32 clk, diff;
568 u16 laps;
548 clk.value = sysclk.value; // freeze system clock time 569 clk.value = sysclk.value; // freeze system clock time
549 570
550 if (car0 != car0_state) { 571 if (car0 != car0_state) {
551 car0_state = car0; 572 car0_state = car0;
552 if (car0_state != 0) { 573 if (car0_state != 0) {
553 diff.value = clk.value - slot[car0-1].lap_time_start.value; 574 diff.value = clk.value - slot[car0-1].lap_time_start.value;
554 if ( diff.value > FINISHLINE_DIFF_BLOCK ) { 575 if ( diff.value > FINISHLINE_DIFF_BLOCK ) {
555 if (slot[car0-1].lap_time_start.value != 0) { 576 if (slot[car0-1].lap_time_start.value != 0) {
556 slot[car0-1].lap_time.value = diff.value; 577 slot[car0-1].lap_time.value = diff.value;
557 slot[car0-1].laps++; 578 slot[car0-1].laps++;
558 RS232_puts("L:3:"); // 3 = BB 579 laps.value = slot[car0-1].laps;
559 itoa(slot[car0-1].laps, s, 16); 580 // New binary protocol:
560 RS232_puts(s); 581 RS232_puts("L:3:\n"); // 3 = BB
561 RS232_putc(':'); 582 RS232_putc(11); // binary bytes following
562 RS232_putc('0'+car0_state); 583 RS232_putc(laps.byte[1]);
563 RS232_putc(':'); 584 RS232_putc(laps.byte[0]);
564 ultoa(diff.value, s, 16); 585 RS232_putc(car0_state); // slot number
565 RS232_puts(s); 586 RS232_putc(diff.byte[3]);
566 RS232_putc(':'); 587 RS232_putc(diff.byte[2]);
567 ultoa(clk.value, s, 16); 588 RS232_putc(diff.byte[1]);
568 RS232_puts(s); 589 RS232_putc(diff.byte[0]);
590 RS232_putc(sysclk.byte[3]);
591 RS232_putc(sysclk.byte[2]);
592 RS232_putc(sysclk.byte[1]);
593 RS232_putc(sysclk.byte[0]);
569 RS232_putc('\n'); 594 RS232_putc('\n');
570 } 595 }
571 slot[car0-1].lap_time_start.value = clk.value; 596 slot[car0-1].lap_time_start.value = clk.value;
572 } 597 }
573 } 598 }
580 diff.value = clk.value - slot[car1-1].lap_time_start.value; 605 diff.value = clk.value - slot[car1-1].lap_time_start.value;
581 if ( diff.value > FINISHLINE_DIFF_BLOCK ) { 606 if ( diff.value > FINISHLINE_DIFF_BLOCK ) {
582 if (slot[car1-1].lap_time_start.value != 0) { 607 if (slot[car1-1].lap_time_start.value != 0) {
583 slot[car1-1].lap_time.value = diff.value; 608 slot[car1-1].lap_time.value = diff.value;
584 slot[car1-1].laps++; 609 slot[car1-1].laps++;
585 RS232_puts("L:1:"); // 1 = AA 610 laps.value = slot[car1-1].laps;
586 itoa(slot[car1-1].laps, s, 16); 611 // New binary protocol:
587 RS232_puts(s); 612 RS232_puts("L:1:\n"); // 1 = AA
588 RS232_putc(':'); 613 RS232_putc(11); // binary bytes following
589 RS232_putc('0'+car1_state); 614 RS232_putc(laps.byte[1]);
590 RS232_putc(':'); 615 RS232_putc(laps.byte[0]);
591 ultoa(diff.value, s, 16); 616 RS232_putc(car1_state); // slot number
592 RS232_puts(s); 617 RS232_putc(diff.byte[3]);
593 RS232_putc(':'); 618 RS232_putc(diff.byte[2]);
594 ultoa(clk.value, s, 16); 619 RS232_putc(diff.byte[1]);
595 RS232_puts(s); 620 RS232_putc(diff.byte[0]);
621 RS232_putc(sysclk.byte[3]);
622 RS232_putc(sysclk.byte[2]);
623 RS232_putc(sysclk.byte[1]);
624 RS232_putc(sysclk.byte[0]);
596 RS232_putc('\n'); 625 RS232_putc('\n');
597 } 626 }
598 slot[car1-1].lap_time_start.value = clk.value; 627 slot[car1-1].lap_time_start.value = clk.value;
599 } 628 }
600 } 629 }
602 631
603 } 632 }
604 633
605 void slot_liveinfo(uint8_t idx) { 634 void slot_liveinfo(uint8_t idx) {
606 if (switches.liveinfo == 0) return; 635 if (switches.liveinfo == 0) return;
636 u16 fuel;
607 637
608 if (switches.liveinfo == 1) { 638 if (switches.liveinfo == 1) {
609 // increment packet counter, if == 10 output some live info 639 // increment packet counter, if == 10 output some live info
610 if (slot[idx].seccnt == 10) { 640 if (slot[idx].seccnt == 10) {
611 // output current fuel status 641 // output current fuel status
612 RS232_putc('F'); 642 fuel.value = slot[idx].fuel;
613 RS232_putc(':'); 643 // new Binary protocol:
614 RS232_putc(idx + '0'); 644 RS232_puts("F:\n");
615 RS232_putc(':'); 645 RS232_putc(7); // binary bytes following
616 itoa(slot[idx].fuel, s, 16); 646 RS232_putc(idx); // slot
617 RS232_puts(s); 647 RS232_putc(fuel.byte[1]);
618 RS232_putc(':'); 648 RS232_putc(fuel.byte[0]);
619 ultoa(sysclk.value, s, 16); 649 RS232_putc(sysclk.byte[3]);
620 RS232_puts(s); 650 RS232_putc(sysclk.byte[2]);
651 RS232_putc(sysclk.byte[1]);
652 RS232_putc(sysclk.byte[0]);
621 RS232_putc('\n'); 653 RS232_putc('\n');
622 slot[idx].seccnt = 0; 654 slot[idx].seccnt = 0;
623 } else slot[idx].seccnt++; 655 } else slot[idx].seccnt++;
624 } else if ( (switches.liveinfo - 2) == idx ) { 656 } else if ( (switches.liveinfo - 2) == idx ) {
625 // output controller status LIVEINFO-2 for remote learning 657 // output controller status LIVEINFO-2 for remote learning
658 // TODO: old ascii protocol
626 RS232_putc('L'); 659 RS232_putc('L');
627 RS232_putc('N'); 660 RS232_putc('N');
628 RS232_putc(':'); 661 RS232_putc(':');
629 itoa(slot[idx].speed, s, 16); 662 itoa(slot[idx].speed, s, 16);
630 RS232_puts(s); 663 RS232_puts(s);
656 check_rails_shortcut(); 689 check_rails_shortcut();
657 check_cars(); 690 check_cars();
658 while (mode == 0xff) panic_mode(); 691 while (mode == 0xff) panic_mode();
659 692
660 if (response_len > 0) { 693 if (response_len > 0) {
661 itoa(response, s, 2); 694 //TODO: Track response data???
695 //itoa(response, s, 2);
662 response_len = 0; 696 response_len = 0;
663 //RS232_puts("ANSWER RX: "); 697 //RS232_puts("ANSWER RX: ");
664 //RS232_puts(s); 698 //RS232_puts(s);
665 //RS232_putc('\n'); 699 //RS232_putc('\n');
666 } 700 }

mercurial