Dual CANbus monitor and instrumentation cluster supporting ILI9341 display controller

Dependencies:   SPI_TFTx2_ILI9341 TOUCH_TFTx2_ILI9341 TFT_fonts mbed

Fork of CANary by Tick Tock

Files at this revision

API Documentation at this revision

Comitter:
TickTock
Date:
Sun Mar 03 17:06:12 2013 +0000
Parent:
12:8e42d7ba8468
Child:
14:736a5e9650c5
Commit message:
More partitioning

Changed in this revision

common.h Show annotated file Show diff for this revision Revisions of this file
displayModes.cpp Show annotated file Show diff for this revision Revisions of this file
displayModes.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
utility.cpp Show annotated file Show diff for this revision Revisions of this file
utility.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common.h	Sun Mar 03 17:06:12 2013 +0000
@@ -0,0 +1,21 @@
+#define maxScreens 7
+#define offScreen 0
+#define logScreen 1
+#define dteScreen 2
+#define brakeScreen 3
+#define powerScreen 4
+#define monitorScreen 5
+#define changedScreen 6
+#define cpScreen 7
+#define upLine "\033[1A"
+#define maxBufLen 768
+#define canTimeout 500
+#define userTimeout 10
+#define btn31x1 12
+#define btn31x2 101
+#define btn32x1 115
+#define btn32x2 204
+#define btn33x1 218
+#define btn33x2 307
+#define btn11y1 180
+#define btn11y2 229
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/displayModes.cpp	Sun Mar 03 17:06:12 2013 +0000
@@ -0,0 +1,285 @@
+//displayModes.cpp
+
+#include "displayModes.h"
+
+void printLast (bool force){
+    CANMessage msg;
+    tt.locate(0,6);
+    tt.foreground(Red);
+    tt.background(Yellow);
+    if(force) tt.cls(); // Just clear screen if forced - always update display
+    tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
+    for(int i=0; i<19; i++){
+        msg = lastMsg[i+indexOffset];
+        printf("%03x : %02x %02x %02x %02x %02x %02x %02x %02x    \n",msg.id,msg.data[0],msg.data[1],msg.data[2],msg.data[3],msg.data[4],msg.data[5],msg.data[6],msg.data[7]);
+    }
+}
+
+void printChanged (bool force){
+    CANMessage msg;
+    unsigned char i,j;
+    tt.locate(0,6);
+    tt.foreground(Red);
+    tt.background(Yellow);
+    if(force) tt.cls(); // Just clear screen if forced - always update display
+    tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
+    i=0;
+    j=indexOffset;
+    do{
+        j=j<99?j+1:j;
+        if(msgChanged[j]>0){
+            msg = lastMsg[j];
+            printf("%03x : %02x %02x %02x %02x %02x %02x %02x %02x    \n",msg.id,msg.data[0],msg.data[1],msg.data[2],msg.data[3],msg.data[4],msg.data[5],msg.data[6],msg.data[7]);
+            i++;
+        }// if changed
+    }while(i<19&&j<99);
+}
+
+void printLog (bool force){
+    static unsigned char lastDisplayLoc = 0;
+    if(force||displayLoc!=lastDisplayLoc){ //only update if changed
+        tt.foreground(Amber);
+        tt.background(Black);
+        tt.cls();
+        tt.locate(0,6);
+        tt.set_font((unsigned char*) Arial12x12);
+        for(int i=0; i<19; i++){
+            printf("%s",displayLog[displayLoc]);
+            displayLoc=displayLoc>17?0:displayLoc+1;
+        }
+    }
+    lastDisplayLoc=displayLoc;
+}
+
+void printDTE (bool force){
+    unsigned short gids, SOC, packV;
+    static unsigned short lgids=0, lSOC=0, lpackV=0;
+    CANMessage msg;
+
+    msg = lastMsg[indexLastMsg[0x5bc]]; //Get gids
+    gids = (msg.data[0]<<2)+(msg.data[1]>>6);
+    msg = lastMsg[indexLastMsg[0x55b]]; //Get SOC
+    SOC = (msg.data[0]<<2)+(msg.data[1]>>6);
+    msg = lastMsg[indexLastMsg[0x1db]]; //Get pack volts
+    packV = (msg.data[2]<<2)+(msg.data[3]>>6);
+
+    tt.background(Navy);
+    if(force) tt.cls();
+    if(force||gids!=lgids){
+        tt.foreground(Amber);
+        tt.set_font((unsigned char*) Arial28x28);
+        tt.locate(10,10);
+        printf("%4d gids\n",gids);
+        tt.locate(10,200);
+        printf("%4.1f kWh\n",(float)gids*0.08);
+        tt.set_font((unsigned char*) SCProSB31x55);
+        //tt.set_font((unsigned char*) Neu42x35);
+        tt.foreground(Green);
+        tt.locate(60,96);
+        printf("%4.1f mi  \n",(float)(gids-5)*0.33); // Approx for now
+        lgids=gids;
+    }
+    if(force||SOC!=lSOC){
+        tt.foreground(Amber);
+        tt.set_font((unsigned char*) Arial28x28);
+        tt.locate(200,10);
+        printf("%4.1f%s\n",(float)SOC/10,"%");
+        lSOC=SOC;
+    }
+    if(force||packV!=lpackV){
+        tt.foreground(Amber);
+        tt.set_font((unsigned char*) Arial28x28);
+        tt.locate(200,200);
+        printf("%4.1fV\n",(float)packV/2);
+        lpackV=packV;
+    }
+}
+
+void braking (bool force, bool prdata){
+    unsigned short targetBraking, regenBraking, speed;
+    static unsigned short maxTarget = 0, maxRegen = 0, tarDivReg = 0;
+    short rpm;
+    unsigned long temp;
+    static unsigned char lastPressure[4] = {200,200,200,200};
+    unsigned char i,r,t;
+    static unsigned char lr, lt;
+    CANMessage msg;
+
+    msg = lastMsg[indexLastMsg[0x1cb]]; //Get Target and Regen
+    regenBraking = (msg.data[0]<<3)+(msg.data[1]>>5);
+    targetBraking = (msg.data[2]<<3)+(msg.data[3]>>5);
+    if (targetBraking>maxTarget) maxTarget=targetBraking;
+    if (regenBraking>maxRegen) maxRegen=regenBraking;
+    if (regenBraking>50) {
+        temp = 1000*targetBraking;
+        temp /= regenBraking;
+        if (temp>tarDivReg) tarDivReg=temp;
+    }
+    msg = lastMsg[indexLastMsg[0x176]]; //Get rpms - not sure what this is but scales to mph with .0725
+    rpm = ((short)msg.data[0]<<8)+msg.data[1];
+    speed =rpm>0?rpm>>3:-rpm>>3; //Take absolute to get speed; div8
+    msg = lastMsg[indexLastMsg[0x1ca]]; //Get brake pressure
+
+    tt.background(Navy);
+    if (force) {
+        tt.cls();
+        tt.rect(0,111,170,239,White);
+        tt.line(0,207,170,207,White);
+        tt.line(0,175,170,175,White);
+        tt.line(0,143,170,143,White);
+        lastPressure[0] = 200;
+        lastPressure[1] = 200;
+        lastPressure[2] = 200;
+        lastPressure[3] = 200;
+    }
+    // plot bar graph for each wheel pressure
+    for (i=0; i<4; i++){
+        if (msg.data[i]<239) {
+            if (msg.data[i]>lastPressure[i]){
+                tt.fillrect(10+40*i,239-msg.data[i],40+40*i,239,Red);
+            } else if (msg.data[i]<lastPressure[i]) {
+                tt.fillrect(10+40*i,238-lastPressure[i],40+40*i,238-msg.data[i],Navy);
+            }
+            lastPressure[i]=msg.data[i];
+        }
+    }
+
+    if(targetBraking>50){
+        targetBraking *= speed;
+        regenBraking *= speed;
+        temp = 200*targetBraking/maxTarget;
+        t = (char) temp;
+        temp = 200*regenBraking*tarDivReg/maxTarget;
+        r = (char) temp;
+        if(lr!=r&&prdata){
+            tt.foreground(Amber);
+            tt.set_font((unsigned char*) Arial28x28);
+            tt.locate(100,50);
+            printf("%d %d    \n",regenBraking,maxRegen);
+            tt.locate(100,90);
+            printf("%3.1f (%3.1f%s)    \n",(float)tarDivReg/1000,(float)regenBraking*tarDivReg/targetBraking/1000,"%");
+        }    
+        if(lt!=t&&prdata){
+            tt.foreground(Amber);
+            tt.set_font((unsigned char*) Arial28x28);
+            tt.locate(100,10);
+            printf("%d %d    \n",targetBraking,maxTarget);
+        }
+        if((lr!=r||lt!=t)&&!prdata){
+            if(r<lr)
+                tt.fillrect(200,239-lr,300,239-r,Red);
+            else
+                tt.fillrect(200,239-r,300,239,Green);
+            if(t<lt)
+                tt.fillrect(200,239-lt,300,239-t,Navy);
+            else
+                tt.fillrect(200,239-t,300,238-r,Red);
+            lt=t;
+            lr=r;
+        }
+    }
+}
+
+void cpData(bool force){
+    short unsigned max, min, jv, i, bd;
+    unsigned avg;
+    if(force){
+        tt.foreground(White);
+        tt.background(Navy);
+        tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
+        max=0;
+        min=9999;
+        avg=0;
+        for(i=0; i<96; i++){
+           bd=(battData[i*2+3]<<8)+battData[i*2+4];
+           avg+=bd;
+            if(bd>max) max=bd;
+            if(bd<min) min=bd;
+        }
+        avg /= 96;
+        if(min<3713) {
+            jv=avg-(max-avg)*1.5;
+        } else { // Only compute judgement value if min cellpair meets <= 3712mV requirement
+            jv=0;
+        }
+        tt.cls();
+        tt.locate(0,6);
+        printf(" MAX  MIN  AVG CVLI T1  T2  T3  T4\n %04d %04d %04d %04d %02dC %02dC %02dC %02dC\n\n",max,min,avg,jv,battData[224+5],battData[224+8],battData[224+11],battData[224+14]);
+        tt.locate(0,36);
+        for(i=0; i<16; i++){
+            printf("%02d-%02d : %04d %04d %04d %04d %04d %04d\n",i*6+1,i*6+6,(battData[i*12+3]<<8)+battData[i*12+4],(battData[i*12+5]<<8)+battData[i*12+6],(battData[i*12+7]<<8)+battData[i*12+8],(battData[i*12+9]<<8)+battData[i*12+10],(battData[i*12+11]<<8)+battData[i*12+12],(battData[i*12+13]<<8)+battData[i*12+14]);
+        }
+        tt.rect(8+0*41,16,40+0*41,28,Green);
+        tt.rect(8+1*41,16,40+1*41,28,Yellow);
+        //tt.rect(8+2*41,16,40+2*41,28,White);
+        tt.rect(8+3*41,16,40+3*41,28,Red);
+        for(i=0; i<96; i++){
+            bd=(battData[i*2+3]<<8)+battData[i*2+4];
+            if(bd>0){
+                if(bd==max) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Green);
+                //if(bd==avg) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,White);
+                if(bd==min) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Yellow);
+                if(bd<jv) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Red);
+            }
+        }
+        showCP=false;
+    }
+}
+
+void updateDisplay(char display){
+    bool changed;
+    changed = dMode[display]!=lastDMode[display];
+    tt.set_display(display);
+    switch (dMode[display]) {
+        case logScreen:
+            printLog(changed);
+            break;
+        case dteScreen:
+            printDTE(changed);
+            break;
+        case brakeScreen:
+            braking(changed,true);
+            break;
+        case powerScreen:
+            braking(changed,false);
+            break;
+        case monitorScreen:
+            printLast(changed);
+            break;
+        case changedScreen:
+            printChanged(changed);
+            break;
+        case cpScreen:
+            cpData(changed||showCP);
+            break;
+        default:
+            tt.background(Black);
+            tt.cls();
+            break;
+    }
+    lastDMode[display]=dMode[display];
+
+    switch (sMode) {
+        case 1:
+            tt.foreground(Yellow);
+            tt.background(DarkCyan);
+            tt.set_font((unsigned char*) Arial12x12);
+            tt.fillrect(btn31x1,btn11y1,btn31x2,btn11y2,DarkCyan);
+            tt.locate(btn31x1+5,btn11y1+5);
+            printf("<-Prev\n");
+            tt.fillrect(btn32x1,btn11y1,btn32x2,btn11y2,DarkCyan);
+            tt.fillrect(btn33x1,btn11y1,btn33x2,btn11y2,DarkCyan);
+            tt.locate(btn33x2-50,btn11y1+5);
+            printf("Next->\n");
+            tt.set_display(0);
+            tt.locate(btn32x1+15,btn11y1+5);
+            printf("Select %d\n",dMode[0]);
+            tt.set_display(1);
+            tt.locate(btn32x1+15,btn11y1+5);
+            printf("Select %d\n",dMode[1]);
+            tt.background(Black);
+            break;
+        default:
+            break;
+    }
+}
--- a/displayModes.h	Sun Mar 03 15:50:54 2013 +0000
+++ b/displayModes.h	Sun Mar 03 17:06:12 2013 +0000
@@ -1,295 +1,32 @@
 // This contains all the display subroutines
 
 #include "TOUCH_TFTx2.h"
