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

Revision:
83:52b1f330a62d
Parent:
81:cf009a64eedd
Child:
85:5c27e88b3fbe
--- a/utility.cpp	Tue Apr 16 21:55:41 2013 +0000
+++ b/utility.cpp	Wed Apr 17 11:48:10 2013 +0000
@@ -38,272 +38,122 @@
     return ((isecs<<10)+msec) ; // return the two byte time stamp
 }
 
-//------------------------------------
-// gg - logcan
 void logCan (char mType, CANMessage canRXmsg) {
-   // re-arranged to put static first
-    static unsigned char ii = 0;
-    static unsigned char lasti = 0; // indexindex
+    char sTemp[40];    
+    unsigned short ts = getTimeStamp();
+    static unsigned char ii = 0, lasti = 0; // indexindex
+    unsigned char changed,i;
     static unsigned char bdi=0;
-    static signed short imotorRPM = 0;
-    static unsigned short nLost = 0; // gg - overrun
-
-    char sTemp[40];    
-    unsigned char changed,i;
-    unsigned char ij;
     signed short packV;
     signed short packA;
+    static signed short imotorRPM = 0;
     signed long imWs_x4;
     
-    unsigned short ts = getTimeStamp();
     secsNoMsg=0; // reset deadman switch
-    
     if(logOpen){
         if(canRXmsg.id>0) {
-            // check to see if buffer is already full (read - write) = 1
-            // actually the last buffer location cannot be used because then 
-            //   the buffer would look empty after writePointer++
-            
-            //if (((writePointer+maxBufLen-readPointer)%maxBufLen)>(maxBufLen/16)) // modulo is slow?
-
-            // maxBufLen = 512, so pointers are 0 through 511
-            if( (readPointer - writePointer) == 1 || (writePointer - readPointer) == (maxBufLen - 1)) {
-                // the buffer is "full", so Lose this message
-                
-                // point to the last-stored message
-                int tempWritePointer = writePointer - 1 ;
-                if( tempWritePointer == -1 ) tempWritePointer = maxBufLen - 1;
-                char strLost[9] ;
-
-                if( nLost == 0 ) {
-                    // this is the first message lost 
-                    //   and we must overwrite the last message with an FFE comment message
-                    // So, there will be two messages lost as the comment message is laid in.
-                    nLost = 2;
-                    sprintf(strLost,"%s","Lost0002"); // indicate two messages lost
-                    
-                    // overlay the last message with a "Lost0002" comment
-                    writeBuffer[tempWritePointer][0]=0;
-                    writeBuffer[tempWritePointer][1]=(ts&0xff00)>>8; // Time Stamp (2 bytes_
-                    writeBuffer[tempWritePointer][2]=(ts&0x00ff);
-                    writeBuffer[tempWritePointer][3]=0xfe; // MsgID, low byte
-                    writeBuffer[tempWritePointer][4]=0xff; // Len nibble, and MsgID high nibble
-                        
-                    for(i=5;i<13;i++){ 
-                        writeBuffer[tempWritePointer][i]= strLost[i-5];
-                    }
-                } else {
-                    // increment the loat counter
-                    nLost += 1;
-                    
-                    // lay the new count into the comment
-                    sprintf(strLost,"%04d",nLost);
-                    for(i=9;i<13;i++){ 
-                        writeBuffer[tempWritePointer][i]= strLost[i-9];
-                    }
-                }
-            } else {
-                // is room to insert the message
-                // get it inserted quickly
-                writeBuffer[writePointer][0]=mType;
-                writeBuffer[writePointer][1]=(ts&0xff00)>>8; // Time Stamp (2 bytes_
-                writeBuffer[writePointer][2]=(ts&0x00ff);
-                writeBuffer[writePointer][3]=canRXmsg.id&0xff; // MsgID, low byte
-                writeBuffer[writePointer][4]=(canRXmsg.id>>8)+(canRXmsg.len<<4); // Len nibble, and MsgID high nibble
-                for(i=5;i<13;i++){ // Is there a better way to do this? (writeBuffer[writePointer][i]=canRXmsg.data?)
-                    writeBuffer[writePointer][i]=canRXmsg.data[i-5];
-                }
-                //--------------
-                // force unused data bytes to FF for CAN-Do compatibility - gg - force FF
-                if(canRXmsg.len < 8){
-                    for(i=canRXmsg.len; i<8; i++) {
-                        writeBuffer[writePointer][i+5]=0xFF;
-                    }
-                }
-                //--------------
-                // note, this is not protected from the interrupt
-                // due to the nLost code above, this no longer
-                //    overflows to writePointer = readPointer
-                //    which would make the buffer look empty
-                if (++writePointer >= maxBufLen) {
-                    writePointer = 0;
-                    led3 = !led3;
-                }
-                //--------------
-                // log a local message if we had lost messages. gg - logcan
-                if( nLost > 0 ) {
-                    // We previously lost messages that did not get into the buffer
-                    sprintf(sTemp,"-- Write Buffer Lost [%d]\n", nLost);
-                    logMsg(sTemp); // write buffer overrun
-                    spkr.beep(500,0.25);
-                    
-                    nLost = 0 ;
-                }
-                //--------------
+            writeBuffer[writePointer][0]=mType;
+            writeBuffer[writePointer][1]=(ts&0xff00)>>8;
+            writeBuffer[writePointer][2]=(ts&0x00ff);
+            writeBuffer[writePointer][3]=canRXmsg.id&0xff;
+            writeBuffer[writePointer][4]=(canRXmsg.id>>8)+(canRXmsg.len<<4);
+            for(i=5;i<13;i++){ // Is there a better way to do this? (writeBuffer[writePointer][i]=canRXmsg.data?)
+                writeBuffer[writePointer][i]=canRXmsg.data[i-5];
+            }
+            if (++writePointer >= maxBufLen) {
+                writePointer = 0;
+                led3 = !led3;
+            }
+            if (writePointer==readPointer) {
+                // Just overwrote an entry that hasn't been sent to thumbdrive
+                sprintf(sTemp,"Write buffer overrun.\n");
+                logMsg(sTemp); // write buffer overrun
+                spkr.beep(500,0.25);
             }
         }
     }
-    
-    //-------------------------------
-    // Some MsgIDS are FFF and FFE, but this array only holds 0 to 7FF
-    //   so, only remember messages 7FF or less - gg - logging bug
-    if( canRXmsg.id < 0x800 ) {
-        // message is 7FF or less - gg - logging bug
-        
-        // Check if this MsgID has an associated ii entry
-        if(indexLastMsg[canRXmsg.id]==0) { 
-            // no ii entry associated with this MsgID
-            
-            // BUG: but ii = 0 is a valid entry after this wraps 
-            //ii=ii<99?ii+1:0;
-            //ii=ii<99?ii+1:1; // FIX: reserve ii = 0 as the "invalid, not used, entry
-            
-            if(ii<99) {
-                // unused entries are available
-                ii += 1; // use next unused entry    
-                
-                // sever previous usage, if any
-                //if( iiUsedBy[ii] != 0 ) indexLastMsg[iiUsedBy[ii]]=0;    
-                 
-                // keep track of what MsgID is using this ii entry
-                //iiUsedBy[ii]=canRXmsg.id; // future                                            
-                                                            
-                indexLastMsg[canRXmsg.id]=ii; // Create MsgID linkage for first message                               
-                
-                // update the entry's data
-                lastMsg[ii]=canRXmsg; //Store in table
-                
-                changed = 0xff ; // all bytes are new, so all changed
-                msgChanged[ii]=changed;
-                
-            } else {
-                // no more available unused entries
-                // so just ignore this MsgID for now
-                // ii = 1; // start to re-use entries
-                
-                // BUG: after this wraps to re-use the ii's, the old MsgID 
-                //   that was using this ii needs to be invalidated           
-                //indexLastMsg[iiUsedBy[ii]]=0; // invalidate ii entry for old MsgID                     
-            }
 
-        } else {
-            // there was an old entry for this MsgID to compare to for changes 
-            ij = indexLastMsg[canRXmsg.id] ;
-            
-            // compare the old message with the new one to make the data-changed flags            
-            // BUG?: why do this only if viewing the changedScreen?
-            if(dMode[0]==changedScreen||dMode[1]==changedScreen){
-                
-                changed=msgChanged[ij]; // why get the old changed bits
-                // what clears the changed bits, dislaying them on the changedScreen?
-                
-                // compare the 8 old and new data bytes for changes
-                for(i=0;i<8;i++){
-                    if(lastMsg[ij].data[i]!=canRXmsg.data[i]){
-                        changed |= 1<<i;
-                    }
+    if(canRXmsg.id<0x800){ // Block FFE and FFF messages
+        if(indexLastMsg[canRXmsg.id]==0) { //Check if no entry
+            ii=ii<99?ii+1:0; // Should never wrap - less than 100 different messages ever used
+            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;
                 }
-                // store the changes
-                msgChanged[ij]=changed;
             }
-            
-            // after the comparison, if any, update the entry's data
-            lastMsg[ij]=canRXmsg; // Store in table
-        }
-    } // end of is 7FF or less
-
-    //-----------------------
-    // Miscellaneous on-receive operations below
-    if((mType==2)&&(canRXmsg.id==0x358)){ // CAR bus
-        // headlight/turn signal indicator
-        headlights = (canRXmsg.data[1]&0x80)?true:false;
-
-    //-----------------        
-    }else if((mType==1)&&(canRXmsg.id==0x7bb)){ // EV bus
-        // is battery-response data?  7bb [0]=SeqNum 1 2 [3]=Group
-        // Need to store all responses
-        
-        // the first SeqNum is 10 (less than 20-2F found later)
-        if(canRXmsg.data[0]<0x20){
-            // the f1rst response in a series
-            if(canRXmsg.data[3]==2){ //cellpair data Group 2
-                bdi=0; // initial SeqNum = 10, so index 0
-                // next is 21 to 2F and then 20 to about 2C
-                sprintf(sTemp,"Getting cell pair data\n");
-                logMsg(sTemp);
-            }else if(canRXmsg.data[3]==4){ //temperature data Group 4
-                bdi=0x20; // index 0 - 2 from SeqNum 20 - 22
-                sprintf(sTemp,"Getting temperature data\n");
-                logMsg(sTemp);
-            //}else bdi=0; // strange, BUG? the same as Group 2
-            }else bdi=0xff; // ignore other messages (for now)
-
-            lasti=0;
-        }
-
-        if(bdi<0xff){
-            // handle just the recognized response
-            i=canRXmsg.data[0]&0x0f; // lower nibble of D0 is index, 0 to F
-            if(lasti>i){ //detect rollover to 20 (index 0) and offset index appropriately
-                bdi=0x10; // adding 10 to the index for CPs
-            }
-            lasti=i; //remember the index nibble to detect rollover next time around
-            i+=bdi; // 0 to F then 10 through about 1C for CPs
-                    // 20 through 22 for the Temperatures (Group 4)
-        
-            //--------------
-            // detect last response from the Temperature series.
-            //if(i==22) logCP=true; //Turbo3
-            //if( (i==22) && (yesBattLog) ) logCP=true; // only if enabled gg - Batt Log 
-            if(i==22){
-                // is the last response from Temperatures
-                logCP=yesBattLog; // Only log if logging enabled
-                showCP=true; // Always show
-            }
-        
-            // storing 7 bytes of data from each response (after the SeqNum)
-            i*=7;
-            if(i<0xfa){ // Is there a better way to do this?
-                // for CP data the base is 0, at i is (i*7)+6 and the last is 28*7+6 
-                // for Temp data,  base is 32*7, at i is (i*7)+6 and the last is 34*7+6      
-                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];
-            }
+            msgChanged[indexLastMsg[canRXmsg.id]]=changed;
         }
     
-    //----------------------   
-    }else if((mType==1)&&(canRXmsg.id==0x1db)){ // EV bus
-        // Battery Volts and Amps
-        packV=((canRXmsg.data[2]<<2)|(canRXmsg.data[3]>>6)); // 1 LSB = 0.5V
-        packA=((canRXmsg.data[0]<<3)|(canRXmsg.data[1]>>5)); // 1 LSB = 0.5A
-        if(packA>0x03ff){
-            packA|=0xf800;//extend sign;
+        lastMsg[indexLastMsg[canRXmsg.id]]=canRXmsg; //Store in table
+    
+        //Miscellaneous on-recieve operations below
+        if((mType==2)&&(canRXmsg.id==0x358)){ // headlight/turn signal indicator
+            headlights = (canRXmsg.data[1]&0x80)?true:false;
+        }else 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=0xff; // ignore other messages (for now)
+                lasti=0;
+            }
+            if(bdi<0xff){
+                i=canRXmsg.data[0]&0x0f; //lower nibble of D0 is index
+                if(lasti>i){ //detect rollover and offset index appropriately
+                    bdi=0x10;
+                }
+                lasti=i; //remember the msb to detect rollover next time around
+                i+=bdi;
+                //if(i==22) logCP=true; //Turbo3
+                //if( (i==22) && (yesBattLog) ) logCP=true; // only if enabled gg - Batt Log 
+                if(i==22){
+                    logCP=yesBattLog; // Only log if logging enabled
+                    showCP=true; // Always show
+                }
+                i*=7;
+                if(i<0xfa){ // Is there a better way to do this?
+                    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];
+                }
+            }
+        }else if((mType==1)&&(canRXmsg.id==0x1db)){ //Battery Volts and Amps
+            packV=((canRXmsg.data[2]<<2)|(canRXmsg.data[3]>>6)); // 1 LSB = 0.5V
+            packA=((canRXmsg.data[0]<<3)|(canRXmsg.data[1]>>5)); // 1 LSB = 0.5A
+            if(packA>0x03ff){
+                packA|=0xf800;//extend sign;
+            }
+            packA -= 1; //Slight correction to value required (unique to my Leaf?)
+            imWs_x4 = packV; // Volts*milliSeconds*2
+            imWs_x4 *= -packA; // milliWattseconds*4
+            if (!((imotorRPM<2)&&(imWs_x4<0))){ //Ignore if charging from wall
+                mWs_x4 += imWs_x4; // total mWs_x4
+                numWsamples++;
+            }
+        }else if((mType==1)&&(canRXmsg.id==0x1da)){ //Motor Speed
+            imotorRPM=((canRXmsg.data[4]<<8)|(canRXmsg.data[5]));
+            if(imotorRPM<0){ // take absolute value
+                imotorRPM=-imotorRPM;
+            }
+            motorRPM+=imotorRPM;
+            numSsamples++;
         }
-        imWs_x4 = packV; // Volts*milliSeconds*2
-        imWs_x4 *= -packA; // milliWattseconds*4
-        if (!((imotorRPM<2)&&(imWs_x4<0))){ //Ignore if charging from wall
-            mWs_x4 += imWs_x4; // total mWs_x4
-            numWsamples++;
-        }
-
-    //-------------------------        
-    }else if((mType==1)&&(canRXmsg.id==0x1da)){ // EV bus
-        // Motor Speed
-        imotorRPM=((canRXmsg.data[4]<<8)|(canRXmsg.data[5]));
-        if(imotorRPM<0){ // take absolute value
-            imotorRPM=-imotorRPM;
-        }
-        motorRPM+=imotorRPM;
-        numSsamples++;
     }
 }
 
