switched firmware to binary protocol, TODO: client implementation

Tue, 25 Jun 2013 23:52:29 +0200

author
Malte Bayer <mbayer@neo-soft.org>
date
Tue, 25 Jun 2013 23:52:29 +0200
changeset 139
7127e7082ee0
parent 138
a570dd24a413
child 140
f910ad6ed0b6

switched firmware to binary protocol, TODO: client implementation

blackbox/Makefile file | annotate | diff | comparison | revisions
blackbox/main.c file | annotate | diff | comparison | revisions
blackbox/main.h file | annotate | diff | comparison | revisions
slotUI/freeslot.py file | annotate | diff | comparison | revisions
slotUI/slotCli.py file | annotate | diff | comparison | revisions
--- a/blackbox/Makefile	Tue Jun 25 22:18:17 2013 +0200
+++ b/blackbox/Makefile	Tue Jun 25 23:52:29 2013 +0200
@@ -9,8 +9,10 @@
 #F_CPU = 14318000
 
 F_CPU = 8000000
+#F_CPU = 16000000
 
-BAUD=57600
+#BAUD=57600
+BAUD=33600
 ISP_BAUD=115200
 ifdef USB
 PORT=/dev/ttyUSB$(USB)
--- a/blackbox/main.c	Tue Jun 25 22:18:17 2013 +0200
+++ b/blackbox/main.c	Tue Jun 25 23:52:29 2013 +0200
@@ -15,12 +15,13 @@
 
 const char ok[]               PROGMEM="OK\n";
 const char busy[]             PROGMEM="BUSY\n";
-const char prepare[]          PROGMEM="!RACE PREPARE\n";
-const char countdownstart[]   PROGMEM="!COUNTDOWN\n";
-const char racestart[]        PROGMEM="!RACE START\n";
 
-const char SHORTCUT[]         PROGMEM="!SHORTCUT\n";
-const char PANIC[]            PROGMEM="!PANIC\n";
+const char prepare[]          PROGMEM="!PRE\n";
+const char countdownstart[]   PROGMEM="!SET\n";
+const char racestart[]        PROGMEM="!GO\n";
+
+const char SHORTCUT[]         PROGMEM="!OC\n";
+const char PANIC[]            PROGMEM="!STOP\n";
 const char RESUME[]           PROGMEM="!RESUME\n";
 
 typedef union {
@@ -29,6 +30,11 @@
     uint8_t  byte[4]; // all four bytes
 } u32;
 
+typedef union {
+    uint16_t value;
+    uint8_t  byte[2]; // all two bytes
+} u16;
+
 #define FUEL_FULL       10000
 #define FUEL_JUMPSTART  5000
 #define FUEL_DIV_DEFAULT 25
@@ -48,7 +54,7 @@
     unsigned unlimitedfuel:1; // 1bit bool
     unsigned trackchange:1; // 1bit bool
     uint16_t jumpstart_time, fuel;
-    uint8_t laps;
+    uint16_t laps;
     u32 lap_time_start, lap_time;
 } cardata;
 
@@ -165,6 +171,8 @@
         if (status == 6) for (data=0; data<MAX_SLOTS; data++) slot[data].canrefuel = 0;
         if (status == 7) slot[car].canrefuel = 0;
     }
