.
Dependencies: SDHCFileSystem mbed
main.cpp
- Committer:
- TickTock
- Date:
- 2012-12-24
- Revision:
- 21:a45a999d6da3
- Parent:
- 20:153800633e28
- Child:
- 22:605c2f33b340
File content as of revision 21:a45a999d6da3:
//CANcan.cpp //A dual canbus monitoring "blackbox" application for the Nissan Leaf //Dumps all messages to a file on the SDRAM //Todo: // Get timestamp on files // // Connections: //LEAF OBD //1: //2: //3: AVCAN-L White/Blue //4: //5: VSS Brown,White/Brown //6: CARCAN-H Green --> VP230b:7 //7: //8: 12V-SW Orange,White/Orange //9: //10: //11: AVCAN-H Blue //12: EVCAN-L White/Grey --> VP230a:6 //13: EVCAN-H Grey --> VP230a:7 //14: CARCAN-L White/Green --> VP230b:6 //15: 6V //16: 12V-AON Red/Blue,Blue/Red ----|<---- LPC1768:2 //note 1: pins 4 & 5 longer //note 2: pins 12 & 13 next to key //note 3: pins 1 & 9 on right side looking into male connector with key on bottom //VP230{a,b} //1:D //2:GND //3:VCC //4:R //5:Vref //6:CANL --> OBD:12,14 //7:CANH --> OBD:13,6 //8:RS --> LPC1768:27,28 //LPC1768 //1: VSS 6V //2: VIN (4.5-9V supply) ---->|---- OBD:16 //3: NC:VB //4: NC:nR //5: SPI:MOSI --> 6:SDRAM:DI //6: SPI:MISO --> 2:SDRAM:DO //7: SPI:SCLK --> 4:SDRAM:SCLK //8: CS --> 7:SDRAM:CS //9: CAN1:RX --> 4:CAN1:R //10: CAN1:TX --> 1:CAN1:D //11: NC:RS --> 4:LCD:RS //12: NC:E --> 6:LCD:E //13: NC:D4 --> 11:LCD:D4 //14: NC:D5 --> 12:LCD:D5 //15: NC:D6 --> 13:LCD:D6 //16: NC:D7 --> 14:LCD:D7 //17: CD --> 1:SDRAM:CD //18: NC:MON12V --> 4K to 12V, 1K to VSS (To be implemented) //19: PB2 //20: PB1 //21: NC:Spkr+ //22: NC:Spkr- (optional complimentary output for more volume) //23: NC:pwm //24: NC:LEDBLU --> 18:LCD:BLU (only used for tri-color displays) //25: NC:LEDGRN --> 17:LCD:GRN (only used for tri-color displays) //26: NC:LEDRED --> 16:LCD:RED //27: CAN1:Sleep --> 8:CAN1:RS //28: CAN2:Sleep --> 8:CAN2:RS //29: CAN2:TX --> 1:CAN2:D //30: CAN2:RX --> 4:CAN2:R //31: NC:USB_D+ //32: NC: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 #include "mbed.h" #include "CAN.h" #include "SDHCFileSystem.h" #define upLine "\033[1A" #define maxBufLen 2048 #define canTimeout 5 #define maxFileNum 30 void Log (char *message); void LogErr (char *message); extern "C" void mbed_reset(); time_t seconds ; DigitalIn CD(p17); DigitalIn PB1( p20 ); SDFileSystem sd(p5, p6, p7, p8, "sd" ); // SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) Timer timer; DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); CAN can1(p9, p10); // CAN1 uses pins 9 and 10 (rx, tx) and pin 27 (rs) DigitalOut can1_SleepMode(p27); // Use pin 27 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 logOpen = false; FILE *rfile; FILE *file; char fileName[35] = "" ; char writeBuffer[maxBufLen][13]; char c; volatile int writePointer = 0; volatile int secsIdle = canTimeout; volatile bool canIdle = false; Serial pc(USBTX, USBRX); 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_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 ); } 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; pc.printf("printing file\n"); file = fopen(fileName, "r"); if (file == NULL) { pc.printf("no file found\n"); } while (!feof(file)) { c=fgetc(file); pc.printf("%02x ",c); if (i==0){ canNum=c; }else if (i==5){ curMsgNum[canNum]=c; } if (++i>12) { if (curMsgNum[canNum]>(lastMsgNum[canNum]+1)) { pc.printf(" ***"); } lastMsgNum[canNum]=curMsgNum[canNum]; pc.printf("\n"); i=0; } } pc.printf("\n\n"); 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 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 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 recieve1() { CANMessage msg1; secsIdle=0; // reset deadman switch can1.read(msg1); if(logOpen) logCan(1, msg1); led1 = !led1; } void recieve2() { CANMessage msg2; secsIdle=0; // reset deadman switch can2.read(msg2); if(logOpen) logCan(2, msg2); led2 = !led2; } int main() { int readPointer=0; int fmon; int fday; int ftime; char sTemp[35]; unsigned long secs; pc.baud(460800); // change serial interface to pc to 450800, 8N1 can1.frequency(500000); can2.frequency(500000); can1_SleepMode = 1; // Monitor_only Mode can2_SleepMode = 1; // Monitor_only Mode CD.mode(PullUp) ; //SDRAM Chip Detect PB1.mode(PullUp) ; //Pushbutton 1 can1.attach(&recieve1); can2.attach(&recieve2); 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); pc.printf("\nCurrent time set to: %s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS wait(1.1); // give time to sync if (PB1==0) { //set time if pb pressed pc.printf("\nEnter year (yyyy):"); pc.scanf("%s", &sTemp); t.tm_year = atoi(sTemp); pc.printf("\nEnter month (mm):"); pc.scanf("%2s", &sTemp); t.tm_mon = atoi(sTemp); pc.printf("\nEnter day (dd):"); pc.scanf("%2s", &sTemp); t.tm_mday = atoi(sTemp); pc.printf("\nEnter hour (hh):"); pc.scanf("%2s", &sTemp); t.tm_hour = atoi(sTemp); pc.printf("\nEnter minute (mm):"); pc.scanf("%2s", &sTemp); t.tm_min = atoi(sTemp); pc.printf("\nEnter seconds (ss):"); pc.scanf("%2s", &sTemp); t.tm_sec = atoi(sTemp); // adjust for tm structure required values t.tm_year = t.tm_year - 1900; t.tm_mon = t.tm_mon - 1; // set the RTC set_time(mktime(&t)); seconds = time(NULL); pc.printf("\nRTC set to: " ); strftime(sTemp, 32, "%a %m/%d/%Y %X", localtime(&seconds)); pc.printf("%s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS } /*if (t.tm_year < 10) {//for test - delete t.tm_year = 2012-1900;//delete set_time(mktime(&t));//delete seconds = time(NULL);//delete } t.tm_mon=(t.tm_mon+1)%12; //for test - delete t.tm_mday=(t.tm_mday+1)%30; //for test - delete set_time(mktime(&t));//delete seconds = time(NULL);//delete*/ while (true) { if(CD == 1) { if (!logOpen) { // Open new file if one is not already open t = *localtime(&seconds) ; strftime(fileName, 32, "/sd/%m%d%H%M.alc", &t); //mmddhhmm.alc pc.printf("Using file %s\n",fileName); file = fopen(fileName, "ab"); if(file==NULL){ pc.printf("\nUnable to open canlog\n\n\n\n"); mbed_reset(); } else { logOpen = true; readPointer=writePointer; pc.printf("\nStarting Can Log %s\n",fileName); logTS(); fclose(file); file = fopen("/sd/loglog.txt", "a"); fprintf(file,"%s\r\n",fileName); fclose(file); } } // if (!logOpen) do { if (((writePointer+maxBufLen-readPointer)%maxBufLen)>(maxBufLen/2)||canIdle||(PB1==0)) { // Dump buffer if > 1/2 full, canbus has stopped, or PB1 pressed if (logOpen) { file = fopen(fileName, "ab"); if (file == NULL) { logOpen = false; pc.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 // Delete all files more than 1 month old rfile = fopen("/sd/loglog.txt", "r"); file = fopen("/sd/loglog.new", "w"); while (!feof(rfile)) { fscanf(rfile,"/sd/%2d%2d%4d.alc\r\n",&fmon,&fday,&ftime); if ((fmon<t.tm_mon)&&(fday<=t.tm_mday)){ sprintf(sTemp,"/sd/%02d%02d%04d.alc",fmon,fday,ftime); if ((remove(sTemp)==NULL)) pc.printf("Removed file %s\n",sTemp); }else{ fprintf(file,"/sd/%02d%02d%04d.alc\r\n",fmon,fday,ftime); } } fclose (file); fclose (rfile); remove ("/sd/loglog.txt"); //rename not working so do it the hard way //rename ("/sd/loglog.new","/sd/loglog.txt"); rfile = fopen("/sd/loglog.new", "r"); file = fopen("/sd/loglog.txt", "w"); while (!feof(rfile)) { fscanf(rfile,"%s\r\n",&sTemp); fprintf(file,"%s\r\n",sTemp); } fclose (file); fclose (rfile); remove ("/sd/loglog.new"); pc.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) 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 ((PB1==1)&&(CD==1)&&logOpen); // keep going until button or SDram removed if (PB1==0) { led1=0; led2=0; led3=0; led4=0; pc.printf("Log stopped\n\n"); logOpen=false; wait(5); // wait 5 seconds to give time to remove SDRAM if desired if (PB1==0) readLog(); // dump file if PB still pressed } } else { pc.printf("\nNo SDRAM Inserted.\n\n"); logOpen=false; led1=!led1; led2=led1; led3=led1; led4=led1; wait(5); } //if (CD==1) } //while (true) }