corrected lap times, packed data struct for each slotcar

Thu, 08 Dec 2011 15:44:43 +0100

author
Malte Bayer <mbayer@neo-soft.org>
date
Thu, 08 Dec 2011 15:44:43 +0100
changeset 46
d200e3d8a550
parent 45
da820f138498
child 47
34ac9f92bc1e

corrected lap times, packed data struct for each slotcar

blackbox/main.c file | annotate | diff | comparison | revisions
--- a/blackbox/main.c	Thu Dec 08 14:33:40 2011 +0100
+++ b/blackbox/main.c	Thu Dec 08 15:44:43 2011 +0100
@@ -20,11 +20,18 @@
 char racestart[]        PROGMEM="!RACE START\n";
 
 typedef union {
-    uint32_t u32;
+    uint32_t value;
     uint16_t word[2]; // high, low word
     uint8_t  byte[4]; // all four bytes
 } u32;
 
+#define MAX_SLOTS       6
+typedef struct {
+    uint8_t speedlimit, fuel, laps;
+    uint16_t jumpstart_time;
+    u32 lap_time_start, lap_time;
+} cardata;
+
 static unsigned char s[10];
 static uint8_t  countdown, countdown_loops;
 uint8_t  mode = 0;
@@ -34,19 +41,9 @@
 // 2: race countdown initiated
 // 3: Race start condition
 
-
-#define MAX_SLOTS       6
 volatile u32 sysclk;
 volatile uint8_t sysclk_packettimer = 0;
-
-volatile uint8_t speedlimit[MAX_SLOTS];
-volatile uint8_t fuel[MAX_SLOTS];
-volatile uint16_t jumpstart_time[MAX_SLOTS];
-
-volatile uint16_t lap_time_start_low[MAX_SLOTS];
-volatile uint16_t lap_time_start_high[MAX_SLOTS];
-volatile uint16_t lap_time_low[MAX_SLOTS];
-volatile uint16_t lap_time_high[MAX_SLOTS];
+volatile cardata slot[MAX_SLOTS];
 
 volatile uint16_t car0, car1;
 volatile uint16_t car0_new, car0_old;
@@ -119,23 +116,23 @@
                     tmp = buffer[2]-'0';
                     if (tmp > 9)
                         tmp = buffer[2]-'A'+10;
-                    speedlimit[buffer[1]-'0'] = tmp;
+                    slot[buffer[1]-'0'].speedlimit = tmp;
                     RS232_puts_p(ok);
                     break;
 
                 case 'I': // get Information data (incl. important global parameter dump)
                     RS232_puts(VERSION);
                     RS232_putc(':');
-                    for (tmp=0;tmp<MAX_SLOTS;tmp++) RS232_putc(speedlimit[tmp]); // output speed limits
+                    for (tmp=0;tmp<MAX_SLOTS;tmp++) RS232_putc(slot[tmp].speedlimit); // output speed limits
                     RS232_putc(':');
                     for (tmp=0;tmp<MAX_SLOTS;tmp++) {
-                        itoa(fuel[tmp], s, 16);
+                        itoa(slot[tmp].fuel, s, 16);
                         RS232_putc(s); // output fuel levels (0=empty, 100=full, 0xff=no fuel option)
                         RS232_putc(',');
                     }
                     RS232_putc(':');
                     for (tmp=0;tmp<MAX_SLOTS;tmp++) {
-                        itoa(jumpstart_time[tmp], s, 16);
+                        itoa(slot[tmp].jumpstart_time, s, 16);
                         RS232_puts(s); // output jumpstart times
                         RS232_putc(',');
                     }
@@ -155,12 +152,12 @@
 
 
 void jumpstart(uint8_t controller) {
-    if (jumpstart_time[controller] == 0) {
-        jumpstart_time[controller] = sysclk.word[1]; // low word
+    if (slot[controller].jumpstart_time == 0) {
+        slot[controller].jumpstart_time = sysclk.word[0]; // low word
         RS232_putc('~');
         RS232_putc('0'-controller);
-        RS232_putc(',');
-        itoa(jumpstart_time[controller], s, 16);
+        RS232_putc(':');
+        itoa(slot[controller].jumpstart_time, s, 16);
         RS232_puts(s);
         RS232_putc('\n');
     }
@@ -175,7 +172,7 @@
         case 0:
             if (mode!=1) tmp = ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) & 0x0F);
             if ((mode == 2) && (tmp != 0)) { jumpstart(controller); tmp = 0; }
-            if (tmp > speedlimit[controller]) tmp = speedlimit[controller];
+            if (tmp > slot[controller].speedlimit) tmp = slot[controller].speedlimit;
             tmp = tmp << 1;
             if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER1_SW)) != 0) {
                 tmp |= (1<<5);
@@ -185,7 +182,7 @@
         case 1:
             if (mode!=1) tmp = ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) & 0x0F);
             if ((mode == 2) && (tmp != 0)) { jumpstart(controller); tmp = 0; }
-            if (tmp > speedlimit[controller]) tmp = speedlimit[controller];
+            if (tmp > slot[controller].speedlimit) tmp = slot[controller].speedlimit;
             tmp = tmp << 1;
             if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER2_SW)) != 0) {
                 tmp |= (1<<5);
@@ -195,7 +192,7 @@
         case 2:
             if (mode!=1) tmp = ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) & 0x0F);
             if ((mode == 2) && (tmp != 0)) { jumpstart(controller); tmp = 0; }
