Dual CANbus monitor and instrumentation cluster

Dependencies:   SPI_TFTx2 TFT_fonts TOUCH_TFTx2 beep mbed

Fork of CANary by Tick Tock

utility.cpp

Committer:
TickTock
Date:
2013-03-17
Revision:
31:082372c83f68
Parent:
26:462ccb580472
Child:
32:c9d9b6cb5de1

File content as of revision 31:082372c83f68:

// utility.cpp

#include "utility.h"

void mbed_reset();

void RTC_IRQHandler() {
    timer.reset(); // zero ms at the-seconds-tic
    canIdle=(++secsNoMsg>canTimeout)?true:false;
    userIdle=(++secsNoTouch>userTimeout)?true:false;
    LPC_RTC->ILR |= (1<<0); // clear interrupt to prepare for next
}

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);
    touched=true; // jsut set flag - touch screen algorythm is long and we don't want to block other interrupts
}

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<29;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<3;i++){
        wait_ms(16); //wait 16ms
        can1.write(CANMessage(0x79b, data, 8));
    }
    can1SleepMode = 1; // disable TX
    can1.monitor(true); // set to snoop mode
}

void msgSend() {
    //char sTemp[40];
    char data[8] = {0x02, 0x21, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff};
    if (CPcount<30) {
        switch (CPcount) {
            case 0:
                can1.monitor(false); // set to active mode
                can1SleepMode = 0; // enable TX
                //data[8] = {0x02, 0x21, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff};
                data[2] = 0x02;
                //sprintf(sTemp,"Sending cp request\n");
                //logMsg(sTemp);
                break;
            default:
                data[0]=0x30; //change to request next line message
                data[1]=0x01;
                data[2]=0x00;
                break;
        }
        can1.write(CANMessage(0x79b, data, 8));
        CPcount+=1;
    } else if (Tcount<4) {
        switch (Tcount) {
            case 0:
                //data[8] = {0x02, 0x21, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff};
                data[2] = 0x04;
                //sprintf(sTemp,"Sending temp request\n");
                //logMsg(sTemp);
                break;
            default:
                data[0]=0x30; //change to request next line message
                data[1]=0x01;
                data[2]=0x00;
                break;
        }
        can1.write(CANMessage(0x79b, data, 8));
        Tcount+=1;
    } else if (Tcount<5){
        showCP=true;
        Tcount+=1;
        can1SleepMode = 1; // disable TX
        can1.monitor(true); // set to snoop mode
    }
}

void tickerISR() {  //This is the ticker ISR for auto-polling
    CPcount=0; //reset CP message counter
    Tcount=0; //reset Temp message counter
}

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;
}

unsigned char buttonX(unsigned short X, unsigned char columns) {
    unsigned char val = X*columns/320;
    return val;
}

unsigned char buttonY(unsigned short Y, unsigned char rows) {
    unsigned short val = Y*rows/240;
    return val;
}

