Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SPI_TFTx2 TFT_fonts TOUCH_TFTx2 mbed
Fork of CANary by
main.cpp
- Committer:
- TickTock
- Date:
- 2013-02-11
- Revision:
- 2:71b1999a8ea5
- Parent:
- 1:9dcd70c32180
- Child:
- 3:3e879b043bc5
File content as of revision 2:71b1999a8ea5:
//CANary.cpp
//LEAF OBD
//1:
//2:
//3: AVCAN-L White/Blue
//4:
//5: VSS Brown,White/Brown
//6: CARCAN-H Green
//7:
//8: 12V-SW Orange,White/Orange
//9:
//10:
//11: AVCAN-H Blue
//12: EVCAN-L White/Grey
//13: EVCAN-H Grey
//14: CARCAN-L White/Green
//15:
//16: 12V-AON Red/Blue,Blue/Red
//VP230
//1:D
//2:GND
//3:VCC
//4:R
//5:Vref
//6:CANL
//7:CANH
//8:RS
//LPC1768
//1: VSS
//2: NC:VIN (4.5-9V supply)
//3: NC:VB
//4: NC:nR
//5: SPI:CS0
//6: SPI:CS1
//7: SPI:Reset
//8: CAN1:Sleep --> 8:CAN1:RS
//9: CAN1:RX --> 4:CAN1:R
//10: CAN1:TX --> 1:CAN1:D
//11: SPI:MOSI
//12: SPI:MISO
//13: SPI:SCLK
//14: NC:Ain
//15: MON12V --> 4K to 12V, 1K to VSS (To be implemented)
//16: TOUCH_X+
//17: TOUCH_X-
//18: NC:Aout
//19: TOUCH_Y+
//20: TOUCH_Y-
//21: Spkr+
//22: Spkr- (optional complimentary output for more volume)
//23: NC:pwm
//24: LED
//25: NC:pwm
//26: NC:pwm
//27: NC
//28: CAN2:Sleep --> 8:CAN2:RS
//29: CAN2:TX --> 1:CAN2:D
//30: CAN2:RX --> 4:CAN2:R
//31: USB_D+
//32: 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 "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);
Ticker ticker;
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(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 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
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;
printf("printing file\n");
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;
}
if (++i>12) {
if (curMsgNum[canNum]>(lastMsgNum[canNum]+1)) {
printf(" ***");
}
lastMsgNum[canNum]=curMsgNum[canNum];
printf("\n");
i=0;
}
}
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
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 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() {
static char counter = 0; // use for fake data
can1.write(CANMessage(0x350, &counter, 1));
counter++;
// test sending 3 quickly
//can1.write(CANMessage(0x351, &counter, 1));
//can1.write(CANMessage(0x352, &counter, 1));
printf("Sending message %d \n",counter);
}
void recieve1() {
CANMessage msg1;
secsIdle=0; // reset deadman switch
can1.read(msg1);
//printf("Can1 rxd: %d\n", msg1.data[0]);
if(logOpen)
logCan(2, msg1);
led1 = !led1;
}
void recieve2() {
CANMessage msg2;
secsIdle=0; // reset deadman switch
can2.read(msg2);
//printf("Can2 rxd: %d\n", msg2.data[0]);
if(logOpen)
logCan(1, msg2);
led2 = !led2;
}
int main() {
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.5);
can1.attach(&recieve1);
can2.attach(&recieve2);
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(1); // select left display
//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 ) {
// before 2012, so the RTC probably lost power
// So, set a near-recent date in 2012
// enter people-values here
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;
// 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);
// printf("Set RTC to:\n" );
// 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)
}
