Dashboard firmware for FBR2012

Dependencies:   mbed TextLCD PinDetect

Files at this revision

API Documentation at this revision

Comitter:
intrinseca
Date:
Wed Oct 17 16:08:51 2012 +0000
Parent:
5:177520d43c87
Child:
7:78cb2263290a
Commit message:
Add CANComms

Changed in this revision

inc/CANComms.h Show annotated file Show diff for this revision Revisions of this file
inc/MSCANHeader.h Show annotated file Show diff for this revision Revisions of this file
inc/PCComms.h Show annotated file Show diff for this revision Revisions of this file
inc/State.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
src/CANComms.cpp Show annotated file Show diff for this revision Revisions of this file
src/MSCANHeader.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/CANComms.h	Wed Oct 17 16:08:51 2012 +0000
@@ -0,0 +1,23 @@
+#ifndef FBRDASH_CANCOMMS_H
+#define FBRDASH_CANCOMMS_H
+
+#include "mbed.h"
+#include "State.h"
+#include "Comms.h"
+
+class CANComms : public Comms
+{
+    public:
+        CANComms(State* _values);
+        virtual void send(char message);
+        
+    private:
+        Ticker* pollTicker;
+        Ticker* readTicker;
+        CAN* can;
+        
+        void receive();
+        void poll();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/MSCANHeader.h	Wed Oct 17 16:08:51 2012 +0000
@@ -0,0 +1,31 @@
+#ifndef FBRDASH_MSCANHEADER_H
+#define FBRDASH_MSCANHEADER_H
+
+#define MSCAN_CMD   0   //a command to set a variable on the receiving processor to the value in the subsequent data part of the message, or
+#define MSCAN_REQ   1   //a request for data, i.e., the value of a specific variable (and where to store the reply)
+#define MSCAN_RSP   2   //a push-type message in reply to the destination processor's request for a variable value, the requested values are in the data buffer (&CAN_RB_DSR0) in the received message,
+#define MSCAN_XSUB  3   //a message to this processor from device 1 to execute subroutine immediately here (set flag if can execute in main loop), or
+#define MSCAN_BURN  4   //a message to burn RAM data table into flash data table.
+
+#define MSCAN_ID_MS   0
+#define MSCAN_ID_DASH 1
+
+#define MSCAN_BLOCK_OUTPC   7
+
+class MSCANHeader
+{
+    public:
+        MSCANHeader();
+        MSCANHeader(char to, char from, char type, char block, short offset);
+        
+        void parse(int id);
+        int build();
+        
+        short var_offset;
+        char msg_type;
+        char from_id;
+        char to_id;
+        char var_blk;        
+};
+
+#endif
\ No newline at end of file
--- a/inc/PCComms.h	Sun Oct 14 21:09:49 2012 +0000
+++ b/inc/PCComms.h	Wed Oct 17 16:08:51 2012 +0000
@@ -12,7 +12,6 @@
         virtual void send(char message);
         
     private:
-        State* values;
         Serial* pc;
         
         void receive();
--- a/inc/State.h	Sun Oct 14 21:09:49 2012 +0000
+++ b/inc/State.h	Wed Oct 17 16:08:51 2012 +0000
@@ -4,7 +4,7 @@
 struct State
 {
     unsigned short int rpm;
-    unsigned char throttle_pos;
+    float throttle_pos;
     unsigned char manifold_pres;
     unsigned char air_temp;
     float coolant_temp;
--- a/main.cpp	Sun Oct 14 21:09:49 2012 +0000
+++ b/main.cpp	Wed Oct 17 16:08:51 2012 +0000
@@ -4,6 +4,7 @@
 #include "Menu.h"
 #include "Comms.h"
 #include "PCComms.h"
+#include "CANComms.h"
 #include "Gears.h"
 #include "LEDS.h"
 #include "bigchar.h"
@@ -39,76 +40,52 @@
 //Main car state structure
 State car;
 
-//Initialise CAN
-CAN can(p30, p29);
-
 //Classes for various parts of the firmware
 Menu dashMenu(&lcd, p16, p17, p12); //*LCD, OK, Left, Right
 PCComms pc(&car);
+CANComms *can;
 Gears gearButtons(p14, p13, p15, &car.gear, &pc); //Up, Neutral, Down, *Current Gear
 LEDS revs(leds);
 
 //Refresh the rev LEDs and warning LEDs
 void revRefresh()
 {
-    CANMessage msg;
     revs.refresh(car.rpm);
-    
-    if(car.voltage<12){
+
+    if(car.voltage < 12) {
         warn[0]=1;
-    }else{
+    } else {
         warn[0]=0;
     }
-    if(car.coolant_temp>110){
+    if(car.coolant_temp>110) {
         warn[1]=1;
-    }else{
+    } else {
         warn[1]=0;
     }
-    if(car.rpm==0 and car.gear!=0){
+    if(car.rpm==0 and car.gear!=0) {
         warn[2]=1;
-    }else{
+    } else {
         warn[2]=0;
     }
-    if(can.read(msg)) {
-        if(msg.id==100 and msg.len==8){
-            car.rpm = msg.data[0] + (msg.data[1] << 8);
-            car.throttle_pos = msg.data[2];
-            car.manifold_pres = msg.data[3];
-            car.air_temp = msg.data[4];
-            car.coolant_temp = msg.data[5];
-            car.lambda = msg.data[6];
-        }
-        else if(msg.id==200 and msg.len==8){
-            car.speed = msg.data[0];
-            car.accel_x = msg.data[1];
-            car.accel_y = msg.data[2];
-            car.gear = msg.data[3];
-            car.oil_temp = msg.data[4];
-            car.voltage = msg.data[5]/16.0;
-        } 
-    }
-
 }
 
 //Refresh the LCD
 void lcdRefresh()
 {
     //If menu off screen, display HUD
-    if(dashMenu.display == false)
-    {
+    if(dashMenu.display == false) {
         lcd.locate(0, 0);
-        lcd.printf("%3.0fC%5.1dRPM", car.coolant_temp, car.rpm);
+        lcd.printf("R:%-5.1d S:%-3d", car.rpm, car.speed);
         lcd.locate(0, 1);
-        lcd.printf("%2dMPH %3.1fV", car.speed, car.voltage);
-        
+        lcd.printf("%-4.1fV %-4.1f\xDF\x43", car.voltage, car.coolant_temp);
+
         write_bigchar(&lcd, 13, car.gear);
     }
     //Otherwise show menu
-    else
-    {
+    else {
         dashMenu.refresh();
-    }    
-    
+    }
+
     //Blink heartbeat
     heartbeat = !heartbeat;
 }
@@ -127,57 +104,36 @@
     lcd.printf("    FBR 2012");
     lcd.locate(0,1);
     lcd.printf(" Ready to drive");
-    int offset = 0;
-    int type=1;
-    int blk=7;
-    int from=1;
-    int to=0;
-    int id = offset*262144+type*32768+from*2048+to*128+blk*8;
-    CANMessage msg;
-    msg = CANMessage(id,0,8,CANData,CANExtended);
-    lcd.cls();
-    lcd.printf("%x",id);
-    can.reset();
-    if(can.write(msg)){
-    wait(0.01);
-    lcd.printf(" %d errors",can.tderror());
-    can.reset();
-    while(can.read(msg)==false){
-    wait(0.1);
-    }
-    wait(0.5);
-    lcd.printf(" %d errors",can.tderror());
-    }
+
     //Light up LEDs
-    for(int i = 0; i < LEDS::NUM_LEDS; i++)
-    {
+    for(int i = 0; i < LEDS::NUM_LEDS; i++) {
         leds[i] = true;
         if(i < 4)
             warn[i] = true;
-        wait(0.2);
+        wait(0.1);
     }
-    
+
     //Turn off LEDs
-    for(int i = LEDS::NUM_LEDS - 1; i >= 0; i--)
-    {
+    for(int i = LEDS::NUM_LEDS - 1; i >= 0; i--) {
         leds[i] = false;
         if(i < 4)
             warn[i] = false;
-        wait(0.2);
+        wait(0.1);
     }
-    
+
     lcd.cls();
 }
 
 int main()
-{   
-    //Initialise CAN
-    can.frequency(500000);
+{
+    printf("\n");
+    printf("FBRDash\n");
+
     //Initialise state
     car.rpm = 0;
     car.gear = 2;
     car.speed = 0;
-    car.coolant_temp = 0;    
+    car.coolant_temp = 0;
     car.throttle_pos = 0;
     car.manifold_pres = 0;
     car.air_temp = 0;
@@ -185,30 +141,31 @@
     car.accel_x = 0;
     car.accel_y = 0;
     car.oil_temp = 0;
-    car.voltage = 0;
+    car.voltage = 10.0;
 
     //Set up menu
     dashMenu.addItem<float>("Coolant Temp  ", "%12.1f\xDF\x43", &car.coolant_temp); // \xDF\x43 -> &#65533;C . Need code for C as otherwise it gets taken as hex digit.
     dashMenu.addItem<unsigned char>("Air Temp      ", "%12d\xDF\x43", &car.air_temp);
-    dashMenu.addItem<unsigned char>("Throttle Pos  ", "%13d\xDF", &car.throttle_pos);
+    dashMenu.addItem<float>("Throttle Pos  ", "%12.1fd\xDF", &car.throttle_pos);
     dashMenu.addItem<unsigned char>("Manifold Pres ", "%10d psi", &car.manifold_pres);
-    dashMenu.addItem<unsigned char>("Lambda        ", "%14d", &car.lambda);    
+    dashMenu.addItem<unsigned char>("Lambda        ", "%14d", &car.lambda);
     dashMenu.addItem<unsigned char>("Oil Temp      ", "%12d\xDF\x43", &car.oil_temp);
-    
+
     //Set up characters on LCS
     setup_bigchar(&lcd);
-    
+
     //Do bootup animation
     selfTest();
-    
+
     //Start refresh tickers
     lcdRefreshTicker.attach_us(&lcdRefresh, LCD_REFRESH_TIME);
     revRefreshTicker.attach_us(&revRefresh, REV_REFRESH_TIME);
     //increment.attach(&doIncrement, 0.0005);
+
+    can = new CANComms(&car);
     
     //Infinite loop - program is interrupt driven
-    while(true)
-    {
+    while(true) {
         __WFI();
     }
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/CANComms.cpp	Wed Oct 17 16:08:51 2012 +0000
@@ -0,0 +1,92 @@
+#include "CANComms.h"
+#include "mbed.h"
+#include "State.h"
+
+#include "MSCANHeader.h"
+
+CANComms::CANComms(State* _values) : Comms(_values)
+{
+    can = new CAN(p30, p29);
+    can->frequency(500000);
+    
+    pollTicker = new Ticker();
+    readTicker = new Ticker();
+    
+    pollTicker->attach(this, &CANComms::poll, 0.05);
+    readTicker->attach(this, &CANComms::receive, 0.025);
+}
+
+void CANComms::poll()
+{
+    char i;
+
+    //start 6, 22
+    //int ids[] = {0x00189838, 0x00589838};
+
+    short offsets[] = {6, 22};    
+    
+    MSCANHeader header(MSCAN_ID_MS, MSCAN_ID_DASH, MSCAN_REQ, MSCAN_BLOCK_OUTPC, 0);
+
+    for(i = 0; i < 2; i++)
+    {
+        header.var_offset = offsets[i];
+        CANMessage msg(header.build(), 0, 3, CANData, CANExtended);
+        
+        msg.data[0] = i; //Where to put the response - used when communicating between MS's to tell them where they wanted the data put
+        msg.data[1] = 0; //Offset into the table specified in data[0]
+        msg.data[2] = 8; //How many bytes of the source table we want
+        
+        /*printf("Polling %d\n", i);*/
+        
+        if(can->write(msg))
+        {
+        
+        }
+    }
+}
+
+void CANComms::send(char message)
+{
+    
+}
+
+void CANComms::receive()
+{   
+    float tps;
+    char block;
+    
+    CANMessage msg;
+    MSCANHeader header;
+
+    while(can->read(msg))
+    {
+        /*printf("CAN Message %08X %d %02X%02X%02X%02X%02X%02X%02X%02X\n", msg.id, msg.len, 
+            msg.data[0], 
+            msg.data[1],
+            msg.data[2],
+            msg.data[3],
+            msg.data[4],
+            msg.data[5],
+            msg.data[6],
+            msg.data[7]
+            );*/
+        
+        header.parse(msg.id);
+       
+        //printf("Processing data, block %d\n", block);
+        
+        if(header.var_blk == 0)
+        {
+            values->rpm = (msg.data[0] << 8) | msg.data[1];
+        }
+        else
+        {
+            values->coolant_temp = (((msg.data[0] << 8) | msg.data[1]) - 320.0) * 0.05555;
+            values->throttle_pos = ((msg.data[2] << 8) | msg.data[3]) / 10.0;
+            values->voltage = ((msg.data[4] << 8) | msg.data[5]) / 10.0;
+            printf("TPS: %f\n", values->throttle_pos);
+        }
+        
+        //printf("Bat: %f\n", battery / 10.0);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/MSCANHeader.cpp	Wed Oct 17 16:08:51 2012 +0000
@@ -0,0 +1,48 @@
+#include "MSCANHeader.h"
+
+MSCANHeader::MSCANHeader()
+{
+
+}
+
+MSCANHeader::MSCANHeader(char to, char from, char type, char block, short offset)
+{
+    to_id = to;
+    from_id = from;
+    msg_type = type;
+    var_blk = block;
+    var_offset = offset;
+}
+
+//MS encodes most of the request params in the message ID.
+//Alignment is weird because the ID really includes some non-data bits. MS worked round these, mBed just skips them
+
+//0-2   3 bits Spare on MSII
+//3-6   4 bits Block to get data from. 7 = outpc, all the stuff that MS sends to the PC via serial
+//7-10  4 bits To ID - 0 for MS
+//11-14 4 bits From ID - Using 3 here for no good reason
+//15-17 3 bits Message type. 1 to get data, response has 2
+//18-28 11 bits Offset into the block in bits 3-6. Look in the INI file for Tuner Studio to find these, 
+//              [OutputChannels] section starting line 3036
+
+void MSCANHeader::parse(int id)
+{
+    var_offset = (id & 0x1FFC0000) >> 18;
+    msg_type =   (id & 0x00038000) >> 15;
+    from_id =    (id & 0x00007800) >> 11;
+    to_id =      (id & 0x00000780) >> 7;
+    var_blk =    (id & 0x00000078) >> 3;
+}
+
+int MSCANHeader::build()
+{
+    int id = 0;
+    
+    id |= (var_offset & 0x7FF)  << 18;
+    id |= (msg_type & 0x7)      << 15;
+    id |= (from_id & 0xF)       << 11;
+    id |= (to_id & 0xF)         << 7;
+    id |= (var_blk & 0xF)       << 3;
+    
+    return id;
+}
\ No newline at end of file