Dual CANbus monitor and instrumentation cluster supporting ILI9341 display controller
Dependencies: SPI_TFTx2_ILI9341 TOUCH_TFTx2_ILI9341 TFT_fonts mbed
Fork of CANary by
Diff: main.cpp
- Revision:
- 2:71b1999a8ea5
- Parent:
- 1:9dcd70c32180
- Child:
- 3:3e879b043bc5
diff -r 9dcd70c32180 -r 71b1999a8ea5 main.cpp --- a/main.cpp Sun Feb 03 18:16:53 2013 +0000 +++ b/main.cpp Mon Feb 11 02:22:04 2013 +0000 @@ -1,14 +1,3 @@ -#include "mbed.h" -#include "CAN.h" -#include "log.h" -#include "beep.h" -#include "MSCFileSystem.h" -#include "SPI_TFTx2.h" -#include "Arial12x12.h" -#include "Arial28x28.h" -#include "TOUCH_TFTx2.h" -#define upLine "\033[1A" - //CANary.cpp //LEAF OBD @@ -80,6 +69,27 @@ //38: NC:IF- //39: NC:5Vout (only available when connected as USB device) //40: VCC3.3 +#include "mbed.h" +#include "CAN.h" +#include "beep.h" +#include "MSCFileSystem.h" +#include "SPI_TFTx2.h" +#include "Arial12x12.h" +#include "Arial28x28.h" +#include "TOUCH_TFTx2.h" +#define upLine "\033[1A" +#define maxBufLen 2048 +#define canTimeout 5 + +// write and read the Mode Data +LocalFileSystem local("local"); // test the local file system to write files + +// to write to USB Flash Drives, or equivalent (SD card in Reader/Writer) +MSCFileSystem fs("fs"); // to write to a USB Flash Drive + +void Log (char *message); +void LogErr (char *message); +extern "C" void mbed_reset(); time_t seconds ; Beep buzzer(p21); @@ -94,124 +104,106 @@ DigitalOut can1_SleepMode(p8); // Use pin 8 to control the sleep mode of can1 CAN can2(p30, p29); // CAN2 uses pins 30 and 29 (rx, tx) and pin 28 (rs) DigitalOut can2_SleepMode(p28); // Use pin 28 to control the sleep mode of can2 -bool logCreated = false; -char logMsg[64]; +bool logOpen = false; +FILE *rfile; +FILE *file; +char fileName[35] = "" ; +char writeBuffer[maxBufLen][13]; +char c; +volatile int writePointer = 0; +volatile int secsIdle = 0; +volatile bool canIdle = false; char counter = 0; TOUCH_TFTx2 tt(p16, p17, p19, p20, p11, p12, p13, p6, p7, p5, "TFT"); // x+,x-,y+,y-,mosi, miso, sclk, cs0, cs1, reset -unsigned short getTimeStamp() {// from Gary's code - - //----------- - // read ms from the timer - int msec = timer.read_ms() ; - - // quickly, read Date and Time (to seconds) from the RTC - unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900 - - //----------- - if ( msec > 999 ) msec = 999 ; - int isecs = secs % 60 ; // modulo 60 for 0-59 seconds from RTC - - return ( ( isecs << 10 ) + msec ) ; // return the two byte time stamp +extern "C" void RTC_IRQHandler() { + timer.reset(); // zero ms at the-seconds-tic + canIdle=(++secsIdle>canTimeout); + LPC_RTC->ILR |= (1<<0); // clear interrupt to prepare for next } -extern "C" void RTC_IRQHandler() -{ - - timer.reset() ; // zero ms at the-seconds-tick - -} - -extern "C" void RTC_Init (void) -{ - - // set up the RTC interrupts - LPC_RTC->ILR=0x00; - - //LPC_RTC->CIIR=0x02; // interrupts each minute - verified - LPC_RTC->CIIR=0x01; // interrupts each second - verified - - //LPC_RTC->CCR = 0x11; // use for interrupts every minute ???? - //LPC_RTC->CCR = 0x00; // Stop the RTC (apparently) - LPC_RTC->CCR = 0x01; // Start RTC (apparently use for interrupt every second) - - // NVIC_SetPriority( RTC_IRQn, LOW_PR ); +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 readLog () -{ - FILE *rfile; +unsigned short getTimeStamp() { + int msec = timer.read_ms() ; // read ms from the timer + unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900 + int isecs = secs%60 ; // modulo 60 for 0-59 seconds from RTC + return ((isecs<<10)+msec) ; // return the two byte time stamp +} + +void readLog (){ unsigned char c; int i=0; + char lastMsgNum[]={0,0}; + char curMsgNum[]={0,0}; + char canNum=0; printf("printing file\n"); - rfile = fopen(LOGFILE, "r"); - if (rfile == NULL) { + file = fopen(fileName, "r"); + if (file == NULL) { printf("no file found\n"); + } + while (!feof(file)) { + c=fgetc(file); + printf("%02x ",c); + if (i==0){ + canNum=c; + }else if (i==5){ + curMsgNum[canNum]=c; } - while (!feof(rfile)) - { - c=fgetc(rfile); - printf("%02x ",c); - if (++i>11) - { + if (++i>12) { + if (curMsgNum[canNum]>(lastMsgNum[canNum]+1)) { + printf(" ***"); + } + lastMsgNum[canNum]=curMsgNum[canNum]; printf("\n"); i=0; - } } - fclose(rfile); + } + printf("\n\n"); + fclose(file); } - -void logCan (CANMessage canRXmsg) -{ - FILE *file; - - unsigned short ts; - - ts=getTimeStamp(); - if (!logCreated) { - file = fopen(LOGFILE, "w"); - logCreated = true; - } - else - file = fopen(LOGFILE, "a"); - - if (file == NULL) { - if (logCreated) - logCreated = false; - return; - } - else - { - fprintf(file,"%c%c%c%c%c%c%c%c%c%c%c%c",ts>>8,ts&0xff,canRXmsg.id&0xff,(canRXmsg.id>>8)+(canRXmsg.len<<4),canRXmsg.data[0],canRXmsg.data[1],canRXmsg.data[2],canRXmsg.data[3],canRXmsg.data[4],canRXmsg.data[5],canRXmsg.data[6],canRXmsg.data[7]); - fclose(file); +void logCan (char mtype, CANMessage canRXmsg) { + unsigned short ts = getTimeStamp(); + unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900 + 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 (int i = 5; i<13; i++){ + writeBuffer[writePointer][i]=canRXmsg.data[i-5]; + } + if (++writePointer >= maxBufLen) { + writePointer = 0; + led4 = !led4; + } } } -void Log (char *message) -{ - FILE *file; - - if (!logCreated) { - file = fopen(LOGFILE, "w"); - logCreated = true; - } - else - file = fopen(LOGFILE, "a"); - - if (file == NULL) { - if (logCreated) - logCreated = false; - return; - } - else - { - fputs(message, file); - fclose(file); - } +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 send1() { @@ -222,65 +214,69 @@ // test sending 3 quickly //can1.write(CANMessage(0x351, &counter, 1)); //can1.write(CANMessage(0x352, &counter, 1)); + printf("Sending message %d \n",counter); } void recieve1() { - static CANMessage msg1; - unsigned short msgTime; - - msgTime=getTimeStamp(); + CANMessage msg1; + secsIdle=0; // reset deadman switch can1.read(msg1); - printf("%sCan1 Message received: %d %x\n", upLine, msg1.data[0], msgTime); - printf("Can1 rxd: %d\n", msg1.data[0]); - if(logCreated) { - logCan(msg1); - } - led2 = !led2; + //printf("Can1 rxd: %d\n", msg1.data[0]); + if(logOpen) + logCan(2, msg1); + led1 = !led1; } + void recieve2() { - static CANMessage msg2; - unsigned short msgTime; - - msgTime=getTimeStamp(); + CANMessage msg2; + secsIdle=0; // reset deadman switch can2.read(msg2); - printf("%sCan2 Message received: %d %x\n", upLine, msg2.data[0],msgTime); - printf("Can2 rxd: %d\n", msg2.data[0]); - if(logCreated) { - logCan(msg2); - } - - led3 = !led3; + //printf("Can2 rxd: %d\n", msg2.data[0]); + if(logOpen) + logCan(1, msg2); + led2 = !led2; } int main() { - can1.frequency(1000000); - can2.frequency(1000000); + int readPointer=0; + int fmon; + int fday; + int ftime; + char sTemp[35]; + unsigned long secs; + bool bit = false; + can1.frequency(500000); + can2.frequency(500000); //can1_SleepMode = 0; // Enable TX //can2_SleepMode = 0; // Enable TX can1_SleepMode = 1; // Turn on Monitor_only Mode can2_SleepMode = 1; // Turn on Monitor_only Mode - ticker.attach(&send1, 0.25); + //ticker.attach(&send1, 0.5); can1.attach(&recieve1); can2.attach(&recieve2); - unsigned int dsel = 1; // select right display tt.set_display(2); // select both displays tt.background(Black); // set background to black tt.foreground(White); // set chars to white tt.cls(); // clear the screen tt.set_font((unsigned char*) Arial12x12); // select the font tt.set_orientation(1); - tt.set_display(dsel); // select display + tt.set_display(1); // select left display - tt.calibrate(); // calibrate the touch - tt.locate(0,0); + //tt.calibrate(); // calibrate the touch tt.claim(stdout); // send stdout to the TFT display - + timer.start() ; + RTC_Init(); // start the RTC Interrupts that sync the timer struct tm t; // pointer to a static tm structure seconds = time(NULL); t = *localtime(&seconds) ; + strftime(sTemp, 32, "%a %m/%d/%Y %X", &t); + tt.locate(0,0); + printf("\nCurrent time : %s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS + tt.set_display(1); // select right display + tt.locate(0,0); // is it a date before 2012 ? if ((t.tm_year + 1900) < 2012 ) { @@ -288,9 +284,9 @@ // So, set a near-recent date in 2012 // enter people-values here - t.tm_year = 2012 ; // 28 May 2012 - t.tm_mon = 6 ; // 1 to 12 - t.tm_mday = 1; + t.tm_year = 2013 ; // 28 May 2012 + t.tm_mon = 3 ; // 1 to 12 + t.tm_mday = 5; t.tm_hour = 12; // 12:59:56 PM (after noon) t.tm_min = 59; t.tm_sec = 56; @@ -307,4 +303,122 @@ // strftime(sTemp, 32, "%a %m/%d/%Y %X", localtime(&seconds)); // printf("%s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS } + while (true) { + if(1 == 1) { + if (!logOpen) { // Open new file if one is not already open + seconds = time(NULL); + t = *localtime(&seconds) ; + strftime(fileName, 32, "/fs/%m%d%H%M.alc", &t); //mmddhhmm.alc + + printf("Using file %s\n",fileName); + file = fopen(fileName, "ab"); + + if(file==NULL){ + printf("\nUnable to open %s\n\n\n\n",fileName); + wait(10); + mbed_reset(); + } else { + logOpen = true; + readPointer=writePointer; + printf("\nStarting Can Log %s\n",fileName); + logTS(); + fclose(file); + file = fopen("/fs/loglog.txt", "a"); + fprintf(file,"%s\r\n",fileName); + fclose(file); + } + } // if (!logOpen) + do { + if (((writePointer+maxBufLen-readPointer)%maxBufLen)>(maxBufLen/2)||canIdle) { + // Dump buffer if > 1/2 full, canbus has stopped, or PB1 pressed + if (logOpen) { + file = fopen(fileName, "ab"); + if (file == NULL) { + logOpen = false; + printf("Failed to append log file.\n\n"); + } else { + while (readPointer != writePointer) { + for (int j = 0; j<13; j++){ + fprintf(file,"%c",writeBuffer[readPointer][j]); + } + if(++readPointer >= maxBufLen) + readPointer=0; + } + led3 = !led3; + fclose(file); + } + } // if (logOpen) + } // if > 1/2 full, canbus has stopped, or PB1 pressed + if (canIdle) { // canbus idle --> sleep to save power + // First take advantage of the idle time to clear some room + + bit = false; + rfile = fopen("/fs/loglog.txt", "r"); + file = fopen("/fs/loglog.new", "w"); + while (!feof(rfile)) { + fscanf(rfile,"/fs/%2d%2d%4d.alc\r\n",&fmon,&fday,&ftime); + //if ((fmon<t.tm_mon)&&(fday<=t.tm_mday)){ // Delete all files more than 1 month old + if ((fmon < 12) || (t.tm_mon > 1)){ + fday = fday + fmon*31; //crude - february will store 3 extra days of data + } + if ((fday+14)<(t.tm_mday+t.tm_mon*31)){ // Delete all files more than ~14 days old + bit=true; + sprintf(sTemp,"/fs/%02d%02d%04d.alc",fmon,fday,ftime); + if ((remove(sTemp)==NULL)) { + printf("Removed file %s\n",sTemp); + } + }else{ + fprintf(file,"/fs/%02d%02d%04d.alc\r\n",fmon,fday,ftime); + } + } + fclose (file); + fclose (rfile); + if (bit) { + remove ("/fs/loglog.txt"); + //rename not working so do it the hard way + //rename ("/fs/loglog.new","/fs/loglog.txt"); + rfile = fopen("/fs/loglog.new", "r"); + file = fopen("/fs/loglog.txt", "w"); + while (!feof(rfile)) { + fscanf(rfile,"%s\r\n",&sTemp); + fprintf(file,"%s\r\n",sTemp); + } + fclose (file); + fclose (rfile); + } + remove ("/fs/loglog.new"); + wait(5); // wait a few seconds to ensure fsRAM is done + + printf("Putting uC to sleep.\n"); + //LPC_RTC->CIIR=0x00; // block RTC interrupts + led1=0; + led2=0; + led3=0; + led4=0; + secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900 + while (secsIdle>canTimeout) { + //DeepPowerDown(); + __wfi(); // freeze CPU and wait for interrupt (from canbus) + } + canIdle=false; + printf("Waking uC.\n"); + if (time(NULL)>(secs+1800)) { + logOpen = false; // Start new file if asleep for more than 30 minutes + } else { // insert timestamp on each wake + logTS(); + } + //LPC_RTC->CIIR=0x01; // re-enable RTC interrupts + } + wait(0.2); // We get >2K messages per second + } while (logOpen); // keep going until button or fsram removed + } else { + printf("\nNo fUSB Inserted.\n\n"); + logOpen=false; + led1=!led1; + led2=led1; + led3=led1; + led4=led1; + wait(5); + } //if (CD==1) + } //while (true) } \ No newline at end of file