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:
- 12:8e42d7ba8468
- Parent:
- 11:e9d155aad4e2
- Child:
- 13:62e0f7f39ff5
--- a/main.cpp Wed Feb 27 03:47:06 2013 +0000 +++ b/main.cpp Sun Mar 03 15:50:54 2013 +0000 @@ -1,504 +1,23 @@ -#include "CANary.h" +//#include "utility.h" +//#include "displayModes.h" //To Do: -// USB device detect -// config file on local fs -// user programmable message decode -// brake trainer -// write and read the Mode Data -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 - -extern "C" void mbed_reset(); - -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); // CAN2 uses pins 9 and 10 (rx, tx) and pin 27 (rs) -DigitalOut can1SleepMode(p8); // Use pin 8 to control the sleep mode of can2 -CAN can2(p30, p29); // CAN1 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 getXY=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; - -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 "C" 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 touched(){ - LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF); - secsNoTouch = 0; - getXY=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]==changedMode||dMode[1]==changedMode){ - 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<64;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<8;i++){ - wait_ms(16); //wait 16ms - can1.write(CANMessage(0x79b, data, 8)); - } - can1SleepMode = 1; // disable TX - can1.monitor(true); // set to snoop mode -} - -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 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*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; - jv=avg-(max-avg)*2.5; - 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 logMode: - printLog(changed); - break; - case dteMode: - printDTE(changed); - break; - case brakeMode: - braking(changed,true); - break; - case powerMode: - braking(changed,false); - break; - case monitorMode: - printLast(changed); - break; - case changedMode: - printChanged(changed); - break; - case cpMode: - 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; - } -} +// * USB device detect +// * config file on local fs with touchscreen calibration +// * user programmable message decode +// * brake trainer +// * write and read the Mode Data +// * Date entry config screen (keypad) +// * auto-poll option for cellpair data +// * cellpair histogram +// * +#include "mbed.h" +#include "CAN.h" +#include "beep.h" +#include "MSCFileSystem.h" +#include "PowerControl.h" +#include "EthernetPowerControl.h" +#include "utility.h" +#include "displayModes.h" int main() { int readPointer=0; @@ -522,9 +41,13 @@ tt.background(Black); tt.cls(); tt.set_display(0); // select left display - tt.calibrate(); // calibrate the touch + if(true){ // bypass calibration + tt.setcal(5570, 34030, 80, 108, 33700, 5780, 82, 108, 32500); + } else { // calibrate the touch + tt.calibrate(); + } tt.claim(stdout); // send stdout to the TFT display - touchpad.rise(&touched); + touchpad.rise(&touch_ISR); tt.wfi(); // enable interrupt on touch dled = 0.8; // turn on display LED 80% timer.start() ; @@ -563,6 +86,7 @@ // strftime(sTemp, 32, "%a %m/%d/%Y %X", localtime(&seconds)); // printf("%s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS } + //ticker.attach(&tickerISR, 60); //poll cellpair data every minute while (true) { if (!logOpen) { // Open new file if one is not already open if(logEn){ //logging enable @@ -623,7 +147,7 @@ secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900 while (secsNoMsg>canTimeout && secsNoTouch>userTimeout) { //DeepPowerDown(); - tt.wfi(); //enable touchpad input + tt.wfi(); //enable touch interrupt __wfi(); // freeze CPU and wait for interrupt (from canbus or touch) //Sleep(); //DeepPowerDown(); @@ -642,10 +166,10 @@ } } // if idle - if(getXY){ + if(touched){ lastTouch = tt.get_touch(); lastTouch = tt.to_pixel(lastTouch); // convert to pixel pos - getXY = false; // clear interrupt flag + touched = false; // clear interrupt flag } if (!userIdle) { if (secsNoTouch<2) {// Recently touched @@ -659,15 +183,15 @@ if (lastTouch.y>btn11y1 && lastTouch.y<btn11y2) { if(sMode==1){ if (lastTouch.x>btn31x1 && lastTouch.x<btn31x2) { - dMode[i]=dMode[i]>0?dMode[i]-1:maxModes; + dMode[i]=dMode[i]>0?dMode[i]-1:maxScreens; } else if (lastTouch.x>btn32x1 && lastTouch.x<btn32x2) { secsNoTouch = userTimeout; // immediately exit config mode } else if (lastTouch.x>btn33x1 && lastTouch.x<btn33x2) { - dMode[i]=dMode[i]<maxModes?dMode[i]+1:0; + dMode[i]=dMode[i]<maxScreens?dMode[i]+1:0; } } else sMode=1; } else { - if (dMode[i]==monitorMode||dMode[i]==changedMode) { + if (dMode[i]==monitorScreen||dMode[i]==changedScreen) { if (lastTouch.x>btn31x1 && lastTouch.x<btn31x2) { indexOffset=indexOffset>4?indexOffset-4:1; } else if (lastTouch.x>btn32x1 && lastTouch.x<btn32x2) { @@ -676,13 +200,9 @@ } else if (lastTouch.x>btn33x1 && lastTouch.x<btn33x2) { indexOffset=indexOffset<77?indexOffset+4:80; } - } else if (dMode[i]==cpMode) { + } else if (dMode[i]==cpScreen) { if (lastTouch.x>btn32x1 && lastTouch.x<btn32x2){ - sendCPreq(); // send cellpair data request. - wait_ms(16); - sendTreq(); //send temperature request - wait_ms(16); - showCP=true; + pollCP=true; } } } //top of screen @@ -694,6 +214,14 @@ lastDMode[1]=99; } } + if(pollCP){ + sendCPreq(); // send cellpair data request. + wait_ms(16); + sendTreq(); //send temperature request + wait_ms(16); + pollCP=false; + showCP=true; + } display=display<1?display+1:0; // toggle display updateDisplay(display); //wait(0.1); // We get >2K messages per second