-//---------------------------------
 void logTS () {
     CANMessage tsMsg;
     unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
@@ -322,9 +172,7 @@
     logCan(0,tsMsg); // Date-Time
 }
 
-//----------------------------------
-// gg - logevent
-void logEvent (char * errMsg) {
+void logErrMsg (char * errMsg) {
     // log CAN-Do 8-character Pseudo Message
     CANMessage tsMsg;
     tsMsg.id=0xffe; // pseudo Message to CAN-Do log
@@ -345,36 +193,37 @@
             case 0:
                 can1.monitor(false); // set to active mode
                 can1SleepMode = 0; // enable TX
-                data[0]=0x02; //change to request frame 1
+                data[0]=0x02; //change to request group 1
                 data[1]=0x21;
                 data[2]=0x01;
                 break;
-            case 6: // frame 1 has 6 lines
+            case 6: // group 1 has 6 frames
                 can1.monitor(false); // set to active mode
                 can1SleepMode = 0; // enable TX
-                data[0]=0x02; //change to request frame 2 (cp data)
+                data[0]=0x02; //change to request group 2 (cp data)
                 data[1]=0x21;
                 data[2]=0x02;
                 break;
-            case 35: // frame 2 has 29 lines
-                data[0]=0x02; //change to request frame 3
+            case 35: // group 2 has 29 frames
+                data[0]=0x02; //change to request group 3
                 data[1]=0x21;
                 data[2]=0x03;
                 break;
-            case 40: // frame 3 has 5 lines
-                data[0]=0x02; //change to request frame 4 (temperature)
+            case 40: // group 3 has 5 frames
+                data[0]=0x02; //change to request group 4 (temperature)
                 data[1]=0x21;
                 data[2]=0x04;
                 break;
-            case 43: // frame 4 has 3 lines
-                data[0]=0x02; //change to request frame 5
+            case 43: // group 4 has 3 frames
+                data[0]=0x02; //change to request group 5
                 data[1]=0x21;
                 data[2]=0x05;
                 break;
-            case 54: // frame 5 has 11 lines
+            case 54: // group 5 has 11 frames
                 reqMsgCnt = 99;
                 can1SleepMode = 1; // disable TX
                 can1.monitor(true); // set to snoop mode
+                msgReq.detach(); // stop ticker
             default:
                 data[0]=0x30; //change to request next line message
                 data[1]=0x01;
@@ -433,6 +282,7 @@
 
 void autoPollISR(){
     reqMsgCnt = 0; //reset message counter
+    msgReq.attach(&sendReq,0.015);
 }
 void playbackISR() { //Used for autoplayback
     step=true;