-            if (tmp > speedlimit[controller]) tmp = speedlimit[controller];
+            if (tmp > slot[controller].speedlimit) tmp = slot[controller].speedlimit;
             tmp = tmp << 1;
             if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER3_SW)) != 0) {
                 tmp |= (1<<5);
@@ -205,7 +202,7 @@
         case 3:
             if (mode!=1) tmp = ((getADC(CONTROLLER4_SPEED) / CONTROLLER_DIVISOR) & 0x0F);
             if ((mode == 2) && (tmp != 0)) { jumpstart(controller); tmp = 0; }
-            if (tmp > speedlimit[controller]) tmp = speedlimit[controller];
+            if (tmp > slot[controller].speedlimit) tmp = slot[controller].speedlimit;
             tmp = tmp << 1;
             if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER4_SW)) != 0) {
                 tmp |= (1<<5);
@@ -275,8 +272,7 @@
     car0_old = TIMER1_500NS;
     car1_old = TIMER1_500NS;
 
-    sysclk.word[1]++; // increment 500ns timer low word
-    if (sysclk.word[1] == 0) sysclk.word[0]++; // increment upper 16bits
+    sysclk.value++; // increment 500ns timer
 }
 
 ISR ( TIMER2_COMP_vect ) {
@@ -391,12 +387,11 @@
 void reset_vars(void) {
     uint8_t i;
     for (i=0; i<MAX_SLOTS; i++) {
-        if (i<4) speedlimit[i] = 15; else speedlimit[i] = 0;
-        fuel[i] = 100;
-        jumpstart_time[i] = 0;
+        if (i<4) slot[i].speedlimit = 15; else slot[i].speedlimit = 0;
+        slot[i].fuel = 100;
+        slot[i].jumpstart_time = 0;
     }
-    sysclk.word[1] = 0;
-    sysclk.word[0] = 0;
+    sysclk.value = 0;
 }
 
 void countdown_progress(void) {
@@ -414,8 +409,7 @@
         case 2: LED(4, 1); break;
         case 1: LED(5, 1); break;
         case 0: { // RACE START!
-            sysclk.word[1] = 1;
-            sysclk.word[0] = 0;
+            sysclk.value = 0;
             LEDS_OFF();
             LED(3, 1);
             mode = 3;
@@ -424,26 +418,21 @@
 }
 
 void check_cars(void) {
-    uint16_t diff_low, diff_high;
+    u32 clk, diff;
+    clk.value = sysclk.value; // freeze system clock time
 
     if (car0 != car0_state) {
         car0_state = car0;
         if (car0_state != 0) {
-            diff_high = sysclk.word[0] - lap_time_start_high[car0-1];
-            diff_low = sysclk.word[1] - lap_time_start_low[car0-1]; // this could be a bug ;)
-            if ( (diff_high > 0) || (diff_low>2000) ) { // minimum 1 second for 1 lap!
-                lap_time_start_low[car0-1] = sysclk.word[1];
-                lap_time_start_high[car0-1] = sysclk.word[0];
-                lap_time_low[car0-1] = diff_low;
-                lap_time_high[car0-1] = diff_high;
+            diff.value = clk.value - slot[car0-1].lap_time_start.value;
+            if ( diff.value > 3000 ) { // minimum 1.5 second for 1 lap!
+                slot[car0-1].lap_time_start.value = clk.value;
+                slot[car0-1].lap_time.value = diff.value;
                 RS232_putc('L');
                 RS232_putc('A');
                 RS232_putc('0'+car0_state);
                 RS232_putc(':');
-                itoa(diff_high, s, 16);
-                RS232_puts(s);
-                RS232_putc(',');
-                itoa(diff_low, s, 16);
+                ultoa(diff.value, s, 16);
                 RS232_puts(s);
                 RS232_putc('\n');
             }
@@ -453,21 +442,15 @@
     if (car1 != car1_state) {
         car1_state = car1;
         if (car1_state != 0) {
-            diff_high = sysclk.word[0] - lap_time_start_high[car1-1];
-            diff_low = sysclk.word[1] - lap_time_start_low[car1-1]; // this could be a bug ;)
-            if ( (diff_high > 0) || (diff_low>2000) ) { // minimum 1 second for 1 lap!
-                lap_time_start_low[car1-1] = sysclk.word[1];
-                lap_time_start_high[car1-1] = sysclk.word[0];
-                lap_time_low[car1-1] = diff_low;
-                lap_time_high[car1-1] = diff_high;
+            diff.value = clk.value - slot[car1-1].lap_time_start.value;
+            if ( diff.value > 3000 ) { // minimum 1.5 second for 1 lap!
+                slot[car1-1].lap_time_start.value = clk.value;
+                slot[car1-1].lap_time.value = diff.value;
                 RS232_putc('L');
                 RS232_putc('B');
                 RS232_putc('0'+car1_state);
                 RS232_putc(':');
-                itoa(diff_high, s, 16);
-                RS232_puts(s);
-                RS232_putc(',');
-                itoa(diff_low, s, 16);
+                ultoa(diff.value, s, 16);
                 RS232_puts(s);
                 RS232_putc('\n');
             }
@@ -523,8 +506,7 @@
                     RS232_puts_p(prepare);
                 } else if (mode == 1) {
                     // Initiate race countdown
-                    sysclk.word[1] = 1;
-                    sysclk.word[0] = 0;
+                    sysclk.value = 0;
                     countdown = 5;
                     countdown_loops = COUNTDOWN_DELAY;
                     mode = 2;

mercurial