-#include "SPI_TFTx2.h"
 #include "Arial12x12.h"
 #include "Arial12x12_prop.h"
 #include "Arial28x28.h"
 #include "Neu42x35.h"
 #include "SCProSB31x55.h"
+#include "common.h"
 
-TOUCH_TFTx2 tt(p16, p17, p19, p20, p11, p12, p13, p6, p7, p5, "TFT"); // x+,x-,y+,y-,mosi, miso, sclk, cs0, cs1, reset
+extern CANMessage lastMsg[100];
+extern unsigned char indexOffset;
+extern unsigned char msgChanged[100];
+extern char displayLog[20][40];
+extern unsigned char displayLoc;
+extern char indexLastMsg[0x800];
+extern unsigned char battData[256];
+extern bool showCP;
+extern unsigned char dMode[2];
+extern unsigned char lastDMode[2];
+extern unsigned char sMode;
+extern TOUCH_TFTx2 tt;
 
 extern "C" {
-    void printLast (bool force){
-        CANMessage msg;
-        tt.locate(0,6);
-        tt.foreground(Red);
-        tt.background(Yellow);
-        if(force) tt.cls(); // Just clear screen if forced - always update display
-        tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
-        for(int i=0; i<19; i++){
-            msg = lastMsg[i+indexOffset];
-            printf("%03x : %02x %02x %02x %02x %02x %02x %02x %02x    \n",msg.id,msg.data[0],msg.data[1],msg.data[2],msg.data[3],msg.data[4],msg.data[5],msg.data[6],msg.data[7]);
-        }
-    }
-    
-    void printChanged (bool force){
-        CANMessage msg;
-        unsigned char i,j;
-        tt.locate(0,6);
-        tt.foreground(Red);
-        tt.background(Yellow);
-        if(force) tt.cls(); // Just clear screen if forced - always update display
-        tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
-        i=0;
-        j=indexOffset;
-        do{
-            j=j<99?j+1:j;
-            if(msgChanged[j]>0){
-                msg = lastMsg[j];
-                printf("%03x : %02x %02x %02x %02x %02x %02x %02x %02x    \n",msg.id,msg.data[0],msg.data[1],msg.data[2],msg.data[3],msg.data[4],msg.data[5],msg.data[6],msg.data[7]);
-                i++;
-            }// if changed
-        }while(i<19&&j<99);
-    }
-    
-    void printLog (bool force){
-        static unsigned char lastDisplayLoc = 0;
-        if(force||displayLoc!=lastDisplayLoc){ //only update if changed
-            tt.foreground(Amber);
-            tt.background(Black);
-            tt.cls();
-            tt.locate(0,6);
-            tt.set_font((unsigned char*) Arial12x12);
-            for(int i=0; i<19; i++){
-                printf("%s",displayLog[displayLoc]);
-                displayLoc=displayLoc>17?0:displayLoc+1;
-            }
-        }
-        lastDisplayLoc=displayLoc;
-    }
-    
-    void printDTE (bool force){
-        unsigned short gids, SOC, packV;
-        static unsigned short lgids=0, lSOC=0, lpackV=0;
-        CANMessage msg;
-    
-        msg = lastMsg[indexLastMsg[0x5bc]]; //Get gids
-        gids = (msg.data[0]<<2)+(msg.data[1]>>6);
-        msg = lastMsg[indexLastMsg[0x55b]]; //Get SOC
-        SOC = (msg.data[0]<<2)+(msg.data[1]>>6);
-        msg = lastMsg[indexLastMsg[0x1db]]; //Get pack volts
-        packV = (msg.data[2]<<2)+(msg.data[3]>>6);
-    
-        tt.background(Navy);
-        if(force) tt.cls();
-        if(force||gids!=lgids){
-            tt.foreground(Amber);
-            tt.set_font((unsigned char*) Arial28x28);
-            tt.locate(10,10);
-            printf("%4d gids\n",gids);
-            tt.locate(10,200);
-            printf("%4.1f kWh\n",(float)gids*0.08);
-            tt.set_font((unsigned char*) SCProSB31x55);
-            //tt.set_font((unsigned char*) Neu42x35);
-            tt.foreground(Green);
-            tt.locate(60,96);
-            printf("%4.1f mi  \n",(float)(gids-5)*0.33); // Approx for now
-            lgids=gids;
-        }
-        if(force||SOC!=lSOC){
-            tt.foreground(Amber);
-            tt.set_font((unsigned char*) Arial28x28);
-            tt.locate(200,10);
-            printf("%4.1f%s\n",(float)SOC/10,"%");
-            lSOC=SOC;
-        }
-        if(force||packV!=lpackV){
-            tt.foreground(Amber);
-            tt.set_font((unsigned char*) Arial28x28);
-            tt.locate(200,200);
-            printf("%4.1fV\n",(float)packV/2);
-            lpackV=packV;
-        }
-    }
-    
-    void braking (bool force, bool prdata){
-        unsigned short targetBraking, regenBraking, speed;
-        static unsigned short maxTarget = 0, maxRegen = 0, tarDivReg = 0;
-        short rpm;
-        unsigned long temp;
-        static unsigned char lastPressure[4] = {200,200,200,200};
-        unsigned char i,r,t;
-        static unsigned char lr, lt;
-        CANMessage msg;
-    
-        msg = lastMsg[indexLastMsg[0x1cb]]; //Get Target and Regen
-        regenBraking = (msg.data[0]<<3)+(msg.data[1]>>5);
-        targetBraking = (msg.data[2]<<3)+(msg.data[3]>>5);
-        if (targetBraking>maxTarget) maxTarget=targetBraking;
-        if (regenBraking>maxRegen) maxRegen=regenBraking;
-        if (regenBraking>50) {
-            temp = 1000*targetBraking;
-            temp /= regenBraking;
-            if (temp>tarDivReg) tarDivReg=temp;
-        }
-        msg = lastMsg[indexLastMsg[0x176]]; //Get rpms - not sure what this is but scales to mph with .0725
-        rpm = ((short)msg.data[0]<<8)+msg.data[1];
-        speed =rpm>0?rpm>>3:-rpm>>3; //Take absolute to get speed; div8
-        msg = lastMsg[indexLastMsg[0x1ca]]; //Get brake pressure
-    
-        tt.background(Navy);
-        if (force) {
-            tt.cls();
-            tt.rect(0,111,170,239,White);
-            tt.line(0,207,170,207,White);
-            tt.line(0,175,170,175,White);
-            tt.line(0,143,170,143,White);
-            lastPressure[0] = 200;
-            lastPressure[1] = 200;
-            lastPressure[2] = 200;
-            lastPressure[3] = 200;
-        }
-        // plot bar graph for each wheel pressure
-        for (i=0; i<4; i++){
-            if (msg.data[i]<239) {
-                if (msg.data[i]>lastPressure[i]){
-                    tt.fillrect(10+40*i,239-msg.data[i],40+40*i,239,Red);
-                } else if (msg.data[i]<lastPressure[i]) {
-                    tt.fillrect(10+40*i,238-lastPressure[i],40+40*i,238-msg.data[i],Navy);
-                }
-                lastPressure[i]=msg.data[i];
-            }
-        }
-    
-        if(targetBraking>50){
-            targetBraking *= speed;
-            regenBraking *= speed;
-            temp = 200*targetBraking/maxTarget;
-            t = (char) temp;
-            temp = 200*regenBraking*tarDivReg/maxTarget;
-            r = (char) temp;
-            if(lr!=r&&prdata){
-                tt.foreground(Amber);
-                tt.set_font((unsigned char*) Arial28x28);
-                tt.locate(100,50);
-                printf("%d %d    \n",regenBraking,maxRegen);
-                tt.locate(100,90);
-                printf("%3.1f (%3.1f%s)    \n",(float)tarDivReg/1000,(float)regenBraking*tarDivReg/targetBraking/1000,"%");
-            }    
-            if(lt!=t&&prdata){
-                tt.foreground(Amber);
-                tt.set_font((unsigned char*) Arial28x28);
-                tt.locate(100,10);
-                printf("%d %d    \n",targetBraking,maxTarget);
-            }
-            if((lr!=r||lt!=t)&&!prdata){
-                if(r<lr)
-                    tt.fillrect(200,239-lr,300,239-r,Red);
-                else
-                    tt.fillrect(200,239-r,300,239,Green);
-                if(t<lt)
-                    tt.fillrect(200,239-lt,300,239-t,Navy);
-                else
-                    tt.fillrect(200,239-t,300,238-r,Red);
-                lt=t;
-                lr=r;
-            }
-        }
-    }
-    
-    void cpData(bool force){
-        short unsigned max, min, jv, i, bd;
-        unsigned avg;
-        if(force){
-            tt.foreground(White);
-            tt.background(Navy);
-            tt.set_font((unsigned char*) Arial12x12_prop);  // select the font
-            max=0;
-            min=9999;
-            avg=0;
-            for(i=0; i<96; i++){
-               bd=(battData[i*2+3]<<8)+battData[i*2+4];
-               avg+=bd;
-                if(bd>max) max=bd;
-                if(bd<min) min=bd;
-            }
-            avg /= 96;
-            if(min<3713) {
-                jv=avg-(max-avg)*1.5;
-            } else { // Only compute judgement value if min cellpair meets <= 3712mV requirement
-                jv=0;
-            }
-            tt.cls();
-            tt.locate(0,6);
-            printf(" MAX  MIN  AVG CVLI T1  T2  T3  T4\n %04d %04d %04d %04d %02dC %02dC %02dC %02dC\n\n",max,min,avg,jv,battData[224+5],battData[224+8],battData[224+11],battData[224+14]);
-            tt.locate(0,36);
-            for(i=0; i<16; i++){
-                printf("%02d-%02d : %04d %04d %04d %04d %04d %04d\n",i*6+1,i*6+6,(battData[i*12+3]<<8)+battData[i*12+4],(battData[i*12+5]<<8)+battData[i*12+6],(battData[i*12+7]<<8)+battData[i*12+8],(battData[i*12+9]<<8)+battData[i*12+10],(battData[i*12+11]<<8)+battData[i*12+12],(battData[i*12+13]<<8)+battData[i*12+14]);
-            }
-            tt.rect(8+0*41,16,40+0*41,28,Green);
-            tt.rect(8+1*41,16,40+1*41,28,Yellow);
-            //tt.rect(8+2*41,16,40+2*41,28,White);
-            tt.rect(8+3*41,16,40+3*41,28,Red);
-            for(i=0; i<96; i++){
-                bd=(battData[i*2+3]<<8)+battData[i*2+4];
-                if(bd>0){
-                    if(bd==max) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Green);
-                    //if(bd==avg) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,White);
-                    if(bd==min) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Yellow);
-                    if(bd<jv) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Red);
-                }
-            }
-            showCP=false;
-        }
-    }
-    
-    void updateDisplay(char display){
-        bool changed;
-        changed = dMode[display]!=lastDMode[display];
-        tt.set_display(display);
-        switch (dMode[display]) {
-            case logScreen:
-                printLog(changed);
-                break;
-            case dteScreen:
-                printDTE(changed);
-                break;
-            case brakeScreen:
-                braking(changed,true);
-                break;
-            case powerScreen:
-                braking(changed,false);
-                break;
-            case monitorScreen:
-                printLast(changed);
-                break;
-            case changedScreen:
-                printChanged(changed);
-                break;
-            case cpScreen:
-                cpData(changed||showCP);
-                break;
-            default:
-                tt.background(Black);
-                tt.cls();
-                break;
-        }
-        lastDMode[display]=dMode[display];
-    
-        switch (sMode) {
-            case 1:
-                tt.foreground(Yellow);
-                tt.background(DarkCyan);
-                tt.set_font((unsigned char*) Arial12x12);
-                tt.fillrect(btn31x1,btn11y1,btn31x2,btn11y2,DarkCyan);
-                tt.locate(btn31x1+5,btn11y1+5);
-                printf("<-Prev\n");
-                tt.fillrect(btn32x1,btn11y1,btn32x2,btn11y2,DarkCyan);
-                tt.fillrect(btn33x1,btn11y1,btn33x2,btn11y2,DarkCyan);
-                tt.locate(btn33x2-50,btn11y1+5);
-                printf("Next->\n");
-                tt.set_display(0);
-                tt.locate(btn32x1+15,btn11y1+5);
-                printf("Select %d\n",dMode[0]);
-                tt.set_display(1);
-                tt.locate(btn32x1+15,btn11y1+5);
-                printf("Select %d\n",dMode[1]);
-                tt.background(Black);
-                break;
-            default:
-                break;
-        }
-    }
+    void printLast (bool force);
+    void printChanged (bool force);
+    void printLog (bool force);
+    void printDTE (bool force);
+    void braking (bool force, bool prdata);
+    void cpData(bool force);
+    void updateDisplay(char display);
 }