void saveConfig(){
    FILE *cfile;
    cfile = fopen("/local/config.txt", "w");
    fprintf(cfile,"format 1\r\n");
    fprintf(cfile,"x0_off %d\r\n",tt.x0_off);
    fprintf(cfile,"y0_off %d\r\n",tt.y0_off);
    fprintf(cfile,"x0_pp %d\r\n",tt.x0_pp);
    fprintf(cfile,"y0_pp %d\r\n",tt.y0_pp);
    fprintf(cfile,"x1_off %d\r\n",tt.x1_off);
    fprintf(cfile,"y1_off %d\r\n",tt.y1_off);
    fprintf(cfile,"x1_pp %d\r\n",tt.x1_pp);
    fprintf(cfile,"y1_pp %d\r\n",tt.y1_pp);
    fprintf(cfile,"x_mid %d\r\n",tt.x_mid);
    if (dMode[0]==config1Screen)
        fprintf(cfile,"dMode0 %d\r\n",dteScreen);
    else
        fprintf(cfile,"dMode0 %d\r\n",dMode[0]);
    if (dMode[1]==config1Screen)
        fprintf(cfile,"dMode1 %d\r\n",dteScreen);
    else
        fprintf(cfile,"dMode1 %d\r\n",dMode[1]);
    fclose(cfile);
}

 void readConfig(){
    FILE *cfile;
    int ff;
    char sTemp[40];
    cfile = fopen("/local/config.txt", "r");
    if (cfile==NULL){ // if doesn't exist --> create
        sprintf(sTemp,"No config file found.\n");
        logMsg(sTemp);
        sprintf(sTemp,"Calibrating touch screen.\n");
        logMsg(sTemp);
        //tt.setcal(5570, 34030, 80, 108, 33700, 5780, 82, 108, 32500);// bypass calibration using my values
        tt.calibrate();   // run touchscreen calibration routine
        saveConfig();
    } else {
        sprintf(sTemp,"Reading config file.\n");
        logMsg(sTemp);
        //tt.setcal(5570, 34030, 80, 108, 33700, 5780, 82, 108, 32500);// bypass calibration using my values
        fscanf(cfile, "format %c\r\n", &ff ) ;
        fscanf(cfile, "x0_off %d\r\n", &tt.x0_off ) ;
        fscanf(cfile, "y0_off %d\r\n", &tt.y0_off ) ;
        fscanf(cfile, "x0_pp %d\r\n", &tt.x0_pp ) ;
        fscanf(cfile, "y0_pp %d\r\n", &tt.y0_pp ) ;
        fscanf(cfile, "x1_off %d\r\n", &tt.x1_off ) ;
        fscanf(cfile, "y1_off %d\r\n", &tt.y1_off ) ;
        fscanf(cfile, "x1_pp %d\r\n", &tt.x1_pp ) ;
        fscanf(cfile, "y1_pp %d\r\n", &tt.y1_pp ) ;
        fscanf(cfile, "x_mid %d\r\n", &tt.x_mid ) ;
        fscanf(cfile, "dMode0 %d\r\n", &dMode[0] ) ;
        fscanf(cfile, "dMode1 %d\r\n", &dMode[1] ) ;
        fclose(cfile);
    }
}

void upDate(unsigned char field, bool upDownBar){
    struct tm t; // pointer to a static tm structure
    time_t seconds ;
    seconds = time(NULL);
    t = *localtime(&seconds) ;
    switch(field){
        case 0: // year
            if (upDownBar) {
                t.tm_year = t.tm_year+1;
            } else {
                t.tm_year = t.tm_year-1;
            }
            break;
        case 1: // month
            if (upDownBar) {
                t.tm_mon = (t.tm_mon<12)?t.tm_mon+1:1;
            } else {
                t.tm_mon = (t.tm_mon>2)?t.tm_mon-1:12;
            }
            break;
        case 2: // day
            if (upDownBar) {
                t.tm_mday = (t.tm_mday<31)?t.tm_mday+1:1;
            } else {
                t.tm_mday = (t.tm_mday>2)?t.tm_mday-1:31;
            }
            break;
        case 3: // hour
            if (upDownBar) {
                t.tm_hour = (t.tm_hour<23)?t.tm_hour+1:0;
            } else {
                t.tm_hour = (t.tm_hour>1)?t.tm_hour-1:23;
            }
            break;
        case 4: // minute
            if (upDownBar) {
                t.tm_min = (t.tm_min<59)?t.tm_min+1:0;
            } else {
                t.tm_min = (t.tm_min>1)?t.tm_min-1:59;
            }
            break;
        case 5: // second
            if (upDownBar) {
                t.tm_sec = (t.tm_sec<59)?t.tm_sec+1:0;
            } else {
                t.tm_sec = (t.tm_sec>1)?t.tm_sec-1:59;
            }
            break;
        default:
            break;
    }
    set_time(mktime(&t));
}