+
+    /* Old ASCII Format:
     RS232_puts("RW:");
     RS232_putc(car + '0');
     RS232_putc(':');
@@ -179,6 +187,20 @@
     ultoa(sysclk.value, s, 16);
     RS232_puts(s);
     RS232_putc('\n');
+    */
+
+    // New binary protocol: TODO: compress sender & status, car & type
+    RS232_puts("RW:\n");
+    RS232_putc(8); // 8 binary bytes following
+    RS232_putc(car);
+    RS232_putc(type);
+    RS232_putc(sender);
+    RS232_putc(status);
+    RS232_putc(sysclk.byte[3]);
+    RS232_putc(sysclk.byte[2]);
+    RS232_putc(sysclk.byte[1]);
+    RS232_putc(sysclk.byte[0]);
+    RS232_putc('\n');
 }
 
 int insert_queue(uint16_t tmp, uint8_t len) {
@@ -218,6 +240,7 @@
 
 ISR ( USART_RXC_vect ) {
     uint8_t tmp;
+    u16 fuel, jumpstart_time;
     char c = UDR;
 
     // check for buffer overflow
@@ -302,7 +325,7 @@
                 case '+': // toggle panic mode
                     RS232_puts_p(ok);
                     if (mode != 0xff) {
-                        mode = 0xff; 
+                        mode = 0xff;
                         RS232_puts_p(PANIC);
                     } else {
                         mode = 0;
@@ -311,24 +334,21 @@
                     break;
 
                 case 'I': // get Information data (incl. important global parameter dump)
+                    // New binary protocol:
+                    RS232_puts("V:");
                     RS232_puts(VERSION);
-                    RS232_putc(':');
-                    for (tmp=0;tmp<MAX_SLOTS;tmp++) RS232_putc(slot[tmp].speedlimit); // output speed limits
-                    RS232_putc(':');
-                    for (tmp=0;tmp<MAX_SLOTS;tmp++) RS232_putc(slot[tmp].speedminimum); // output minimum speed
-                    RS232_putc(':');
+                    RS232_puts(":\n");
+                    RS232_putc(6 * MAX_SLOTS); // binary bytes following
                     for (tmp=0;tmp<MAX_SLOTS;tmp++) {
-                        itoa(slot[tmp].fuel, s, 16);
-                        RS232_putc(s); // output fuel levels (0=empty, 100=full, 0xff=no fuel option)
-                        RS232_putc(',');
+                        fuel.value = slot[tmp].fuel;
+                        jumpstart_time.value = slot[tmp].jumpstart_time;
+                        RS232_putc(slot[tmp].speedlimit); // output speed limits
+                        RS232_putc(slot[tmp].speedminimum); // output minimum speed
+                        RS232_putc(fuel.byte[1]); // output fuel levels (0=empty, 100=full, 0xff=no fuel option)
+                        RS232_putc(fuel.byte[0]); // output fuel levels (0=empty, 100=full, 0xff=no fuel option)
+                        RS232_putc(jumpstart_time.byte[1]); // output jumpstart times
+                        RS232_putc(jumpstart_time.byte[0]); // output jumpstart times
                     }
-                    RS232_putc(':');
-                    for (tmp=0;tmp<MAX_SLOTS;tmp++) {
-                        itoa(slot[tmp].jumpstart_time, s, 16);
-                        RS232_puts(s); // output jumpstart times
-                        RS232_putc(',');
-                    }
-                    RS232_putc(':');
                     RS232_putc('\n');
                     break;
 
@@ -483,7 +503,7 @@
         if (slot[4].speedminimum != 0) tmp |= 0b10000101;
         if (slot[5].speedminimum != 0) tmp |= 0b10000011;
     }
-    // todo: wenn Daten enpfangen wurden hier eine Quittierung senden anstatt dem Active Word
+    // TODO: wenn Daten enpfangen wurden hier eine Quittierung senden anstatt dem Active Word
 
     return insert_queue(tmp, 7);
 }
@@ -545,6 +565,7 @@
 
 void check_cars(void) {
     u32 clk, diff;
+    u16 laps;
     clk.value = sysclk.value; // freeze system clock time
 
     if (car0 != car0_state) {
@@ -555,17 +576,21 @@
                 if (slot[car0-1].lap_time_start.value != 0) {
                     slot[car0-1].lap_time.value = diff.value;
                     slot[car0-1].laps++;
-                    RS232_puts("L:3:"); // 3 = BB
-                    itoa(slot[car0-1].laps, s, 16);
-                    RS232_puts(s);
-                    RS232_putc(':');
-                    RS232_putc('0'+car0_state);
-                    RS232_putc(':');
-                    ultoa(diff.value, s, 16);
-                    RS232_puts(s);
-                    RS232_putc(':');
-                    ultoa(clk.value, s, 16);
-                    RS232_puts(s);
+                    laps.value = slot[car0-1].laps;
+                    // New binary protocol:
+                    RS232_puts("L:3:\n"); // 3 = BB
+                    RS232_putc(11); // binary bytes following
+                    RS232_putc(laps.byte[1]);
+                    RS232_putc(laps.byte[0]);
+                    RS232_putc(car0_state); // slot number
+                    RS232_putc(diff.byte[3]);
+                    RS232_putc(diff.byte[2]);
+                    RS232_putc(diff.byte[1]);
+                    RS232_putc(diff.byte[0]);
+                    RS232_putc(sysclk.byte[3]);
+                    RS232_putc(sysclk.byte[2]);
+                    RS232_putc(sysclk.byte[1]);
+                    RS232_putc(sysclk.byte[0]);
                     RS232_putc('\n');
                 }
                 slot[car0-1].lap_time_start.value = clk.value;
@@ -582,17 +607,21 @@
                 if (slot[car1-1].lap_time_start.value != 0) {
                     slot[car1-1].lap_time.value = diff.value;
                     slot[car1-1].laps++;
-                    RS232_puts("L:1:"); // 1 = AA
-                    itoa(slot[car1-1].laps, s, 16);
-                    RS232_puts(s);
-                    RS232_putc(':');
-                    RS232_putc('0'+car1_state);
-                    RS232_putc(':');
-                    ultoa(diff.value, s, 16);
-                    RS232_puts(s);
-                    RS232_putc(':');
-                    ultoa(clk.value, s, 16);
-                    RS232_puts(s);
+                    laps.value = slot[car1-1].laps;
+                    // New binary protocol:
+                    RS232_puts("L:1:\n"); // 1 = AA
+                    RS232_putc(11); // binary bytes following
+                    RS232_putc(laps.byte[1]);
+                    RS232_putc(laps.byte[0]);
+                    RS232_putc(car1_state); // slot number
+                    RS232_putc(diff.byte[3]);
+                    RS232_putc(diff.byte[2]);
+                    RS232_putc(diff.byte[1]);
+                    RS232_putc(diff.byte[0]);
+                    RS232_putc(sysclk.byte[3]);
+                    RS232_putc(sysclk.byte[2]);
+                    RS232_putc(sysclk.byte[1]);
+                    RS232_putc(sysclk.byte[0]);
                     RS232_putc('\n');
                 }
                 slot[car1-1].lap_time_start.value = clk.value;
@@ -604,25 +633,29 @@
 
 void slot_liveinfo(uint8_t idx) {
     if (switches.liveinfo == 0) return;
+    u16 fuel;
 
     if (switches.liveinfo == 1) {
         // increment packet counter, if == 10 output some live info
         if (slot[idx].seccnt == 10) {
             // output current fuel status
-            RS232_putc('F');
-            RS232_putc(':');
-            RS232_putc(idx + '0');
-            RS232_putc(':');
-            itoa(slot[idx].fuel, s, 16);
-            RS232_puts(s);
-            RS232_putc(':');
-            ultoa(sysclk.value, s, 16);
-            RS232_puts(s);
+            fuel.value = slot[idx].fuel;
+            // new Binary protocol:
+            RS232_puts("F:\n");
+            RS232_putc(7); // binary bytes following
+            RS232_putc(idx); // slot
+            RS232_putc(fuel.byte[1]);
+            RS232_putc(fuel.byte[0]);
+            RS232_putc(sysclk.byte[3]);
+            RS232_putc(sysclk.byte[2]);
+            RS232_putc(sysclk.byte[1]);
+            RS232_putc(sysclk.byte[0]);
             RS232_putc('\n');
             slot[idx].seccnt = 0;
         } else slot[idx].seccnt++;
     } else if ( (switches.liveinfo - 2) == idx ) {
             // output controller status LIVEINFO-2 for remote learning
+            // TODO: old ascii protocol
             RS232_putc('L');
             RS232_putc('N');
             RS232_putc(':');
@@ -658,7 +691,8 @@
         while (mode == 0xff) panic_mode();
 
         if (response_len > 0) {
-            itoa(response, s, 2);
+            //TODO: Track response data???
+            //itoa(response, s, 2);
             response_len = 0;
             //RS232_puts("ANSWER RX: ");
             //RS232_puts(s);
--- a/blackbox/main.h	Tue Jun 25 22:18:17 2013 +0200
+++ b/blackbox/main.h	Tue Jun 25 23:52:29 2013 +0200
@@ -4,7 +4,7 @@
 #include <avr/wdt.h>
 #include <stdint.h>
 
-#define VERSION "1.8"
+#define VERSION "1.8.2"
 
 #define COUNTDOWN_DELAY         10 // x/10 seconds
 
@@ -93,7 +93,7 @@
 #define PIN(x) (*(&x - 2))      // address of input register of port x
 
 
-// constants
+// constants, do not change this
 #define MAX_SLOTS       6
 
 // external variabled
--- a/slotUI/freeslot.py	Tue Jun 25 22:18:17 2013 +0200
+++ b/slotUI/freeslot.py	Tue Jun 25 23:52:29 2013 +0200
@@ -67,6 +67,8 @@
         self.info = None
 
     def readline(self):
+        # TODO: Binärprotokoll implementieren und als "alte" ASCII Antwort zurückgeben!
+        #
         if self.com:
             return self.com.readline()
         return ""
@@ -76,7 +78,8 @@
             return self.com.query(msg)
         return ""
 
-    def connect(self, device="/dev/ttyUSB0", speed=57600):
+    def connect(self, device="/dev/ttyUSB0", speed=33600):
+        # old connection speed 57600
         if self.com == None:
             self.com = SerialCommunicator(device, speed)
         if self.com.connected:
--- a/slotUI/slotCli.py	Tue Jun 25 22:18:17 2013 +0200
+++ b/slotUI/slotCli.py	Tue Jun 25 23:52:29 2013 +0200
@@ -20,7 +20,7 @@
 import threading
 
 
-VERSION = "1.8.1"
+VERSION = "1.8.2"
 MAXSLOTS = 6
 TERM = {
     "caption": "\033[1;37m\033[1;44m",
@@ -607,7 +607,7 @@
 
                         self.render_slots()
 
-                    if rx == "!RACE PREPARE":
+                    if rx == "!PRE":
                         # reset current race status
                         # and display PREPARE PHASE
                         self.reset_slots()
@@ -615,29 +615,30 @@
                             self.slot[slot]["status"] = "Prepare"
                         trigger_event("race_prepare")
 
-                    if rx == "!RACE START":
+                    if rx == "!GO":
+                        # race start!
                         for slot in range(MAXSLOTS):
                             if self.slot[slot]["status"] == "~~~~~~~~~~":
                                 self.slot[slot]["status"] = "Idle"
                         trigger_event("race_start")
                         self.raceactive = True
 
-                    if rx == "!COUNTDOWN":
+                    if rx == "!SET":
                         # countdown initiated
                         for slot in range(MAXSLOTS):
                             self.slot[slot]["status"] = "~~~~~~~~~~"
                         trigger_event("countdown_start")
 
-                    if rx == "!PANIC":
-                        # panic mode
+                    if rx == "!STOP":
+                        # panic mode, race stopped
                         trigger_event("panic")
 
-                    if rx == "!SHORTCUT":
-                        # panic mode
+                    if rx == "!OC":
+                        # panic mode, overcurrent
                         trigger_event("panic_shortcut")
 
                     if rx == "!RESUME":
-                        # panic mode
+                        # panic mode reset - race goes on normally
                         trigger_event("resume")
 
 

mercurial