\ No newline at end of file
--- a/main.cpp	Sun Mar 03 15:50:54 2013 +0000
+++ b/main.cpp	Sun Mar 03 17:06:12 2013 +0000
@@ -1,5 +1,5 @@
-//#include "utility.h"
-//#include "displayModes.h"
+// main.cpp
+
 //To Do:
 // * USB device detect
 // * config file on local fs with touchscreen calibration
@@ -10,6 +10,7 @@
 // * auto-poll option for cellpair data
 // * cellpair histogram
 // * 
+
 #include "mbed.h"
 #include "CAN.h"
 #include "beep.h"
@@ -19,6 +20,56 @@
 #include "utility.h"
 #include "displayModes.h"
 
+LocalFileSystem local("local");
+
+// to write to USB Flash Drives, or equivalent (SD card in Reader/Writer)
+MSCFileSystem fs("fs"); // to write to a USB Flash Drive
+
+time_t seconds ;
+Beep spkr(p21);
+
+Ticker ticker;
+Timer timer;
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+PwmOut dled(p24);
+
+InterruptIn touchpad(p17);
+CAN can1(p9, p10);      // CAN1 (EV) uses pins 9 and 10 (rx, tx) and pin 8 (rs)
+DigitalOut can1SleepMode(p8);     // Use pin 8 to control the sleep mode of can2
+CAN can2(p30, p29);     // CAN2 (CAR) uses pins 30 and 29 (rx, tx) and pin 28 (rs)
+DigitalOut can2SleepMode(p28);     // Use pin 28 to control the sleep mode of can1
+
+TOUCH_TFTx2 tt(p16, p17, p19, p20, p11, p12, p13, p6, p7, p5, "TFT"); // x+,x-,y+,y-,mosi, miso, sclk, cs0, cs1, reset
+
+bool logEn = true,logOpen = false;
+FILE *rfile;
+FILE *file;
+char fileName[35] = "" ;
+char writeBuffer[maxBufLen][13]; // buffer for USB write
+char indexLastMsg[0x800]={0}; // index table for last message
+CANMessage lastMsg[100]; // table to store last message of eachtype
+unsigned char battData[256]={0};
+unsigned char msgChanged[100]; // inidcates which bytes changed
+char c;
+volatile int writePointer = 0;
+volatile int secsNoMsg = 0, secsNoTouch = 0;
+volatile bool canIdle = false, userIdle = false;
+bool touched=0; //flag to read touchscreen
+char counter = 0;
+unsigned char dMode[2] = {7,2}; //display mode
+unsigned char sMode = 0; // setup mode
+unsigned char lastDMode[2] = {0,0}; //last screen mode
+char displayLog[20][40];
+unsigned char displayLoc = 0;
+unsigned char indexOffset = 1;
+bool showCP = false;
+bool pollCP = false;
+
 int main() {
     int readPointer=0;
     char sTemp[40];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utility.cpp	Sun Mar 03 17:06:12 2013 +0000
@@ -0,0 +1,177 @@
+// utility.cpp
+
+#include "utility.h"
+
+void mbed_reset();
+void RTC_IRQHandler() {
+    timer.reset(); // zero ms at the-seconds-tic
+    canIdle=(++secsNoMsg>canTimeout);
+    userIdle=(++secsNoTouch>userTimeout);
+    LPC_RTC->ILR |= (1<<0); // clear interrupt to prepare for next
+}
+
+extern "C" void RTC_Init (void) {
+    LPC_RTC->ILR=0x00; // set up the RTC interrupts
+    LPC_RTC->CIIR=0x01; // interrupts each second
+    LPC_RTC->CCR = 0x01;  // Clock enable
+    //NVIC_SetPriority( RTC_IRQn, 10 );
+    NVIC_EnableIRQ( RTC_IRQn );
+}
+
+void logMsg (char *msg) {
+    strcpy(displayLog[displayLoc],msg);
+    displayLoc=displayLoc>17?0:displayLoc+1;
+}
+
+void touch_ISR(){
+    LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF);
+    secsNoTouch = 0;
+    touched=true;
+}
+
+unsigned short getTimeStamp() {
+    unsigned short msec = timer.read_ms() ; // read ms from the timer
+    unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
+    unsigned short isecs = secs%60 ; // modulo 60 for 0-59 seconds from RTC
+    return ((isecs<<10)+msec) ; // return the two byte time stamp
+}
+
+void logCan (char mType, CANMessage canRXmsg) {
+    char sTemp[40];
+    unsigned short ts = getTimeStamp();
+    unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
+    static unsigned char ii = 0, lasti = 0; // indexindex
+    unsigned char changed,i;
+    static unsigned char bdi;
+    if(logOpen){
+        if(canRXmsg.id>0) {
+            writeBuffer[writePointer][0]=mType;
+            writeBuffer[writePointer][1]=((secs%60)<<2)+((ts&0x300)>>8);
+            writeBuffer[writePointer][2]=ts&0xff;
+            writeBuffer[writePointer][3]=canRXmsg.id&0xff;
+            writeBuffer[writePointer][4]=(canRXmsg.id>>8)+(canRXmsg.len<<4);
+            for(i=5;i<13;i++){
+                writeBuffer[writePointer][i]=canRXmsg.data[i-5];
+            }
+            if (++writePointer >= maxBufLen) {
+                writePointer = 0;
+                led3 = !led3;
+            }
+        }
+    }//if logOpen
+    if(indexLastMsg[canRXmsg.id]==0) { //Check if no entry
+        ii=ii<99?ii+1:0;
+        indexLastMsg[canRXmsg.id]=ii; //Create entry if first message
+    }
+    if(dMode[0]==changedScreen||dMode[1]==changedScreen){
+        changed=msgChanged[indexLastMsg[canRXmsg.id]];
+        for(i=0;i<8;i++){
+            if(lastMsg[indexLastMsg[canRXmsg.id]].data[i]!=canRXmsg.data[i]){
+                changed |= 1<<i;
+            }
+        }
+        msgChanged[indexLastMsg[canRXmsg.id]]=changed;
+    }
+    lastMsg[indexLastMsg[canRXmsg.id]]=canRXmsg; //Store in table
+    if(mType==1&&canRXmsg.id==0x7bb){ // is battery data?  Need to store all responses
+        if(canRXmsg.data[0]<0x20){
+            if(canRXmsg.data[3]==2){//cellpair data
+                bdi=0;
+                sprintf(sTemp,"Getting cell pair data\n");
+                logMsg(sTemp);
+           }else if(canRXmsg.data[3]==4){//temperature data
+                bdi=0x20;
+                sprintf(sTemp,"Getting temperature data\n");
+                logMsg(sTemp);
+            }else bdi=0;
+            lasti=0;
+        }
+        i=canRXmsg.data[0]&0x0f; //lower nibble of D0 is index
+        if(lasti>i){ //detect rolloever and offset index appropriately
+            bdi=0x10;
+        }
+        lasti=i; //remember the msb to detect rollover next time around
+        i+=bdi;
+        i*=7;
+        if(i<0xfa){
+            battData[i+0]=canRXmsg.data[1];
+            battData[i+1]=canRXmsg.data[2];
+            battData[i+2]=canRXmsg.data[3];
+            battData[i+3]=canRXmsg.data[4];
+            battData[i+4]=canRXmsg.data[5];
+            battData[i+5]=canRXmsg.data[6];
+            battData[i+6]=canRXmsg.data[7];
+        }
+    }//if 0x7bb
+}
+
+void logTS () {
+    CANMessage tsMsg;
+    unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
+    tsMsg.id=0xfff;
+    tsMsg.len=0xf;
+    tsMsg.data[0]=secs&0xff;
+    tsMsg.data[1]=(secs>>8)&0xff;
+    tsMsg.data[2]=(secs>>16)&0xff;
+    tsMsg.data[3]=secs>>24;
+    tsMsg.data[4]=0xff;
+    tsMsg.data[5]=0xff;
+    tsMsg.data[6]=0xff;
+    tsMsg.data[7]=0xff;
+    logCan(0,tsMsg);
+}
+
+void sendCPreq() {
+    char i;
+    char data[8] = {0x02, 0x21, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff};
+    can1.monitor(false); // set to active mode
+    can1SleepMode = 0; // enable TX
+    can1.write(CANMessage(0x79b, data, 8));
+    data[0]=0x30; //change to request next line message
+    data[1]=0x01;
+    data[2]=0x00;
+    for(i=0;i<27;i++){
+        wait_ms(16); //wait 16ms
+        can1.write(CANMessage(0x79b, data, 8));
+    }
+    can1SleepMode = 1; // disable TX
+    can1.monitor(true); // set to snoop mode
+}
+
+void sendTreq() {
+    char i;
+    char data[8] = {0x02, 0x21, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff};
+    can1.monitor(false); // set to active mode
+    can1SleepMode = 0; // enable TX
+    can1.write(CANMessage(0x79b, data, 8));
+    data[0]=0x30; //change to request next line message
+    data[1]=0x01;
+    data[2]=0x00;
+    for(i=0;i<2;i++){
+        wait_ms(16); //wait 16ms
+        can1.write(CANMessage(0x79b, data, 8));
+    }
+    can1SleepMode = 1; // disable TX
+    can1.monitor(true); // set to snoop mode
+}
+
+void tickerISR() {  //This is the ticker ISR for auto-polling
+    pollCP=true;    //Set a flag to do in main loop instead of here
+}                   //since ticker blocks other interrupts
+
+void recieve1() {
+    CANMessage msg1;
+    secsNoMsg=0; // reset deadman switch
+    can1.read(msg1);
+    logCan(1, msg1);
+    led1 = !led1;
+}
+
+void recieve2() {
+    CANMessage msg2;
+    secsNoMsg=0; // reset deadman switch
+    can2.read(msg2);
+    logCan(2, msg2);
+    led2 = !led2;
+}
+
--- a/utility.h	Sun Mar 03 15:50:54 2013 +0000
+++ b/utility.h	Sun Mar 03 17:06:12 2013 +0000
@@ -1,251 +1,44 @@
-// utility.cpp
+// utility.h
+
 #include "mbed.h"
 #include "CAN.h"
