.
Dependencies: SDHCFileSystem mbed
main.cpp@24:4c823092012a, 2013-07-17 (annotated)
- Committer:
- TickTock
- Date:
- Wed Jul 17 19:09:27 2013 +0000
- Revision:
- 24:4c823092012a
- Parent:
- 23:7e6a9684f647
- Child:
- 25:bfbe84136774
Added cellpair polling
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
TickTock | 1:dafb963c3c14 | 1 | //CANcan.cpp |
TickTock | 8:6872945e8e91 | 2 | //A dual canbus monitoring "blackbox" application for the Nissan Leaf |
TickTock | 8:6872945e8e91 | 3 | //Dumps all messages to a file on the SDRAM |
TickTock | 8:6872945e8e91 | 4 | //Todo: |
TickTock | 15:3ff21ce810da | 5 | // Get timestamp on files |
TickTock | 8:6872945e8e91 | 6 | // |
TickTock | 8:6872945e8e91 | 7 | // Connections: |
TickTock | 1:dafb963c3c14 | 8 | //LEAF OBD |
TickTock | 7:281df0ba57d0 | 9 | //1: |
TickTock | 1:dafb963c3c14 | 10 | //2: |
TickTock | 1:dafb963c3c14 | 11 | //3: AVCAN-L White/Blue |
TickTock | 7:281df0ba57d0 | 12 | //4: |
TickTock | 1:dafb963c3c14 | 13 | //5: VSS Brown,White/Brown |
TickTock | 7:281df0ba57d0 | 14 | //6: CARCAN-H Green --> VP230b:7 |
TickTock | 1:dafb963c3c14 | 15 | //7: |
TickTock | 1:dafb963c3c14 | 16 | //8: 12V-SW Orange,White/Orange |
TickTock | 1:dafb963c3c14 | 17 | //9: |
TickTock | 1:dafb963c3c14 | 18 | //10: |
TickTock | 1:dafb963c3c14 | 19 | //11: AVCAN-H Blue |
TickTock | 7:281df0ba57d0 | 20 | //12: EVCAN-L White/Grey --> VP230a:6 |
TickTock | 7:281df0ba57d0 | 21 | //13: EVCAN-H Grey --> VP230a:7 |
TickTock | 7:281df0ba57d0 | 22 | //14: CARCAN-L White/Green --> VP230b:6 |
TickTock | 7:281df0ba57d0 | 23 | //15: 6V |
TickTock | 7:281df0ba57d0 | 24 | //16: 12V-AON Red/Blue,Blue/Red ----|<---- LPC1768:2 |
TickTock | 7:281df0ba57d0 | 25 | //note 1: pins 4 & 5 longer |
TickTock | 7:281df0ba57d0 | 26 | //note 2: pins 12 & 13 next to key |
TickTock | 7:281df0ba57d0 | 27 | //note 3: pins 1 & 9 on right side looking into male connector with key on bottom |
TickTock | 1:dafb963c3c14 | 28 | |
TickTock | 8:6872945e8e91 | 29 | //VP230{a,b} |
TickTock | 1:dafb963c3c14 | 30 | //1:D |
TickTock | 1:dafb963c3c14 | 31 | //2:GND |
TickTock | 1:dafb963c3c14 | 32 | //3:VCC |
TickTock | 1:dafb963c3c14 | 33 | //4:R |
TickTock | 1:dafb963c3c14 | 34 | //5:Vref |
TickTock | 7:281df0ba57d0 | 35 | //6:CANL --> OBD:12,14 |
TickTock | 7:281df0ba57d0 | 36 | //7:CANH --> OBD:13,6 |
TickTock | 7:281df0ba57d0 | 37 | //8:RS --> LPC1768:27,28 |
TickTock | 0:1596b8644523 | 38 | |
TickTock | 0:1596b8644523 | 39 | //LPC1768 |
TickTock | 8:6872945e8e91 | 40 | //1: VSS 6V |
TickTock | 8:6872945e8e91 | 41 | //2: VIN (4.5-9V supply) ---->|---- OBD:16 |
TickTock | 0:1596b8644523 | 42 | //3: NC:VB |
TickTock | 0:1596b8644523 | 43 | //4: NC:nR |
TickTock | 0:1596b8644523 | 44 | //5: SPI:MOSI --> 6:SDRAM:DI |
TickTock | 0:1596b8644523 | 45 | //6: SPI:MISO --> 2:SDRAM:DO |
TickTock | 0:1596b8644523 | 46 | //7: SPI:SCLK --> 4:SDRAM:SCLK |
TickTock | 0:1596b8644523 | 47 | //8: CS --> 7:SDRAM:CS |
TickTock | 1:dafb963c3c14 | 48 | //9: CAN1:RX --> 4:CAN1:R |
TickTock | 1:dafb963c3c14 | 49 | //10: CAN1:TX --> 1:CAN1:D |
TickTock | 8:6872945e8e91 | 50 | //11: NC:RS --> 4:LCD:RS |
TickTock | 8:6872945e8e91 | 51 | //12: NC:E --> 6:LCD:E |
TickTock | 8:6872945e8e91 | 52 | //13: NC:D4 --> 11:LCD:D4 |
TickTock | 8:6872945e8e91 | 53 | //14: NC:D5 --> 12:LCD:D5 |
TickTock | 8:6872945e8e91 | 54 | //15: NC:D6 --> 13:LCD:D6 |
TickTock | 8:6872945e8e91 | 55 | //16: NC:D7 --> 14:LCD:D7 |
TickTock | 0:1596b8644523 | 56 | //17: CD --> 1:SDRAM:CD |
TickTock | 8:6872945e8e91 | 57 | //18: NC:MON12V --> 4K to 12V, 1K to VSS (To be implemented) |
TickTock | 0:1596b8644523 | 58 | //19: PB2 |
TickTock | 0:1596b8644523 | 59 | //20: PB1 |
TickTock | 8:6872945e8e91 | 60 | //21: NC:Spkr+ |
TickTock | 8:6872945e8e91 | 61 | //22: NC:Spkr- (optional complimentary output for more volume) |
TickTock | 0:1596b8644523 | 62 | //23: NC:pwm |
TickTock | 8:6872945e8e91 | 63 | //24: NC:LEDBLU --> 18:LCD:BLU (only used for tri-color displays) |
TickTock | 8:6872945e8e91 | 64 | //25: NC:LEDGRN --> 17:LCD:GRN (only used for tri-color displays) |
TickTock | 8:6872945e8e91 | 65 | //26: NC:LEDRED --> 16:LCD:RED |
TickTock | 0:1596b8644523 | 66 | //27: CAN1:Sleep --> 8:CAN1:RS |
TickTock | 0:1596b8644523 | 67 | //28: CAN2:Sleep --> 8:CAN2:RS |
TickTock | 1:dafb963c3c14 | 68 | //29: CAN2:TX --> 1:CAN2:D |
TickTock | 1:dafb963c3c14 | 69 | //30: CAN2:RX --> 4:CAN2:R |
TickTock | 0:1596b8644523 | 70 | //31: NC:USB_D+ |
TickTock | 0:1596b8644523 | 71 | //32: NC:USB_D- |
TickTock | 0:1596b8644523 | 72 | //33: NC:Eth_TD+ |
TickTock | 0:1596b8644523 | 73 | //34: NC:Eth_TD- |
TickTock | 0:1596b8644523 | 74 | //35: NC:Eth_RD+ |
TickTock | 0:1596b8644523 | 75 | //36: NC:Eth_RD- |
TickTock | 0:1596b8644523 | 76 | //37: NC:IF+ |
TickTock | 0:1596b8644523 | 77 | //38: NC:IF- |
TickTock | 1:dafb963c3c14 | 78 | //39: NC:5Vout (only available when connected as USB device) |
TickTock | 0:1596b8644523 | 79 | //40: VCC3.3 |
TickTock | 0:1596b8644523 | 80 | |
TickTock | 8:6872945e8e91 | 81 | #include "mbed.h" |
TickTock | 8:6872945e8e91 | 82 | #include "CAN.h" |
TickTock | 8:6872945e8e91 | 83 | #include "SDHCFileSystem.h" |
TickTock | 8:6872945e8e91 | 84 | |
TickTock | 8:6872945e8e91 | 85 | #define upLine "\033[1A" |
TickTock | 8:6872945e8e91 | 86 | #define maxBufLen 2048 |
TickTock | 8:6872945e8e91 | 87 | #define canTimeout 5 |
TickTock | 19:610a71236b6e | 88 | #define maxFileNum 30 |
TickTock | 24:4c823092012a | 89 | #define pollInt 60 |
TickTock | 24:4c823092012a | 90 | #define BatDataBaseG1 0x00 // 6 frames - SOH, SOC, Ah |
TickTock | 24:4c823092012a | 91 | #define BatDataBaseG2 0x06 // 29 frames - Cell Pair data |
TickTock | 24:4c823092012a | 92 | #define BatDataBaseG3 0x23 // 5 frames |
TickTock | 24:4c823092012a | 93 | #define BatDataBaseG4 0x28 // 3 frames - Temperature data |
TickTock | 24:4c823092012a | 94 | #define BatDataBaseG5 0x2B // 11 frames |
TickTock | 24:4c823092012a | 95 | #define BatDataBaseG6 0x36 // 4 frames |
TickTock | 24:4c823092012a | 96 | #define BatDataBaseG7 0x3A |
TickTock | 24:4c823092012a | 97 | #define BatDataBufMax 0x196 // 7 x 3A bytes |
TickTock | 8:6872945e8e91 | 98 | |
TickTock | 24:4c823092012a | 99 | //void Log (char *message); |
TickTock | 24:4c823092012a | 100 | //void LogErr (char *message); |
TickTock | 24:4c823092012a | 101 | //void autoPollISR(); |
TickTock | 24:4c823092012a | 102 | //void sendReq(); |
TickTock | 6:594d9717e609 | 103 | extern "C" void mbed_reset(); |
TickTock | 1:dafb963c3c14 | 104 | |
TickTock | 1:dafb963c3c14 | 105 | time_t seconds ; |
TickTock | 9:8396b76e42fc | 106 | DigitalIn CD(p17); |
TickTock | 9:8396b76e42fc | 107 | DigitalIn PB1( p20 ); |
TickTock | 1:dafb963c3c14 | 108 | SDFileSystem sd(p5, p6, p7, p8, "sd" ); // SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) |
TickTock | 1:dafb963c3c14 | 109 | Timer timer; |
TickTock | 0:1596b8644523 | 110 | DigitalOut led1(LED1); |
TickTock | 0:1596b8644523 | 111 | DigitalOut led2(LED2); |
TickTock | 0:1596b8644523 | 112 | DigitalOut led3(LED3); |
TickTock | 0:1596b8644523 | 113 | DigitalOut led4(LED4); |
TickTock | 1:dafb963c3c14 | 114 | CAN can1(p9, p10); // CAN1 uses pins 9 and 10 (rx, tx) and pin 27 (rs) |
TickTock | 2:55b2357f0cf9 | 115 | DigitalOut can1_SleepMode(p27); // Use pin 27 to control the sleep mode of can1 |
TickTock | 1:dafb963c3c14 | 116 | CAN can2(p30, p29); // CAN2 uses pins 30 and 29 (rx, tx) and pin 28 (rs) |
TickTock | 2:55b2357f0cf9 | 117 | DigitalOut can2_SleepMode(p28); // Use pin 28 to control the sleep mode of can2 |
TickTock | 3:51134a275609 | 118 | bool logOpen = false; |
TickTock | 21:a45a999d6da3 | 119 | FILE *rfile; |
TickTock | 2:55b2357f0cf9 | 120 | FILE *file; |
TickTock | 17:f0209f149b3e | 121 | char fileName[35] = "" ; |
TickTock | 4:fb373a391155 | 122 | char writeBuffer[maxBufLen][13]; |
TickTock | 13:544b15b00c2d | 123 | char c; |
TickTock | 11:d97071bf877b | 124 | volatile int writePointer = 0; |
TickTock | 22:605c2f33b340 | 125 | volatile int secsIdle = 0; |
TickTock | 19:610a71236b6e | 126 | volatile bool canIdle = false; |
TickTock | 10:663bff0a6144 | 127 | Serial pc(USBTX, USBRX); |
TickTock | 24:4c823092012a | 128 | Ticker autoPoll; |
TickTock | 24:4c823092012a | 129 | Ticker msgReq; |
TickTock | 24:4c823092012a | 130 | unsigned char reqMsgCnt = 99; |
TickTock | 0:1596b8644523 | 131 | |
TickTock | 2:55b2357f0cf9 | 132 | extern "C" void RTC_IRQHandler() { |
TickTock | 9:8396b76e42fc | 133 | timer.reset(); // zero ms at the-seconds-tic |
TickTock | 10:663bff0a6144 | 134 | canIdle=(++secsIdle>canTimeout); |
TickTock | 8:6872945e8e91 | 135 | LPC_RTC->ILR |= (1<<0); // clear interrupt to prepare for next |
TickTock | 2:55b2357f0cf9 | 136 | } |
TickTock | 2:55b2357f0cf9 | 137 | |
TickTock | 2:55b2357f0cf9 | 138 | extern "C" void RTC_Init (void) { |
TickTock | 2:55b2357f0cf9 | 139 | LPC_RTC->ILR=0x00; // set up the RTC interrupts |
TickTock | 2:55b2357f0cf9 | 140 | LPC_RTC->CIIR=0x01; // interrupts each second |
TickTock | 8:6872945e8e91 | 141 | LPC_RTC->CCR = 0x01; // Clock enable |
TickTock | 9:8396b76e42fc | 142 | //NVIC_SetPriority( RTC_IRQn, 10 ); |
TickTock | 2:55b2357f0cf9 | 143 | NVIC_EnableIRQ( RTC_IRQn ); |
TickTock | 2:55b2357f0cf9 | 144 | } |
TickTock | 2:55b2357f0cf9 | 145 | |
TickTock | 2:55b2357f0cf9 | 146 | unsigned short getTimeStamp() { |
TickTock | 2:55b2357f0cf9 | 147 | int msec = timer.read_ms() ; // read ms from the timer |
TickTock | 2:55b2357f0cf9 | 148 | unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900 |
TickTock | 2:55b2357f0cf9 | 149 | int isecs = secs%60 ; // modulo 60 for 0-59 seconds from RTC |
TickTock | 2:55b2357f0cf9 | 150 | return ((isecs<<10)+msec) ; // return the two byte time stamp |
TickTock | 1:dafb963c3c14 | 151 | } |
TickTock | 1:dafb963c3c14 | 152 | |
TickTock | 2:55b2357f0cf9 | 153 | void readLog (){ |
TickTock | 2:55b2357f0cf9 | 154 | unsigned char c; |
TickTock | 2:55b2357f0cf9 | 155 | int i=0; |
TickTock | 3:51134a275609 | 156 | char lastMsgNum[]={0,0}; |
TickTock | 3:51134a275609 | 157 | char curMsgNum[]={0,0}; |
TickTock | 3:51134a275609 | 158 | char canNum=0; |
TickTock | 2:55b2357f0cf9 | 159 | pc.printf("printing file\n"); |
TickTock | 2:55b2357f0cf9 | 160 | file = fopen(fileName, "r"); |
TickTock | 2:55b2357f0cf9 | 161 | if (file == NULL) { |
TickTock | 2:55b2357f0cf9 | 162 | pc.printf("no file found\n"); |
TickTock | 1:dafb963c3c14 | 163 | } |
TickTock | 2:55b2357f0cf9 | 164 | while (!feof(file)) { |
TickTock | 2:55b2357f0cf9 | 165 | c=fgetc(file); |
TickTock | 2:55b2357f0cf9 | 166 | pc.printf("%02x ",c); |
TickTock | 3:51134a275609 | 167 | if (i==0){ |
TickTock | 3:51134a275609 | 168 | canNum=c; |
TickTock | 3:51134a275609 | 169 | }else if (i==5){ |
TickTock | 3:51134a275609 | 170 | curMsgNum[canNum]=c; |
TickTock | 2:55b2357f0cf9 | 171 | } |
TickTock | 2:55b2357f0cf9 | 172 | if (++i>12) { |
TickTock | 3:51134a275609 | 173 | if (curMsgNum[canNum]>(lastMsgNum[canNum]+1)) { |
TickTock | 2:55b2357f0cf9 | 174 | pc.printf(" ***"); |
TickTock | 2:55b2357f0cf9 | 175 | } |
TickTock | 3:51134a275609 | 176 | lastMsgNum[canNum]=curMsgNum[canNum]; |
TickTock | 2:55b2357f0cf9 | 177 | pc.printf("\n"); |
TickTock | 2:55b2357f0cf9 | 178 | i=0; |
TickTock | 2:55b2357f0cf9 | 179 | } |
TickTock | 2:55b2357f0cf9 | 180 | } |
TickTock | 10:663bff0a6144 | 181 | pc.printf("\n\n"); |
TickTock | 2:55b2357f0cf9 | 182 | fclose(file); |
TickTock | 2:55b2357f0cf9 | 183 | } |
TickTock | 1:dafb963c3c14 | 184 | |
TickTock | 2:55b2357f0cf9 | 185 | void logCan (char mtype, CANMessage canRXmsg) { |
TickTock | 2:55b2357f0cf9 | 186 | unsigned short ts = getTimeStamp(); |
TickTock | 11:d97071bf877b | 187 | unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900 |
TickTock | 22:605c2f33b340 | 188 | if(canRXmsg.id>0) { |
TickTock | 22:605c2f33b340 | 189 | writeBuffer[writePointer][0]=mtype; |
TickTock | 22:605c2f33b340 | 190 | writeBuffer[writePointer][1]=((secs%60)<<2)+((ts&0x300)>>8); |
TickTock | 22:605c2f33b340 | 191 | writeBuffer[writePointer][2]=ts&0xff; |
TickTock | 22:605c2f33b340 | 192 | writeBuffer[writePointer][3]=canRXmsg.id&0xff; |
TickTock | 22:605c2f33b340 | 193 | writeBuffer[writePointer][4]=(canRXmsg.id>>8)+(canRXmsg.len<<4); |
TickTock | 22:605c2f33b340 | 194 | for (int i = 5; i<13; i++){ |
TickTock | 22:605c2f33b340 | 195 | writeBuffer[writePointer][i]=canRXmsg.data[i-5]; |
TickTock | 22:605c2f33b340 | 196 | } |
TickTock | 22:605c2f33b340 | 197 | if (++writePointer >= maxBufLen) { |
TickTock | 22:605c2f33b340 | 198 | writePointer = 0; |
TickTock | 22:605c2f33b340 | 199 | led4 = !led4; |
TickTock | 22:605c2f33b340 | 200 | } |
TickTock | 4:fb373a391155 | 201 | } |
TickTock | 1:dafb963c3c14 | 202 | } |
TickTock | 0:1596b8644523 | 203 | |
TickTock | 18:a4cf0547bfc2 | 204 | void logTS () { |
TickTock | 18:a4cf0547bfc2 | 205 | CANMessage tsMsg; |
TickTock | 18:a4cf0547bfc2 | 206 | unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900 |
TickTock | 18:a4cf0547bfc2 | 207 | tsMsg.id=0xfff; |
TickTock | 18:a4cf0547bfc2 | 208 | tsMsg.len=0xf; |
TickTock | 18:a4cf0547bfc2 | 209 | tsMsg.data[0]=secs&0xff; |
TickTock | 18:a4cf0547bfc2 | 210 | tsMsg.data[1]=(secs>>8)&0xff; |
TickTock | 18:a4cf0547bfc2 | 211 | tsMsg.data[2]=(secs>>16)&0xff; |
TickTock | 18:a4cf0547bfc2 | 212 | tsMsg.data[3]=secs>>24; |
TickTock | 18:a4cf0547bfc2 | 213 | tsMsg.data[4]=0xff; |
TickTock | 18:a4cf0547bfc2 | 214 | tsMsg.data[5]=0xff; |
TickTock | 18:a4cf0547bfc2 | 215 | tsMsg.data[6]=0xff; |
TickTock | 18:a4cf0547bfc2 | 216 | tsMsg.data[7]=0xff; |
TickTock | 18:a4cf0547bfc2 | 217 | logCan(0,tsMsg); |
TickTock | 18:a4cf0547bfc2 | 218 | } |
TickTock | 0:1596b8644523 | 219 | void recieve1() { |
TickTock | 2:55b2357f0cf9 | 220 | CANMessage msg1; |
TickTock | 9:8396b76e42fc | 221 | secsIdle=0; // reset deadman switch |
TickTock | 0:1596b8644523 | 222 | can1.read(msg1); |
TickTock | 11:d97071bf877b | 223 | if(logOpen) |
TickTock | 22:605c2f33b340 | 224 | logCan(2, msg1); |
TickTock | 11:d97071bf877b | 225 | led1 = !led1; |
TickTock | 0:1596b8644523 | 226 | } |
TickTock | 2:55b2357f0cf9 | 227 | |
TickTock | 0:1596b8644523 | 228 | void recieve2() { |
TickTock | 2:55b2357f0cf9 | 229 | CANMessage msg2; |
TickTock | 9:8396b76e42fc | 230 | secsIdle=0; // reset deadman switch |
TickTock | 0:1596b8644523 | 231 | can2.read(msg2); |
TickTock | 11:d97071bf877b | 232 | if(logOpen) |
TickTock | 22:605c2f33b340 | 233 | logCan(1, msg2); |
TickTock | 11:d97071bf877b | 234 | led2 = !led2; |
TickTock | 0:1596b8644523 | 235 | } |
TickTock | 0:1596b8644523 | 236 | |
TickTock | 24:4c823092012a | 237 | void sendReq() { |
TickTock | 24:4c823092012a | 238 | static char data[8] = {0x02, 0x21, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff}; |
TickTock | 24:4c823092012a | 239 | if(reqMsgCnt<99){ |
TickTock | 24:4c823092012a | 240 | switch (reqMsgCnt){ |
TickTock | 24:4c823092012a | 241 | case BatDataBaseG1: |
TickTock | 24:4c823092012a | 242 | can1.monitor(false); // set to active mode |
TickTock | 24:4c823092012a | 243 | can1_SleepMode = 0; // enable TX |
TickTock | 24:4c823092012a | 244 | data[0]=0x02; //change to request group 1 |
TickTock | 24:4c823092012a | 245 | data[1]=0x21; |
TickTock | 24:4c823092012a | 246 | data[2]=0x01; |
TickTock | 24:4c823092012a | 247 | break; |
TickTock | 24:4c823092012a | 248 | case BatDataBaseG2: // group 1 has 6 frames |
TickTock | 24:4c823092012a | 249 | data[0]=0x02; //change to request group 2 (cp data) |
TickTock | 24:4c823092012a | 250 | data[1]=0x21; |
TickTock | 24:4c823092012a | 251 | data[2]=0x02; |
TickTock | 24:4c823092012a | 252 | break; |
TickTock | 24:4c823092012a | 253 | case BatDataBaseG3: // group 2 has 29 frames |
TickTock | 24:4c823092012a | 254 | data[0]=0x02; //change to request group 3 |
TickTock | 24:4c823092012a | 255 | data[1]=0x21; |
TickTock | 24:4c823092012a | 256 | data[2]=0x03; |
TickTock | 24:4c823092012a | 257 | break; |
TickTock | 24:4c823092012a | 258 | case BatDataBaseG4: // group 3 has 5 frames |
TickTock | 24:4c823092012a | 259 | data[0]=0x02; //change to request group 4 (temperature) |
TickTock | 24:4c823092012a | 260 | data[1]=0x21; |
TickTock | 24:4c823092012a | 261 | data[2]=0x04; |
TickTock | 24:4c823092012a | 262 | break; |
TickTock | 24:4c823092012a | 263 | case BatDataBaseG5: // group 4 has 3 frames |
TickTock | 24:4c823092012a | 264 | data[0]=0x02; //change to request group 5 |
TickTock | 24:4c823092012a | 265 | data[1]=0x21; |
TickTock | 24:4c823092012a | 266 | data[2]=0x05; |
TickTock | 24:4c823092012a | 267 | break; |
TickTock | 24:4c823092012a | 268 | case BatDataBaseG6: // group 4 has 3 frames |
TickTock | 24:4c823092012a | 269 | data[0]=0x02; //change to request group 5 |
TickTock | 24:4c823092012a | 270 | data[1]=0x21; |
TickTock | 24:4c823092012a | 271 | data[2]=0x06; |
TickTock | 24:4c823092012a | 272 | break; |
TickTock | 24:4c823092012a | 273 | case BatDataBaseG7: // group 5 has 11 frames |
TickTock | 24:4c823092012a | 274 | reqMsgCnt = 99; |
TickTock | 24:4c823092012a | 275 | can1_SleepMode = 1; // disable TX |
TickTock | 24:4c823092012a | 276 | can1.monitor(true); // set to snoop mode |
TickTock | 24:4c823092012a | 277 | msgReq.detach(); // stop ticker |
TickTock | 24:4c823092012a | 278 | default: |
TickTock | 24:4c823092012a | 279 | data[0]=0x30; //change to request next line message |
TickTock | 24:4c823092012a | 280 | data[1]=0x01; |
TickTock | 24:4c823092012a | 281 | data[2]=0x00; |
TickTock | 24:4c823092012a | 282 | } |
TickTock | 24:4c823092012a | 283 | can1.write(CANMessage(0x79b, data, 8)); |
TickTock | 24:4c823092012a | 284 | reqMsgCnt++; |
TickTock | 24:4c823092012a | 285 | } |
TickTock | 24:4c823092012a | 286 | } |
TickTock | 24:4c823092012a | 287 | |
TickTock | 24:4c823092012a | 288 | void autoPollISR(){ |
TickTock | 24:4c823092012a | 289 | reqMsgCnt = 0; //reset message counter |
TickTock | 24:4c823092012a | 290 | msgReq.attach(&sendReq,0.015); |
TickTock | 24:4c823092012a | 291 | } |
TickTock | 24:4c823092012a | 292 | |
TickTock | 0:1596b8644523 | 293 | int main() { |
TickTock | 9:8396b76e42fc | 294 | int readPointer=0; |
TickTock | 21:a45a999d6da3 | 295 | int fmon; |
TickTock | 21:a45a999d6da3 | 296 | int fday; |
TickTock | 21:a45a999d6da3 | 297 | int ftime; |
TickTock | 21:a45a999d6da3 | 298 | char sTemp[35]; |
TickTock | 11:d97071bf877b | 299 | unsigned long secs; |
TickTock | 22:605c2f33b340 | 300 | bool bit = false; |
TickTock | 10:663bff0a6144 | 301 | pc.baud(460800); // change serial interface to pc to 450800, 8N1 |
TickTock | 7:281df0ba57d0 | 302 | can1.frequency(500000); |
TickTock | 7:281df0ba57d0 | 303 | can2.frequency(500000); |
TickTock | 10:663bff0a6144 | 304 | can1_SleepMode = 1; // Monitor_only Mode |
TickTock | 10:663bff0a6144 | 305 | can2_SleepMode = 1; // Monitor_only Mode |
TickTock | 0:1596b8644523 | 306 | CD.mode(PullUp) ; //SDRAM Chip Detect |
TickTock | 2:55b2357f0cf9 | 307 | PB1.mode(PullUp) ; //Pushbutton 1 |
TickTock | 0:1596b8644523 | 308 | can1.attach(&recieve1); |
TickTock | 0:1596b8644523 | 309 | can2.attach(&recieve2); |
TickTock | 24:4c823092012a | 310 | autoPoll.attach(&autoPollISR,pollInt); // Poll battery data every 60 seconds |
TickTock | 24:4c823092012a | 311 | msgReq.attach(&sendReq,0.015); // Each poll message separated by 15ms |
TickTock | 24:4c823092012a | 312 | |
TickTock | 1:dafb963c3c14 | 313 | timer.start() ; |
TickTock | 2:55b2357f0cf9 | 314 | RTC_Init(); // start the RTC Interrupts that sync the timer |
TickTock | 12:7cd4e9303165 | 315 | |
TickTock | 12:7cd4e9303165 | 316 | struct tm t; // pointer to a static tm structure |
TickTock | 12:7cd4e9303165 | 317 | |
TickTock | 12:7cd4e9303165 | 318 | seconds = time(NULL); |
TickTock | 12:7cd4e9303165 | 319 | t = *localtime(&seconds) ; |
TickTock | 14:ed5d2a503374 | 320 | strftime(sTemp, 32, "%a %m/%d/%Y %X", &t); |
TickTock | 14:ed5d2a503374 | 321 | pc.printf("\nCurrent time set to: %s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS |
TickTock | 14:ed5d2a503374 | 322 | wait(1.1); // give time to sync |
TickTock | 14:ed5d2a503374 | 323 | |
TickTock | 14:ed5d2a503374 | 324 | if (PB1==0) { //set time if pb pressed |
TickTock | 12:7cd4e9303165 | 325 | |
TickTock | 13:544b15b00c2d | 326 | pc.printf("\nEnter year (yyyy):"); |
TickTock | 13:544b15b00c2d | 327 | pc.scanf("%s", &sTemp); |
TickTock | 13:544b15b00c2d | 328 | t.tm_year = atoi(sTemp); |
TickTock | 13:544b15b00c2d | 329 | |
TickTock | 13:544b15b00c2d | 330 | pc.printf("\nEnter month (mm):"); |
TickTock | 13:544b15b00c2d | 331 | pc.scanf("%2s", &sTemp); |
TickTock | 13:544b15b00c2d | 332 | t.tm_mon = atoi(sTemp); |
TickTock | 13:544b15b00c2d | 333 | |
TickTock | 13:544b15b00c2d | 334 | pc.printf("\nEnter day (dd):"); |
TickTock | 13:544b15b00c2d | 335 | pc.scanf("%2s", &sTemp); |
TickTock | 13:544b15b00c2d | 336 | t.tm_mday = atoi(sTemp); |
TickTock | 13:544b15b00c2d | 337 | |
TickTock | 13:544b15b00c2d | 338 | pc.printf("\nEnter hour (hh):"); |
TickTock | 13:544b15b00c2d | 339 | pc.scanf("%2s", &sTemp); |
TickTock | 13:544b15b00c2d | 340 | t.tm_hour = atoi(sTemp); |
TickTock | 13:544b15b00c2d | 341 | |
TickTock | 13:544b15b00c2d | 342 | pc.printf("\nEnter minute (mm):"); |
TickTock | 13:544b15b00c2d | 343 | pc.scanf("%2s", &sTemp); |
TickTock | 13:544b15b00c2d | 344 | t.tm_min = atoi(sTemp); |
TickTock | 13:544b15b00c2d | 345 | |
TickTock | 13:544b15b00c2d | 346 | pc.printf("\nEnter seconds (ss):"); |
TickTock | 13:544b15b00c2d | 347 | pc.scanf("%2s", &sTemp); |
TickTock | 13:544b15b00c2d | 348 | t.tm_sec = atoi(sTemp); |
TickTock | 12:7cd4e9303165 | 349 | |
TickTock | 12:7cd4e9303165 | 350 | // adjust for tm structure required values |
TickTock | 12:7cd4e9303165 | 351 | t.tm_year = t.tm_year - 1900; |
TickTock | 12:7cd4e9303165 | 352 | t.tm_mon = t.tm_mon - 1; |
TickTock | 12:7cd4e9303165 | 353 | |
TickTock | 12:7cd4e9303165 | 354 | // set the RTC |
TickTock | 12:7cd4e9303165 | 355 | set_time(mktime(&t)); |
TickTock | 12:7cd4e9303165 | 356 | seconds = time(NULL); |
TickTock | 12:7cd4e9303165 | 357 | |
TickTock | 14:ed5d2a503374 | 358 | pc.printf("\nRTC set to: " ); |
TickTock | 12:7cd4e9303165 | 359 | strftime(sTemp, 32, "%a %m/%d/%Y %X", localtime(&seconds)); |
TickTock | 12:7cd4e9303165 | 360 | pc.printf("%s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS |
TickTock | 12:7cd4e9303165 | 361 | } |
TickTock | 21:a45a999d6da3 | 362 | |
TickTock | 6:594d9717e609 | 363 | while (true) { |
TickTock | 6:594d9717e609 | 364 | if(CD == 1) { |
TickTock | 11:d97071bf877b | 365 | if (!logOpen) { // Open new file if one is not already open |
TickTock | 22:605c2f33b340 | 366 | seconds = time(NULL); |
TickTock | 21:a45a999d6da3 | 367 | t = *localtime(&seconds) ; |
TickTock | 21:a45a999d6da3 | 368 | strftime(fileName, 32, "/sd/%m%d%H%M.alc", &t); //mmddhhmm.alc |
TickTock | 21:a45a999d6da3 | 369 | |
TickTock | 15:3ff21ce810da | 370 | pc.printf("Using file %s\n",fileName); |
TickTock | 21:a45a999d6da3 | 371 | file = fopen(fileName, "ab"); |
TickTock | 23:7e6a9684f647 | 372 | pc.printf("Using file2 %s\n",fileName); |
TickTock | 15:3ff21ce810da | 373 | |
TickTock | 11:d97071bf877b | 374 | if(file==NULL){ |
TickTock | 11:d97071bf877b | 375 | pc.printf("\nUnable to open canlog\n\n\n\n"); |
TickTock | 11:d97071bf877b | 376 | mbed_reset(); |
TickTock | 11:d97071bf877b | 377 | } else { |
TickTock | 11:d97071bf877b | 378 | logOpen = true; |
TickTock | 11:d97071bf877b | 379 | readPointer=writePointer; |
TickTock | 15:3ff21ce810da | 380 | pc.printf("\nStarting Can Log %s\n",fileName); |
TickTock | 18:a4cf0547bfc2 | 381 | logTS(); |
TickTock | 21:a45a999d6da3 | 382 | fclose(file); |
TickTock | 21:a45a999d6da3 | 383 | file = fopen("/sd/loglog.txt", "a"); |
TickTock | 21:a45a999d6da3 | 384 | fprintf(file,"%s\r\n",fileName); |
TickTock | 11:d97071bf877b | 385 | fclose(file); |
TickTock | 11:d97071bf877b | 386 | } |
TickTock | 11:d97071bf877b | 387 | } // if (!logOpen) |
TickTock | 9:8396b76e42fc | 388 | do { |
TickTock | 10:663bff0a6144 | 389 | if (((writePointer+maxBufLen-readPointer)%maxBufLen)>(maxBufLen/2)||canIdle||(PB1==0)) { |
TickTock | 10:663bff0a6144 | 390 | // Dump buffer if > 1/2 full, canbus has stopped, or PB1 pressed |
TickTock | 9:8396b76e42fc | 391 | if (logOpen) { |
TickTock | 9:8396b76e42fc | 392 | file = fopen(fileName, "ab"); |
TickTock | 9:8396b76e42fc | 393 | if (file == NULL) { |
TickTock | 9:8396b76e42fc | 394 | logOpen = false; |
TickTock | 9:8396b76e42fc | 395 | pc.printf("Failed to append log file.\n\n"); |
TickTock | 9:8396b76e42fc | 396 | } else { |
TickTock | 9:8396b76e42fc | 397 | while (readPointer != writePointer) { |
TickTock | 9:8396b76e42fc | 398 | for (int j = 0; j<13; j++){ |
TickTock | 9:8396b76e42fc | 399 | fprintf(file,"%c",writeBuffer[readPointer][j]); |
TickTock | 9:8396b76e42fc | 400 | } |
TickTock | 9:8396b76e42fc | 401 | if(++readPointer >= maxBufLen) |
TickTock | 9:8396b76e42fc | 402 | readPointer=0; |
TickTock | 9:8396b76e42fc | 403 | } |
TickTock | 9:8396b76e42fc | 404 | led3 = !led3; |
TickTock | 9:8396b76e42fc | 405 | fclose(file); |
TickTock | 9:8396b76e42fc | 406 | } |
TickTock | 10:663bff0a6144 | 407 | } // if (logOpen) |
TickTock | 17:f0209f149b3e | 408 | } // if > 1/2 full, canbus has stopped, or PB1 pressed |
TickTock | 10:663bff0a6144 | 409 | if (canIdle) { // canbus idle --> sleep to save power |
TickTock | 21:a45a999d6da3 | 410 | // First take advantage of the idle time to clear some room |
TickTock | 22:605c2f33b340 | 411 | |
TickTock | 22:605c2f33b340 | 412 | bit = false; |
TickTock | 21:a45a999d6da3 | 413 | rfile = fopen("/sd/loglog.txt", "r"); |
TickTock | 21:a45a999d6da3 | 414 | file = fopen("/sd/loglog.new", "w"); |
TickTock | 21:a45a999d6da3 | 415 | while (!feof(rfile)) { |
TickTock | 21:a45a999d6da3 | 416 | fscanf(rfile,"/sd/%2d%2d%4d.alc\r\n",&fmon,&fday,&ftime); |
TickTock | 23:7e6a9684f647 | 417 | //if ((fmon < 12) || (t.tm_mon > 1)){ |
TickTock | 23:7e6a9684f647 | 418 | // fday = fday + fmon*31; //crude - february will store 3 extra days of data |
TickTock | 23:7e6a9684f647 | 419 | //} |
TickTock | 23:7e6a9684f647 | 420 | //if ((fday+14)<(t.tm_mday+t.tm_mon*31)){ // Delete all files more than ~14 days old |
TickTock | 23:7e6a9684f647 | 421 | if (((fmon<=t.tm_mon)&&(fday<t.tm_mday))||(fmon>t.tm_mon+2)){ // Delete all files more than 1 month old |
TickTock | 22:605c2f33b340 | 422 | bit=true; |
TickTock | 21:a45a999d6da3 | 423 | sprintf(sTemp,"/sd/%02d%02d%04d.alc",fmon,fday,ftime); |
TickTock | 22:605c2f33b340 | 424 | if ((remove(sTemp)==NULL)) { |
TickTock | 21:a45a999d6da3 | 425 | pc.printf("Removed file %s\n",sTemp); |
TickTock | 22:605c2f33b340 | 426 | } |
TickTock | 21:a45a999d6da3 | 427 | }else{ |
TickTock | 21:a45a999d6da3 | 428 | fprintf(file,"/sd/%02d%02d%04d.alc\r\n",fmon,fday,ftime); |
TickTock | 21:a45a999d6da3 | 429 | } |
TickTock | 21:a45a999d6da3 | 430 | } |
TickTock | 21:a45a999d6da3 | 431 | fclose (file); |
TickTock | 21:a45a999d6da3 | 432 | fclose (rfile); |
TickTock | 22:605c2f33b340 | 433 | if (bit) { |
TickTock | 22:605c2f33b340 | 434 | remove ("/sd/loglog.txt"); |
TickTock | 22:605c2f33b340 | 435 | //rename not working so do it the hard way |
TickTock | 22:605c2f33b340 | 436 | //rename ("/sd/loglog.new","/sd/loglog.txt"); |
TickTock | 22:605c2f33b340 | 437 | rfile = fopen("/sd/loglog.new", "r"); |
TickTock | 22:605c2f33b340 | 438 | file = fopen("/sd/loglog.txt", "w"); |
TickTock | 22:605c2f33b340 | 439 | while (!feof(rfile)) { |
TickTock | 22:605c2f33b340 | 440 | fscanf(rfile,"%s\r\n",&sTemp); |
TickTock | 22:605c2f33b340 | 441 | fprintf(file,"%s\r\n",sTemp); |
TickTock | 22:605c2f33b340 | 442 | } |
TickTock | 22:605c2f33b340 | 443 | fclose (file); |
TickTock | 22:605c2f33b340 | 444 | fclose (rfile); |
TickTock | 21:a45a999d6da3 | 445 | } |
TickTock | 22:605c2f33b340 | 446 | remove ("/sd/loglog.new"); |
TickTock | 22:605c2f33b340 | 447 | wait(5); // wait a few seconds to ensure SDRAM is done |
TickTock | 21:a45a999d6da3 | 448 | |
TickTock | 17:f0209f149b3e | 449 | pc.printf("Putting uC to sleep.\n"); |
TickTock | 13:544b15b00c2d | 450 | //LPC_RTC->CIIR=0x00; // block RTC interrupts |
TickTock | 10:663bff0a6144 | 451 | led1=0; |
TickTock | 10:663bff0a6144 | 452 | led2=0; |
TickTock | 10:663bff0a6144 | 453 | led3=0; |
TickTock | 10:663bff0a6144 | 454 | led4=0; |
TickTock | 11:d97071bf877b | 455 | secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900 |
TickTock | 22:605c2f33b340 | 456 | while (secsIdle>canTimeout) { |
TickTock | 11:d97071bf877b | 457 | //DeepPowerDown(); |
TickTock | 10:663bff0a6144 | 458 | __wfi(); // freeze CPU and wait for interrupt (from canbus) |
TickTock | 22:605c2f33b340 | 459 | } |
TickTock | 22:605c2f33b340 | 460 | canIdle=false; |
TickTock | 22:605c2f33b340 | 461 | pc.printf("Waking uC.\n"); |
TickTock | 21:a45a999d6da3 | 462 | if (time(NULL)>(secs+1800)) { |
TickTock | 21:a45a999d6da3 | 463 | logOpen = false; // Start new file if asleep for more than 30 minutes |
TickTock | 18:a4cf0547bfc2 | 464 | } else { // insert timestamp on each wake |
TickTock | 18:a4cf0547bfc2 | 465 | logTS(); |
TickTock | 18:a4cf0547bfc2 | 466 | } |
TickTock | 13:544b15b00c2d | 467 | //LPC_RTC->CIIR=0x01; // re-enable RTC interrupts |
TickTock | 9:8396b76e42fc | 468 | } |
TickTock | 17:f0209f149b3e | 469 | wait(0.2); // We get >2K messages per second |
TickTock | 11:d97071bf877b | 470 | } while ((PB1==1)&&(CD==1)&&logOpen); // keep going until button or SDram removed |
TickTock | 9:8396b76e42fc | 471 | |
TickTock | 11:d97071bf877b | 472 | if (PB1==0) { |
TickTock | 11:d97071bf877b | 473 | led1=0; |
TickTock | 11:d97071bf877b | 474 | led2=0; |
TickTock | 11:d97071bf877b | 475 | led3=0; |
TickTock | 11:d97071bf877b | 476 | led4=0; |
TickTock | 11:d97071bf877b | 477 | pc.printf("Log stopped\n\n"); |
TickTock | 11:d97071bf877b | 478 | logOpen=false; |
TickTock | 11:d97071bf877b | 479 | wait(5); // wait 5 seconds to give time to remove SDRAM if desired |
TickTock | 17:f0209f149b3e | 480 | if (PB1==0) |
TickTock | 17:f0209f149b3e | 481 | readLog(); // dump file if PB still pressed |
TickTock | 11:d97071bf877b | 482 | } |
TickTock | 11:d97071bf877b | 483 | } else { |
TickTock | 11:d97071bf877b | 484 | pc.printf("\nNo SDRAM Inserted.\n\n"); |
TickTock | 6:594d9717e609 | 485 | logOpen=false; |
TickTock | 11:d97071bf877b | 486 | led1=!led1; |
TickTock | 11:d97071bf877b | 487 | led2=led1; |
TickTock | 11:d97071bf877b | 488 | led3=led1; |
TickTock | 11:d97071bf877b | 489 | led4=led1; |
TickTock | 11:d97071bf877b | 490 | wait(5); |
TickTock | 10:663bff0a6144 | 491 | } //if (CD==1) |
TickTock | 9:8396b76e42fc | 492 | } //while (true) |
TickTock | 9:8396b76e42fc | 493 | } |