Dual CANbus monitor and instrumentation cluster

Dependencies:   SPI_TFTx2 TFT_fonts TOUCH_TFTx2 beep mbed

Fork of CANary by Tick Tock

Revision:
12:8e42d7ba8468
Child:
13:62e0f7f39ff5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utility.h	Sun Mar 03 15:50:54 2013 +0000
@@ -0,0 +1,319 @@
+// utility.cpp
+#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);
+
+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 "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;
+    }
+}
+
+//LEAF OBD
+//1:
+//2:
+//3:    AVCAN-L     White/Blue
+//4:    VSS-Shield
+//5:    VSS         Brown,White/Brown
+//6:    CARCAN-H    Green
+//7:
+//8:    12V-SW      Orange,White/Orange
+//9:
+//10:
+//11:   AVCAN-H     Blue
+//12:   EVCAN-L     White/Grey
+//13:   EVCAN-H     Grey
+//14:   CARCAN-L    White/Green
+//15:
+//16:   12V-AON     Red/Blue,Blue/Red
+
+//VP230
+//1:D   
+//2:GND 
+//3:VCC 
+//4:R   
+//5:Vref
+//6:CANL
+//7:CANH
+//8:RS
+
+//LPC1768
+//1:    VSS
+//2:        NC:VIN  (4.5-9V supply)
+//3:        NC:VB
+//4:        NC:nR
+//5:    SPI:CS0
+//6:    SPI:CS1
+//7:    SPI:Reset
+//8:    CAN1:Sleep -->  8:CAN1:RS
+//9:    CAN1:RX    -->  4:CAN1:R
+//10:   CAN1:TX    -->  1:CAN1:D
+//11:   SPI:MOSI
+//12:   SPI:MISO
+//13:   SPI:SCLK
+//14:       NC:Ain
+//15:   MON12V     -->  4K to 12V, 1K to VSS  (To be implemented)
+//16:   TOUCH_X+
+//17:   TOUCH_X-
+//18:       NC:Aout
+//19:   TOUCH_Y+
+//20:   TOUCH_Y-
+//21:   Spkr+
+//22:   Spkr-           (optional complimentary output for more volume)
+//23:       NC:pwm
+//24:       LED
+//25:       NC:pwm
+//26:       NC:pwm
+//27:       NC
+//28:   CAN2:Sleep -->  8:CAN2:RS
+//29:   CAN2:TX    -->  1:CAN2:D
+//30:   CAN2:RX    -->  4:CAN2:R
+//31:   USB_D+
+//32:   USB_D-
+//33:       NC:Eth_TD+
+//34:       NC:Eth_TD-
+//35:       NC:Eth_RD+
+//36:       NC:Eth_RD-
+//37:       NC:IF+
+//38:       NC:IF-
+//39:       NC:5Vout (only available when connected as USB device)
+//40:   VCC3.3
\ No newline at end of file