-#include "beep.h"
-#include "MSCFileSystem.h"
-#include "PowerControl.h"
-#include "EthernetPowerControl.h"
-
-#define upLine "\033[1A"
-#define maxBufLen 768
-#define canTimeout 500
-#define userTimeout 10
-#define btn31x1 12
-#define btn31x2 101
-#define btn32x1 115
-#define btn32x2 204
-#define btn33x1 218
-#define btn33x2 307
-#define btn11y1 180
-#define btn11y2 229
-#define maxScreens 7
-#define offScreen 0
-#define logScreen 1
-#define dteScreen 2
-#define brakeScreen 3
-#define powerScreen 4
-#define monitorScreen 5
-#define changedScreen 6
-#define cpScreen 7
-LocalFileSystem local("local");
-
-// to write to USB Flash Drives, or equivalent (SD card in Reader/Writer)
-MSCFileSystem fs("fs"); // to write to a USB Flash Drive
-
-time_t seconds ;
-Beep spkr(p21);
+#include "common.h"
 
-Ticker ticker;
-Timer timer;
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
-PwmOut dled(p24);
-
-InterruptIn touchpad(p17);
-CAN can1(p9, p10);      // CAN1 (EV) uses pins 9 and 10 (rx, tx) and pin 8 (rs)
-DigitalOut can1SleepMode(p8);     // Use pin 8 to control the sleep mode of can2
-CAN can2(p30, p29);     // CAN2 (CAR) uses pins 30 and 29 (rx, tx) and pin 28 (rs)
-DigitalOut can2SleepMode(p28);     // Use pin 28 to control the sleep mode of can1
-
-bool logEn = true,logOpen = false;
-FILE *rfile;
-FILE *file;
-char fileName[35] = "" ;
-char writeBuffer[maxBufLen][13]; // buffer for USB write
-char indexLastMsg[0x800]={0}; // index table for last message
-CANMessage lastMsg[100]; // table to store last message of eachtype
-unsigned char battData[256]={0};
-unsigned char msgChanged[100]; // inidcates which bytes changed
-char c;
-volatile int writePointer = 0;
-volatile int secsNoMsg = 0, secsNoTouch = 0;
-volatile bool canIdle = false, userIdle = false;
-bool touched=0; //flag to read touchscreen
-char counter = 0;
-unsigned char dMode[2] = {7,2}; //display mode
-unsigned char sMode = 0; // setup mode
-unsigned char lastDMode[2] = {0,0}; //last screen mode
-char displayLog[20][40];
-unsigned char displayLoc = 0;
-unsigned char indexOffset = 1;
-bool showCP = false;
-bool pollCP = false;
+extern Timer timer;
+extern volatile int secsNoMsg;
+extern volatile int secsNoTouch;
+extern volatile bool canIdle;
+extern volatile bool userIdle;
+extern char displayLog[20][40];
+extern unsigned char displayLoc;
+extern bool touched;
+extern bool logOpen;
+extern char writeBuffer[maxBufLen][13];
+extern volatile int writePointer;
+extern DigitalOut led1,led2,led3,led4;
+extern char indexLastMsg[0x800];
+extern unsigned char dMode[2];
+extern unsigned char msgChanged[100];
+extern unsigned char battData[256];
+extern CANMessage lastMsg[100];
+extern CAN can1,can2;
+extern DigitalOut can1SleepMode,can2SleepMode;
+extern bool pollCP;
 
 extern "C" {
     void mbed_reset();
-    void RTC_IRQHandler() {
-        timer.reset(); // zero ms at the-seconds-tic
-        canIdle=(++secsNoMsg>canTimeout);
-        userIdle=(++secsNoTouch>userTimeout);
-        LPC_RTC->ILR |= (1<<0); // clear interrupt to prepare for next
-    }
-    
-    extern "C" void RTC_Init (void) {
-        LPC_RTC->ILR=0x00; // set up the RTC interrupts
-        LPC_RTC->CIIR=0x01; // interrupts each second
-        LPC_RTC->CCR = 0x01;  // Clock enable
-        //NVIC_SetPriority( RTC_IRQn, 10 );
-        NVIC_EnableIRQ( RTC_IRQn );
-    }
-    
-    void logMsg (char *msg) {
-        strcpy(displayLog[displayLoc],msg);
-        displayLoc=displayLoc>17?0:displayLoc+1;
-    }
-    
-    void touch_ISR(){
-        LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF);
-        secsNoTouch = 0;
-        touched=true;
-    }
-    
-    unsigned short getTimeStamp() {
-        unsigned short msec = timer.read_ms() ; // read ms from the timer
-        unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
-        unsigned short isecs = secs%60 ; // modulo 60 for 0-59 seconds from RTC
-        return ((isecs<<10)+msec) ; // return the two byte time stamp
-    }
-    
-    void logCan (char mType, CANMessage canRXmsg) {
-        char sTemp[40];
-        unsigned short ts = getTimeStamp();
-        unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
-        static unsigned char ii = 0, lasti = 0; // indexindex
-        unsigned char changed,i;
-        static unsigned char bdi;
-        if(logOpen){
-            if(canRXmsg.id>0) {
-                writeBuffer[writePointer][0]=mType;
-                writeBuffer[writePointer][1]=((secs%60)<<2)+((ts&0x300)>>8);
-                writeBuffer[writePointer][2]=ts&0xff;
-                writeBuffer[writePointer][3]=canRXmsg.id&0xff;
-                writeBuffer[writePointer][4]=(canRXmsg.id>>8)+(canRXmsg.len<<4);
-                for(i=5;i<13;i++){
-                    writeBuffer[writePointer][i]=canRXmsg.data[i-5];
-                }
-                if (++writePointer >= maxBufLen) {
-                    writePointer = 0;
-                    led3 = !led3;
-                }
-            }
-        }//if logOpen
-        if(indexLastMsg[canRXmsg.id]==0) { //Check if no entry
-            ii=ii<99?ii+1:0;
-            indexLastMsg[canRXmsg.id]=ii; //Create entry if first message
-        }
-        if(dMode[0]==changedScreen||dMode[1]==changedScreen){
-            changed=msgChanged[indexLastMsg[canRXmsg.id]];
-            for(i=0;i<8;i++){
-                if(lastMsg[indexLastMsg[canRXmsg.id]].data[i]!=canRXmsg.data[i]){
-                    changed |= 1<<i;
-                }
-            }
-            msgChanged[indexLastMsg[canRXmsg.id]]=changed;
-        }
-        lastMsg[indexLastMsg[canRXmsg.id]]=canRXmsg; //Store in table
-        if(mType==1&&canRXmsg.id==0x7bb){ // is battery data?  Need to store all responses
-            if(canRXmsg.data[0]<0x20){
-                if(canRXmsg.data[3]==2){//cellpair data
-                    bdi=0;
-                    sprintf(sTemp,"Getting cell pair data\n");
-                    logMsg(sTemp);
-               }else if(canRXmsg.data[3]==4){//temperature data
-                    bdi=0x20;
-                    sprintf(sTemp,"Getting temperature data\n");
-                    logMsg(sTemp);
-                }else bdi=0;
-                lasti=0;
-            }
-            i=canRXmsg.data[0]&0x0f; //lower nibble of D0 is index
-            if(lasti>i){ //detect rolloever and offset index appropriately
-                bdi=0x10;
-            }
-            lasti=i; //remember the msb to detect rollover next time around
-            i+=bdi;
-            i*=7;
-            if(i<0xfa){
-                battData[i+0]=canRXmsg.data[1];
-                battData[i+1]=canRXmsg.data[2];
-                battData[i+2]=canRXmsg.data[3];
-                battData[i+3]=canRXmsg.data[4];
-                battData[i+4]=canRXmsg.data[5];
-                battData[i+5]=canRXmsg.data[6];
-                battData[i+6]=canRXmsg.data[7];
-            }
-        }//if 0x7bb
-    }
-    
-    void logTS () {
-        CANMessage tsMsg;
-        unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
-        tsMsg.id=0xfff;
-        tsMsg.len=0xf;
-        tsMsg.data[0]=secs&0xff;
-        tsMsg.data[1]=(secs>>8)&0xff;
-        tsMsg.data[2]=(secs>>16)&0xff;
-        tsMsg.data[3]=secs>>24;
-        tsMsg.data[4]=0xff;
-        tsMsg.data[5]=0xff;
-        tsMsg.data[6]=0xff;
-        tsMsg.data[7]=0xff;
-        logCan(0,tsMsg);
-    }
-    
-    void sendCPreq() {
-        char i;
-        char data[8] = {0x02, 0x21, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff};
-        can1.monitor(false); // set to active mode
-        can1SleepMode = 0; // enable TX
-        can1.write(CANMessage(0x79b, data, 8));
-        data[0]=0x30; //change to request next line message
-        data[1]=0x01;
-        data[2]=0x00;
-        for(i=0;i<27;i++){
-            wait_ms(16); //wait 16ms
-            can1.write(CANMessage(0x79b, data, 8));
-        }
-        can1SleepMode = 1; // disable TX
-        can1.monitor(true); // set to snoop mode
-    }
-    
-    void sendTreq() {
-        char i;
-        char data[8] = {0x02, 0x21, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff};
-        can1.monitor(false); // set to active mode
-        can1SleepMode = 0; // enable TX
-        can1.write(CANMessage(0x79b, data, 8));
-        data[0]=0x30; //change to request next line message
-        data[1]=0x01;
-        data[2]=0x00;
-        for(i=0;i<2;i++){
-            wait_ms(16); //wait 16ms
-            can1.write(CANMessage(0x79b, data, 8));
-        }
-        can1SleepMode = 1; // disable TX
-        can1.monitor(true); // set to snoop mode
-    }
-    
-    void tickerISR() {  //This is the ticker ISR for auto-polling
-        pollCP=true;    //Set a flag to do in main loop instead of here
-    }                   //since ticker blocks other interrupts
-    
-    void recieve1() {
-        CANMessage msg1;
-        secsNoMsg=0; // reset deadman switch
-        can1.read(msg1);
-        logCan(1, msg1);
-        led1 = !led1;
-    }
-    
-    void recieve2() {
-        CANMessage msg2;
-        secsNoMsg=0; // reset deadman switch
-        can2.read(msg2);
-        logCan(2, msg2);
-        led2 = !led2;
-    }
+    void RTC_IRQHandler();
+    void RTC_Init (void);    
+    void logMsg (char *msg);
+    void touch_ISR();
+    unsigned short getTimeStamp();
+    void logCan (char mType, CANMessage canRXmsg);
+    void logTS ();    
+    void sendCPreq();    
+    void sendTreq();    
+    void tickerISR();
+    void recieve1();
+    void recieve2();
 }
 
 //LEAF OBD