Dual CANbus monitor and instrumentation cluster supporting ILI9341 display controller

Dependencies:   SPI_TFTx2_ILI9341 TOUCH_TFTx2_ILI9341 TFT_fonts mbed

Fork of CANary by Tick Tock

Committer:
TickTock
Date:
Tue Feb 19 18:19:47 2013 +0000
Revision:
5:ebf6fa994b78
Parent:
4:8d7759f4fe7a
Child:
7:17bf9ceaf0aa
Added braking screen and improved config routine;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TickTock 4:8d7759f4fe7a 1 //To Do:
TickTock 5:ebf6fa994b78 2 // USB device detect
TickTock 5:ebf6fa994b78 3 // config file on local fs
TickTock 5:ebf6fa994b78 4 // user programmable message decode
TickTock 5:ebf6fa994b78 5 // brake trainer
TickTock 4:8d7759f4fe7a 6 #include "CANary.h"
TickTock 2:71b1999a8ea5 7 // write and read the Mode Data
TickTock 2:71b1999a8ea5 8 LocalFileSystem local("local"); // test the local file system to write files
TickTock 2:71b1999a8ea5 9
TickTock 2:71b1999a8ea5 10 // to write to USB Flash Drives, or equivalent (SD card in Reader/Writer)
TickTock 2:71b1999a8ea5 11 MSCFileSystem fs("fs"); // to write to a USB Flash Drive
TickTock 2:71b1999a8ea5 12
TickTock 2:71b1999a8ea5 13 extern "C" void mbed_reset();
TickTock 0:1596b8644523 14
TickTock 1:9dcd70c32180 15 time_t seconds ;
TickTock 0:1596b8644523 16 Beep buzzer(p21);
TickTock 1:9dcd70c32180 17
TickTock 0:1596b8644523 18 Ticker ticker;
TickTock 1:9dcd70c32180 19 Timer timer;
TickTock 0:1596b8644523 20 DigitalOut led1(LED1);
TickTock 0:1596b8644523 21 DigitalOut led2(LED2);
TickTock 0:1596b8644523 22 DigitalOut led3(LED3);
TickTock 0:1596b8644523 23 DigitalOut led4(LED4);
TickTock 4:8d7759f4fe7a 24 PwmOut dled(p24);
TickTock 4:8d7759f4fe7a 25
TickTock 4:8d7759f4fe7a 26 InterruptIn touchpad(p17);
TickTock 4:8d7759f4fe7a 27
TickTock 1:9dcd70c32180 28 CAN can1(p9, p10); // CAN1 uses pins 9 and 10 (rx, tx) and pin 27 (rs)
TickTock 1:9dcd70c32180 29 DigitalOut can1_SleepMode(p8); // Use pin 8 to control the sleep mode of can1
TickTock 1:9dcd70c32180 30 CAN can2(p30, p29); // CAN2 uses pins 30 and 29 (rx, tx) and pin 28 (rs)
TickTock 1:9dcd70c32180 31 DigitalOut can2_SleepMode(p28); // Use pin 28 to control the sleep mode of can2
TickTock 2:71b1999a8ea5 32 bool logOpen = false;
TickTock 2:71b1999a8ea5 33 FILE *rfile;
TickTock 2:71b1999a8ea5 34 FILE *file;
TickTock 2:71b1999a8ea5 35 char fileName[35] = "" ;
TickTock 3:3e879b043bc5 36 char writeBuffer[maxBufLen][13]; // buffer for USB write
TickTock 3:3e879b043bc5 37 char indexLastMsg[0x800]={0}; // index table for last message
TickTock 3:3e879b043bc5 38 CANMessage lastMsg[100]; // table to store last message of eachtype
TickTock 2:71b1999a8ea5 39 char c;
TickTock 2:71b1999a8ea5 40 volatile int writePointer = 0;
TickTock 4:8d7759f4fe7a 41 volatile int secsNoMsg = 0, secsNoTouch = 0;
TickTock 4:8d7759f4fe7a 42 volatile bool canIdle = false, userIdle = false;
TickTock 4:8d7759f4fe7a 43 point lastTouch;
TickTock 0:1596b8644523 44 char counter = 0;
TickTock 5:ebf6fa994b78 45 int dMode[2] = {4,2}; //display mode
TickTock 4:8d7759f4fe7a 46 int sMode = 0; // setup mode
TickTock 4:8d7759f4fe7a 47 int lastDMode[2]; //last screen mode
TickTock 4:8d7759f4fe7a 48 int lastSMode = 0;
TickTock 4:8d7759f4fe7a 49 char displayLog[19][40];
TickTock 4:8d7759f4fe7a 50 int displayLoc = 0;
TickTock 5:ebf6fa994b78 51 int indexOffset = 1;
TickTock 1:9dcd70c32180 52
TickTock 1:9dcd70c32180 53 TOUCH_TFTx2 tt(p16, p17, p19, p20, p11, p12, p13, p6, p7, p5, "TFT"); // x+,x-,y+,y-,mosi, miso, sclk, cs0, cs1, reset
TickTock 1:9dcd70c32180 54
TickTock 2:71b1999a8ea5 55 extern "C" void RTC_IRQHandler() {
TickTock 2:71b1999a8ea5 56 timer.reset(); // zero ms at the-seconds-tic
TickTock 4:8d7759f4fe7a 57 canIdle=(++secsNoMsg>canTimeout);
TickTock 4:8d7759f4fe7a 58 userIdle=(++secsNoTouch>userTimeout);
TickTock 2:71b1999a8ea5 59 LPC_RTC->ILR |= (1<<0); // clear interrupt to prepare for next
TickTock 1:9dcd70c32180 60 }
TickTock 1:9dcd70c32180 61
TickTock 2:71b1999a8ea5 62 extern "C" void RTC_Init (void) {
TickTock 2:71b1999a8ea5 63 LPC_RTC->ILR=0x00; // set up the RTC interrupts
TickTock 2:71b1999a8ea5 64 LPC_RTC->CIIR=0x01; // interrupts each second
TickTock 2:71b1999a8ea5 65 LPC_RTC->CCR = 0x01; // Clock enable
TickTock 2:71b1999a8ea5 66 //NVIC_SetPriority( RTC_IRQn, 10 );
TickTock 1:9dcd70c32180 67 NVIC_EnableIRQ( RTC_IRQn );
TickTock 1:9dcd70c32180 68 }
TickTock 1:9dcd70c32180 69
TickTock 2:71b1999a8ea5 70 unsigned short getTimeStamp() {
TickTock 2:71b1999a8ea5 71 int msec = timer.read_ms() ; // read ms from the timer
TickTock 2:71b1999a8ea5 72 unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
TickTock 2:71b1999a8ea5 73 int isecs = secs%60 ; // modulo 60 for 0-59 seconds from RTC
TickTock 2:71b1999a8ea5 74 return ((isecs<<10)+msec) ; // return the two byte time stamp
TickTock 2:71b1999a8ea5 75 }
TickTock 2:71b1999a8ea5 76 void logCan (char mtype, CANMessage canRXmsg) {
TickTock 2:71b1999a8ea5 77 unsigned short ts = getTimeStamp();
TickTock 2:71b1999a8ea5 78 unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
TickTock 5:ebf6fa994b78 79 static char ii = 0; // indexindex
TickTock 2:71b1999a8ea5 80 if(canRXmsg.id>0) {
TickTock 2:71b1999a8ea5 81 writeBuffer[writePointer][0]=mtype;
TickTock 2:71b1999a8ea5 82 writeBuffer[writePointer][1]=((secs%60)<<2)+((ts&0x300)>>8);
TickTock 2:71b1999a8ea5 83 writeBuffer[writePointer][2]=ts&0xff;
TickTock 2:71b1999a8ea5 84 writeBuffer[writePointer][3]=canRXmsg.id&0xff;
TickTock 2:71b1999a8ea5 85 writeBuffer[writePointer][4]=(canRXmsg.id>>8)+(canRXmsg.len<<4);
TickTock 2:71b1999a8ea5 86 for (int i = 5; i<13; i++){
TickTock 2:71b1999a8ea5 87 writeBuffer[writePointer][i]=canRXmsg.data[i-5];
TickTock 2:71b1999a8ea5 88 }
TickTock 2:71b1999a8ea5 89 if (++writePointer >= maxBufLen) {
TickTock 2:71b1999a8ea5 90 writePointer = 0;
TickTock 2:71b1999a8ea5 91 led4 = !led4;
TickTock 2:71b1999a8ea5 92 }
TickTock 3:3e879b043bc5 93 if(indexLastMsg[canRXmsg.id]==0) { //Check if no entry
TickTock 3:3e879b043bc5 94 indexLastMsg[canRXmsg.id]=++ii; //Create entry if first message
TickTock 3:3e879b043bc5 95 if(ii>99) {
TickTock 3:3e879b043bc5 96 ii=0;
TickTock 3:3e879b043bc5 97 }
TickTock 3:3e879b043bc5 98 }
TickTock 3:3e879b043bc5 99 lastMsg[indexLastMsg[canRXmsg.id]]=canRXmsg; //Store in table
TickTock 1:9dcd70c32180 100 }
TickTock 1:9dcd70c32180 101 }
TickTock 0:1596b8644523 102
TickTock 2:71b1999a8ea5 103 void logTS () {
TickTock 2:71b1999a8ea5 104 CANMessage tsMsg;
TickTock 2:71b1999a8ea5 105 unsigned long secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
TickTock 2:71b1999a8ea5 106 tsMsg.id=0xfff;
TickTock 2:71b1999a8ea5 107 tsMsg.len=0xf;
TickTock 2:71b1999a8ea5 108 tsMsg.data[0]=secs&0xff;
TickTock 2:71b1999a8ea5 109 tsMsg.data[1]=(secs>>8)&0xff;
TickTock 2:71b1999a8ea5 110 tsMsg.data[2]=(secs>>16)&0xff;
TickTock 2:71b1999a8ea5 111 tsMsg.data[3]=secs>>24;
TickTock 2:71b1999a8ea5 112 tsMsg.data[4]=0xff;
TickTock 2:71b1999a8ea5 113 tsMsg.data[5]=0xff;
TickTock 2:71b1999a8ea5 114 tsMsg.data[6]=0xff;
TickTock 2:71b1999a8ea5 115 tsMsg.data[7]=0xff;
TickTock 2:71b1999a8ea5 116 logCan(0,tsMsg);
TickTock 1:9dcd70c32180 117 }
TickTock 0:1596b8644523 118
TickTock 1:9dcd70c32180 119 void send1() {
TickTock 1:9dcd70c32180 120 static char counter = 0; // use for fake data
TickTock 1:9dcd70c32180 121
TickTock 1:9dcd70c32180 122 can1.write(CANMessage(0x350, &counter, 1));
TickTock 1:9dcd70c32180 123 counter++;
TickTock 1:9dcd70c32180 124 // test sending 3 quickly
TickTock 1:9dcd70c32180 125 //can1.write(CANMessage(0x351, &counter, 1));
TickTock 1:9dcd70c32180 126 //can1.write(CANMessage(0x352, &counter, 1));
TickTock 2:71b1999a8ea5 127 printf("Sending message %d \n",counter);
TickTock 1:9dcd70c32180 128
TickTock 0:1596b8644523 129 }
TickTock 0:1596b8644523 130
TickTock 0:1596b8644523 131
TickTock 0:1596b8644523 132 void recieve1() {
TickTock 2:71b1999a8ea5 133 CANMessage msg1;
TickTock 4:8d7759f4fe7a 134 secsNoMsg=0; // reset deadman switch
TickTock 0:1596b8644523 135 can1.read(msg1);
TickTock 2:71b1999a8ea5 136 //printf("Can1 rxd: %d\n", msg1.data[0]);
TickTock 2:71b1999a8ea5 137 if(logOpen)
TickTock 2:71b1999a8ea5 138 logCan(2, msg1);
TickTock 2:71b1999a8ea5 139 led1 = !led1;
TickTock 0:1596b8644523 140 }
TickTock 2:71b1999a8ea5 141
TickTock 0:1596b8644523 142 void recieve2() {
TickTock 2:71b1999a8ea5 143 CANMessage msg2;
TickTock 4:8d7759f4fe7a 144 secsNoMsg=0; // reset deadman switch
TickTock 0:1596b8644523 145 can2.read(msg2);
TickTock 2:71b1999a8ea5 146 //printf("Can2 rxd: %d\n", msg2.data[0]);
TickTock 2:71b1999a8ea5 147 if(logOpen)
TickTock 2:71b1999a8ea5 148 logCan(1, msg2);
TickTock 2:71b1999a8ea5 149 led2 = !led2;
TickTock 0:1596b8644523 150 }
TickTock 0:1596b8644523 151
TickTock 5:ebf6fa994b78 152 void logMsg (char *msg) {
TickTock 5:ebf6fa994b78 153 strcpy(displayLog[displayLoc],msg);
TickTock 5:ebf6fa994b78 154 displayLoc=displayLoc>17?0:displayLoc+1;
TickTock 5:ebf6fa994b78 155 }
TickTock 5:ebf6fa994b78 156
TickTock 4:8d7759f4fe7a 157 void touched(){
TickTock 4:8d7759f4fe7a 158 LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF);
TickTock 4:8d7759f4fe7a 159 lastTouch = tt.get_touch();
TickTock 4:8d7759f4fe7a 160 lastTouch = tt.to_pixel(lastTouch); // convert to pixel pos
TickTock 4:8d7759f4fe7a 161 secsNoTouch = 0;
TickTock 4:8d7759f4fe7a 162 }
TickTock 4:8d7759f4fe7a 163
TickTock 5:ebf6fa994b78 164 void printLast (bool force){
TickTock 5:ebf6fa994b78 165 CANMessage msg;
TickTock 5:ebf6fa994b78 166 if(force) tt.cls();
TickTock 5:ebf6fa994b78 167 tt.locate(0,6);
TickTock 5:ebf6fa994b78 168 tt.foreground(Red);
TickTock 5:ebf6fa994b78 169 tt.background(Yellow);
TickTock 5:ebf6fa994b78 170 if(force) tt.cls(); // Just clear screen if forced - always update display
TickTock 5:ebf6fa994b78 171 tt.set_font((unsigned char*) Arial12x12_prop); // select the font
TickTock 5:ebf6fa994b78 172 for(int i=0; i<19; i++){
TickTock 5:ebf6fa994b78 173 msg = lastMsg[i+indexOffset];
TickTock 5:ebf6fa994b78 174 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]);
TickTock 5:ebf6fa994b78 175 }
TickTock 5:ebf6fa994b78 176 }
TickTock 5:ebf6fa994b78 177
TickTock 5:ebf6fa994b78 178 void printLog (bool force){
TickTock 4:8d7759f4fe7a 179 static int lastDisplayLoc = 0;
TickTock 5:ebf6fa994b78 180 if(force||displayLoc!=lastDisplayLoc){ //only update if changed
TickTock 5:ebf6fa994b78 181 tt.foreground(Amber);
TickTock 5:ebf6fa994b78 182 tt.background(Black);
TickTock 5:ebf6fa994b78 183 tt.cls();
TickTock 5:ebf6fa994b78 184 tt.locate(0,6);
TickTock 5:ebf6fa994b78 185 tt.set_font((unsigned char*) Arial12x12);
TickTock 5:ebf6fa994b78 186 for(int i=0; i<19; i++){
TickTock 5:ebf6fa994b78 187 printf("%s",displayLog[displayLoc]);
TickTock 5:ebf6fa994b78 188 displayLoc=displayLoc>17?0:displayLoc+1;
TickTock 5:ebf6fa994b78 189 }
TickTock 5:ebf6fa994b78 190 }
TickTock 5:ebf6fa994b78 191 lastDisplayLoc=displayLoc;
TickTock 5:ebf6fa994b78 192 }
TickTock 5:ebf6fa994b78 193
TickTock 5:ebf6fa994b78 194 void dte (bool force){
TickTock 5:ebf6fa994b78 195 unsigned gids, SOC, packV;
TickTock 5:ebf6fa994b78 196 static unsigned lgids=0, lSOC=0, lpackV=0;
TickTock 5:ebf6fa994b78 197 CANMessage msg;
TickTock 5:ebf6fa994b78 198
TickTock 5:ebf6fa994b78 199 msg = lastMsg[indexLastMsg[0x5bc]]; //Get gids
TickTock 5:ebf6fa994b78 200 gids = (msg.data[0]<<2)+(msg.data[1]>>6);
TickTock 5:ebf6fa994b78 201 msg = lastMsg[indexLastMsg[0x55b]]; //Get SOC
TickTock 5:ebf6fa994b78 202 SOC = (msg.data[0]<<2)+(msg.data[1]>>6);
TickTock 5:ebf6fa994b78 203 msg = lastMsg[indexLastMsg[0x1db]]; //Get pack volts
TickTock 5:ebf6fa994b78 204 packV = (msg.data[2]<<2)+(msg.data[3]>>6);
TickTock 5:ebf6fa994b78 205
TickTock 5:ebf6fa994b78 206 tt.background(Navy);
TickTock 5:ebf6fa994b78 207 if(force) tt.cls();
TickTock 5:ebf6fa994b78 208 if(force||gids!=lgids){
TickTock 5:ebf6fa994b78 209 tt.foreground(Amber);
TickTock 5:ebf6fa994b78 210 tt.set_font((unsigned char*) Arial28x28);
TickTock 5:ebf6fa994b78 211 tt.locate(10,10);
TickTock 5:ebf6fa994b78 212 printf("%4d gids\n",gids);
TickTock 5:ebf6fa994b78 213 tt.locate(10,200);
TickTock 5:ebf6fa994b78 214 printf("%4.1f kWh\n",(float)gids*0.08);
TickTock 5:ebf6fa994b78 215 tt.set_font((unsigned char*) SCProSB31x55);
TickTock 5:ebf6fa994b78 216 tt.foreground(Green);
TickTock 5:ebf6fa994b78 217 tt.locate(60,96);
TickTock 5:ebf6fa994b78 218 printf("%4.1f mi\n",(float)gids*0.33); // Approx for now
TickTock 5:ebf6fa994b78 219 lgids=gids;
TickTock 5:ebf6fa994b78 220 }
TickTock 5:ebf6fa994b78 221 if(force||SOC!=lSOC){
TickTock 5:ebf6fa994b78 222 tt.foreground(Amber);
TickTock 5:ebf6fa994b78 223 tt.set_font((unsigned char*) Arial28x28);
TickTock 5:ebf6fa994b78 224 tt.locate(200,10);
TickTock 5:ebf6fa994b78 225 printf("%4.1f%s\n",(float)SOC/10,"%");
TickTock 5:ebf6fa994b78 226 lSOC=SOC;
TickTock 5:ebf6fa994b78 227 }
TickTock 5:ebf6fa994b78 228 if(force||packV!=lpackV){
TickTock 5:ebf6fa994b78 229 tt.foreground(Amber);
TickTock 5:ebf6fa994b78 230 tt.set_font((unsigned char*) Arial28x28);
TickTock 5:ebf6fa994b78 231 tt.locate(200,200);
TickTock 5:ebf6fa994b78 232 printf("%4.1fV\n",(float)packV/2);
TickTock 5:ebf6fa994b78 233 lpackV=packV;
TickTock 5:ebf6fa994b78 234 }
TickTock 5:ebf6fa994b78 235 }
TickTock 5:ebf6fa994b78 236
TickTock 5:ebf6fa994b78 237 void braking (bool force, bool prdata){
TickTock 5:ebf6fa994b78 238 unsigned short targetBraking, regenBraking, speed;
TickTock 5:ebf6fa994b78 239 static unsigned short maxTarget = 0, maxRegen = 0, tarDivReg = 0;
TickTock 5:ebf6fa994b78 240 short rpm;
TickTock 5:ebf6fa994b78 241 unsigned long temp;
TickTock 5:ebf6fa994b78 242 static unsigned char lastPressure[4] = {200,200,200,200};
TickTock 5:ebf6fa994b78 243 unsigned char i,r,t;
TickTock 5:ebf6fa994b78 244 static unsigned char lr, lt;
TickTock 5:ebf6fa994b78 245 CANMessage msg;
TickTock 5:ebf6fa994b78 246
TickTock 5:ebf6fa994b78 247 msg = lastMsg[indexLastMsg[0x1cb]]; //Get Target and Regen
TickTock 5:ebf6fa994b78 248 regenBraking = (msg.data[0]<<3)+(msg.data[1]>>5);
TickTock 5:ebf6fa994b78 249 targetBraking = (msg.data[2]<<3)+(msg.data[3]>>5);
TickTock 5:ebf6fa994b78 250 if (targetBraking>maxTarget) maxTarget=targetBraking;
TickTock 5:ebf6fa994b78 251 if (regenBraking>maxRegen) maxRegen=regenBraking;
TickTock 5:ebf6fa994b78 252 if (regenBraking>50) {
TickTock 5:ebf6fa994b78 253 temp = 1000*targetBraking;
TickTock 5:ebf6fa994b78 254 temp /= regenBraking;
TickTock 5:ebf6fa994b78 255 if (temp>tarDivReg) tarDivReg=temp;
TickTock 5:ebf6fa994b78 256 }
TickTock 5:ebf6fa994b78 257 msg = lastMsg[indexLastMsg[0x176]]; //Get rpms - not sure what this is but scales to mph with .0725
TickTock 5:ebf6fa994b78 258 rpm = ((short)msg.data[0]<<8)+msg.data[1];
TickTock 5:ebf6fa994b78 259 speed =rpm>0?rpm>>3:-rpm>>3; //Take absolute to get speed; div8
TickTock 5:ebf6fa994b78 260 msg = lastMsg[indexLastMsg[0x1ca]]; //Get brake pressure
TickTock 5:ebf6fa994b78 261
TickTock 5:ebf6fa994b78 262 tt.background(Navy);
TickTock 5:ebf6fa994b78 263 if (force) {
TickTock 5:ebf6fa994b78 264 tt.cls();
TickTock 5:ebf6fa994b78 265 tt.rect(0,111,170,239,White);
TickTock 5:ebf6fa994b78 266 tt.line(0,207,170,207,White);
TickTock 5:ebf6fa994b78 267 tt.line(0,175,170,175,White);
TickTock 5:ebf6fa994b78 268 tt.line(0,143,170,143,White);
TickTock 5:ebf6fa994b78 269 lastPressure[0] = 200;
TickTock 5:ebf6fa994b78 270 lastPressure[1] = 200;
TickTock 5:ebf6fa994b78 271 lastPressure[2] = 200;
TickTock 5:ebf6fa994b78 272 lastPressure[3] = 200;
TickTock 5:ebf6fa994b78 273 }
TickTock 5:ebf6fa994b78 274 // plot bar graph for each wheel pressure
TickTock 5:ebf6fa994b78 275 for (i=0; i<4; i++){
TickTock 5:ebf6fa994b78 276 if (msg.data[i]<239) {
TickTock 5:ebf6fa994b78 277 if (msg.data[i]>lastPressure[i]){
TickTock 5:ebf6fa994b78 278 tt.fillrect(10+40*i,239-msg.data[i],40+40*i,239,Red);
TickTock 5:ebf6fa994b78 279 } else if (msg.data[i]<lastPressure[i]) {
TickTock 5:ebf6fa994b78 280 tt.fillrect(10+40*i,238-lastPressure[i],40+40*i,238-msg.data[i],Navy);
TickTock 5:ebf6fa994b78 281 }
TickTock 5:ebf6fa994b78 282 lastPressure[i]=msg.data[i];
TickTock 5:ebf6fa994b78 283 }
TickTock 5:ebf6fa994b78 284 }
TickTock 5:ebf6fa994b78 285
TickTock 5:ebf6fa994b78 286 if(targetBraking>50){
TickTock 5:ebf6fa994b78 287 targetBraking *= speed;
TickTock 5:ebf6fa994b78 288 regenBraking *= speed;
TickTock 5:ebf6fa994b78 289 temp = 200*targetBraking/maxTarget;
TickTock 5:ebf6fa994b78 290 t = (char) temp;
TickTock 5:ebf6fa994b78 291 temp = 200*regenBraking*tarDivReg/maxTarget;
TickTock 5:ebf6fa994b78 292 r = (char) temp;
TickTock 5:ebf6fa994b78 293 if(lr!=r&&prdata){
TickTock 5:ebf6fa994b78 294 tt.foreground(Amber);
TickTock 5:ebf6fa994b78 295 tt.set_font((unsigned char*) Arial28x28);
TickTock 5:ebf6fa994b78 296 tt.locate(100,50);
TickTock 5:ebf6fa994b78 297 printf("%d %d \n",regenBraking,maxRegen);
TickTock 5:ebf6fa994b78 298 tt.locate(100,90);
TickTock 5:ebf6fa994b78 299 printf("%3.1f (%3.1f%s) \n",(float)tarDivReg/1000,(float)regenBraking*tarDivReg/targetBraking/1000,"%");
TickTock 5:ebf6fa994b78 300 }
TickTock 5:ebf6fa994b78 301 if(lt!=t&&prdata){
TickTock 5:ebf6fa994b78 302 tt.foreground(Amber);
TickTock 5:ebf6fa994b78 303 tt.set_font((unsigned char*) Arial28x28);
TickTock 5:ebf6fa994b78 304 tt.locate(100,10);
TickTock 5:ebf6fa994b78 305 printf("%d %d \n",targetBraking,maxTarget);
TickTock 5:ebf6fa994b78 306 }
TickTock 5:ebf6fa994b78 307 if((lr!=r||lt!=t)&&!prdata){
TickTock 5:ebf6fa994b78 308 tt.fillrect(200,239-t,300,238-r,Red);
TickTock 5:ebf6fa994b78 309 tt.fillrect(200,239-r,300,239,Green);
TickTock 5:ebf6fa994b78 310 lt=t;
TickTock 5:ebf6fa994b78 311 lr=r;
TickTock 5:ebf6fa994b78 312 }
TickTock 5:ebf6fa994b78 313 }
TickTock 5:ebf6fa994b78 314 }
TickTock 5:ebf6fa994b78 315
TickTock 5:ebf6fa994b78 316 void updateDisplay(){
TickTock 5:ebf6fa994b78 317 bool changed;
TickTock 4:8d7759f4fe7a 318 for (int i=0; i<2; i++){
TickTock 5:ebf6fa994b78 319 changed = dMode[i]!=lastDMode[i]||(lastSMode>0&&sMode==0);
TickTock 4:8d7759f4fe7a 320 tt.set_display(i);
TickTock 4:8d7759f4fe7a 321 switch (dMode[i]) {
TickTock 4:8d7759f4fe7a 322 case logMode:
TickTock 5:ebf6fa994b78 323 printLog(changed);
TickTock 4:8d7759f4fe7a 324 break;
TickTock 4:8d7759f4fe7a 325 case dteMode:
TickTock 5:ebf6fa994b78 326 dte(changed);
TickTock 5:ebf6fa994b78 327 break;
TickTock 4:8d7759f4fe7a 328 case brakeMode:
TickTock 5:ebf6fa994b78 329 braking(changed,true);
TickTock 4:8d7759f4fe7a 330 break;
TickTock 4:8d7759f4fe7a 331 case powerMode:
TickTock 5:ebf6fa994b78 332 braking(changed,false);
TickTock 4:8d7759f4fe7a 333 break;
TickTock 4:8d7759f4fe7a 334 case controlMode:
TickTock 4:8d7759f4fe7a 335 tt.background(Black);
TickTock 4:8d7759f4fe7a 336 if(dMode[i]!=lastDMode[i]||(lastSMode>0&&sMode==0)) tt.cls();
TickTock 4:8d7759f4fe7a 337 tt.fillcircle(100,100,15,Orange);
TickTock 4:8d7759f4fe7a 338 break;
TickTock 4:8d7759f4fe7a 339 case monitorMode:
TickTock 5:ebf6fa994b78 340 printLast(changed);
TickTock 4:8d7759f4fe7a 341 break;
TickTock 4:8d7759f4fe7a 342 default:
TickTock 4:8d7759f4fe7a 343 tt.background(Black);
TickTock 4:8d7759f4fe7a 344 if(dMode[i]!=lastDMode[i]||(lastSMode>0&&sMode==0)) tt.cls();
TickTock 4:8d7759f4fe7a 345 break;
TickTock 4:8d7759f4fe7a 346 }
TickTock 4:8d7759f4fe7a 347 lastDMode[i]=dMode[i];
TickTock 4:8d7759f4fe7a 348 } // for (i=0; i<1; i++)
TickTock 4:8d7759f4fe7a 349
TickTock 4:8d7759f4fe7a 350 switch (sMode) {
TickTock 4:8d7759f4fe7a 351 case 1:
TickTock 4:8d7759f4fe7a 352 tt.set_display(2); // select both displays
TickTock 4:8d7759f4fe7a 353 tt.foreground(Yellow);
TickTock 4:8d7759f4fe7a 354 tt.background(DarkCyan);
TickTock 4:8d7759f4fe7a 355 tt.set_font((unsigned char*) Arial12x12);
TickTock 4:8d7759f4fe7a 356 tt.fillrect(btn31x1,btn11y1,btn31x2,btn11y2,DarkCyan);
TickTock 4:8d7759f4fe7a 357 tt.locate(btn31x1+5,btn11y1+5);
TickTock 4:8d7759f4fe7a 358 printf("<-Prev\n");
TickTock 4:8d7759f4fe7a 359 tt.fillrect(btn32x1,btn11y1,btn32x2,btn11y2,DarkCyan);
TickTock 4:8d7759f4fe7a 360 tt.fillrect(btn33x1,btn11y1,btn33x2,btn11y2,DarkCyan);
TickTock 4:8d7759f4fe7a 361 tt.locate(btn33x2-50,btn11y1+5);
TickTock 4:8d7759f4fe7a 362 printf("Next->\n");
TickTock 4:8d7759f4fe7a 363 tt.set_display(0);
TickTock 4:8d7759f4fe7a 364 tt.locate(btn32x1+15,btn11y1+5);
TickTock 4:8d7759f4fe7a 365 printf("Select %d\n",dMode[0]);
TickTock 4:8d7759f4fe7a 366 tt.set_display(1);
TickTock 4:8d7759f4fe7a 367 tt.locate(btn32x1+15,btn11y1+5);
TickTock 4:8d7759f4fe7a 368 printf("Select %d\n",dMode[1]);
TickTock 4:8d7759f4fe7a 369 tt.background(Black);
TickTock 4:8d7759f4fe7a 370 break;
TickTock 4:8d7759f4fe7a 371 default:
TickTock 4:8d7759f4fe7a 372 break;
TickTock 4:8d7759f4fe7a 373 }
TickTock 4:8d7759f4fe7a 374 lastSMode=sMode;
TickTock 4:8d7759f4fe7a 375 }
TickTock 4:8d7759f4fe7a 376
TickTock 0:1596b8644523 377 int main() {
TickTock 2:71b1999a8ea5 378 int readPointer=0;
TickTock 2:71b1999a8ea5 379 int fmon;
TickTock 2:71b1999a8ea5 380 int fday;
TickTock 2:71b1999a8ea5 381 int ftime;
TickTock 4:8d7759f4fe7a 382 char sTemp[40];
TickTock 2:71b1999a8ea5 383 unsigned long secs;
TickTock 2:71b1999a8ea5 384 bool bit = false;
TickTock 4:8d7759f4fe7a 385 int i,j;
TickTock 4:8d7759f4fe7a 386
TickTock 2:71b1999a8ea5 387 can1.frequency(500000);
TickTock 2:71b1999a8ea5 388 can2.frequency(500000);
TickTock 1:9dcd70c32180 389 //can1_SleepMode = 0; // Enable TX
TickTock 1:9dcd70c32180 390 //can2_SleepMode = 0; // Enable TX
TickTock 1:9dcd70c32180 391 can1_SleepMode = 1; // Turn on Monitor_only Mode
TickTock 1:9dcd70c32180 392 can2_SleepMode = 1; // Turn on Monitor_only Mode
TickTock 2:71b1999a8ea5 393 //ticker.attach(&send1, 0.5);
TickTock 5:ebf6fa994b78 394 ticker.attach(&updateDisplay, 0.5); // Display messages
TickTock 0:1596b8644523 395 can1.attach(&recieve1);
TickTock 0:1596b8644523 396 can2.attach(&recieve2);
TickTock 4:8d7759f4fe7a 397
TickTock 3:3e879b043bc5 398 tt.set_orientation(1);
TickTock 3:3e879b043bc5 399 tt.set_font((unsigned char*) Arial12x12_prop); // select the font
TickTock 4:8d7759f4fe7a 400 tt.set_display(2); // select right display
TickTock 4:8d7759f4fe7a 401 tt.background(Black);
TickTock 3:3e879b043bc5 402 tt.cls();
TickTock 3:3e879b043bc5 403 tt.set_display(0); // select left display
TickTock 4:8d7759f4fe7a 404 tt.calibrate(); // calibrate the touch
TickTock 1:9dcd70c32180 405 tt.claim(stdout); // send stdout to the TFT display
TickTock 4:8d7759f4fe7a 406 touchpad.rise(&touched);
TickTock 4:8d7759f4fe7a 407 tt.wfi(); // enable interrupt on touch
TickTock 4:8d7759f4fe7a 408 dled = 1; // turn on display LED 80%
TickTock 2:71b1999a8ea5 409 timer.start() ;
TickTock 2:71b1999a8ea5 410 RTC_Init(); // start the RTC Interrupts that sync the timer
TickTock 1:9dcd70c32180 411 struct tm t; // pointer to a static tm structure
TickTock 1:9dcd70c32180 412
TickTock 1:9dcd70c32180 413 seconds = time(NULL);
TickTock 1:9dcd70c32180 414 t = *localtime(&seconds) ;
TickTock 2:71b1999a8ea5 415 strftime(sTemp, 32, "%a %m/%d/%Y %X", &t);
TickTock 3:3e879b043bc5 416 //tt.locate(0,0);
TickTock 3:3e879b043bc5 417 //printf("\nCurrent time : %s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS
TickTock 1:9dcd70c32180 418
TickTock 1:9dcd70c32180 419 // is it a date before 2012 ?
TickTock 1:9dcd70c32180 420 if ((t.tm_year + 1900) < 2012 ) {
TickTock 1:9dcd70c32180 421 // before 2012, so the RTC probably lost power
TickTock 1:9dcd70c32180 422 // So, set a near-recent date in 2012
TickTock 1:9dcd70c32180 423
TickTock 1:9dcd70c32180 424 // enter people-values here
TickTock 2:71b1999a8ea5 425 t.tm_year = 2013 ; // 28 May 2012
TickTock 2:71b1999a8ea5 426 t.tm_mon = 3 ; // 1 to 12
TickTock 2:71b1999a8ea5 427 t.tm_mday = 5;
TickTock 1:9dcd70c32180 428 t.tm_hour = 12; // 12:59:56 PM (after noon)
TickTock 1:9dcd70c32180 429 t.tm_min = 59;
TickTock 1:9dcd70c32180 430 t.tm_sec = 56;
TickTock 1:9dcd70c32180 431
TickTock 1:9dcd70c32180 432 // adjust for tm structure required values
TickTock 1:9dcd70c32180 433 t.tm_year = t.tm_year - 1900;
TickTock 1:9dcd70c32180 434 t.tm_mon = t.tm_mon - 1;
TickTock 1:9dcd70c32180 435
TickTock 1:9dcd70c32180 436 // set the RTC
TickTock 1:9dcd70c32180 437 set_time(mktime(&t));
TickTock 1:9dcd70c32180 438 seconds = time(NULL);
TickTock 1:9dcd70c32180 439
TickTock 1:9dcd70c32180 440 // printf("Set RTC to:\n" );
TickTock 1:9dcd70c32180 441 // strftime(sTemp, 32, "%a %m/%d/%Y %X", localtime(&seconds));
TickTock 1:9dcd70c32180 442 // printf("%s\n", sTemp); // DAY MM/DD/YYYY HH:MM:SS
TickTock 0:1596b8644523 443 }
TickTock 2:71b1999a8ea5 444 while (true) {
TickTock 4:8d7759f4fe7a 445 if (!logOpen) { // Open new file if one is not already open
TickTock 4:8d7759f4fe7a 446 seconds = time(NULL);
TickTock 4:8d7759f4fe7a 447 t = *localtime(&seconds) ;
TickTock 4:8d7759f4fe7a 448 strftime(fileName, 32, "/fs/%m%d%H%M.alc", &t); //mmddhhmm.alc
TickTock 2:71b1999a8ea5 449
TickTock 4:8d7759f4fe7a 450 tt.set_display(0); // select left display
TickTock 4:8d7759f4fe7a 451 tt.locate(0,0);
TickTock 4:8d7759f4fe7a 452 tt.foreground(Cyan); // set chars to Cyan
TickTock 4:8d7759f4fe7a 453 //printf("Using file %s\n",fileName);
TickTock 4:8d7759f4fe7a 454 sprintf(sTemp,"Using file %s\n",fileName);
TickTock 4:8d7759f4fe7a 455 logMsg(sTemp);
TickTock 4:8d7759f4fe7a 456 file = fopen(fileName, "ab");
TickTock 4:8d7759f4fe7a 457
TickTock 4:8d7759f4fe7a 458 if(file==NULL){
TickTock 4:8d7759f4fe7a 459 sprintf(sTemp,"\nUnable to open %s\n\n\n\n",fileName);
TickTock 4:8d7759f4fe7a 460 logMsg(sTemp);
TickTock 4:8d7759f4fe7a 461 } else {
TickTock 4:8d7759f4fe7a 462 logOpen = true;
TickTock 4:8d7759f4fe7a 463 readPointer=writePointer;
TickTock 4:8d7759f4fe7a 464 sprintf(sTemp,"Starting Can Log %s\n",fileName);
TickTock 4:8d7759f4fe7a 465 logMsg(sTemp);
TickTock 4:8d7759f4fe7a 466 logTS();
TickTock 4:8d7759f4fe7a 467 fclose(file);
TickTock 4:8d7759f4fe7a 468 file = fopen("/fs/loglog.txt", "a");
TickTock 4:8d7759f4fe7a 469 fprintf(file,"%s\r\n",fileName);
TickTock 4:8d7759f4fe7a 470 fclose(file);
TickTock 4:8d7759f4fe7a 471 }
TickTock 4:8d7759f4fe7a 472 } else { // if (!logOpen)
TickTock 4:8d7759f4fe7a 473 if (((writePointer+maxBufLen-readPointer)%maxBufLen)>(maxBufLen/2)||canIdle) {
TickTock 4:8d7759f4fe7a 474 // Dump buffer if > 1/2 full, canbus has stopped, or PB1 pressed
TickTock 4:8d7759f4fe7a 475 if (logOpen) {
TickTock 4:8d7759f4fe7a 476 file = fopen(fileName, "ab");
TickTock 4:8d7759f4fe7a 477 if (file == NULL) {
TickTock 4:8d7759f4fe7a 478 logOpen = false;
TickTock 4:8d7759f4fe7a 479 sprintf(sTemp,"Failed to append log file.\n\n");
TickTock 4:8d7759f4fe7a 480 logMsg(sTemp);
TickTock 4:8d7759f4fe7a 481 } else {
TickTock 4:8d7759f4fe7a 482 while (readPointer != writePointer) {
TickTock 4:8d7759f4fe7a 483 for (j = 0; j<13; j++){
TickTock 4:8d7759f4fe7a 484 fprintf(file,"%c",writeBuffer[readPointer][j]);
TickTock 4:8d7759f4fe7a 485 }
TickTock 4:8d7759f4fe7a 486 if(++readPointer >= maxBufLen)
TickTock 4:8d7759f4fe7a 487 readPointer=0;
TickTock 4:8d7759f4fe7a 488 }
TickTock 4:8d7759f4fe7a 489 led3 = !led3;
TickTock 4:8d7759f4fe7a 490 fclose(file);
TickTock 4:8d7759f4fe7a 491 }
TickTock 4:8d7759f4fe7a 492 } // if (logOpen)
TickTock 4:8d7759f4fe7a 493 } // if > 1/2 full, canbus has stopped, or PB1 pressed
TickTock 4:8d7759f4fe7a 494 } // if logOpen
TickTock 4:8d7759f4fe7a 495 if (canIdle&&userIdle) { // canbus idle --> sleep to save power
TickTock 4:8d7759f4fe7a 496 if (logOpen){
TickTock 4:8d7759f4fe7a 497 // First take advantage of the idle time to clear some room
TickTock 4:8d7759f4fe7a 498 bit = false;
TickTock 4:8d7759f4fe7a 499 rfile = fopen("/fs/loglog.txt", "r");
TickTock 4:8d7759f4fe7a 500 file = fopen("/fs/loglog.new", "w");
TickTock 4:8d7759f4fe7a 501 while (!feof(rfile)) {
TickTock 4:8d7759f4fe7a 502 fscanf(rfile,"/fs/%2d%2d%4d.alc\r\n",&fmon,&fday,&ftime);
TickTock 4:8d7759f4fe7a 503 //if ((fmon<t.tm_mon)&&(fday<=t.tm_mday)){ // Delete all files more than 1 month old
TickTock 4:8d7759f4fe7a 504 if ((fmon < 12) || (t.tm_mon > 1)){
TickTock 4:8d7759f4fe7a 505 fday = fday + fmon*31; //crude - february will store 3 extra days of data
TickTock 4:8d7759f4fe7a 506 }
TickTock 4:8d7759f4fe7a 507 if ((fday+14)<(t.tm_mday+t.tm_mon*31)){ // Delete all files more than ~14 days old
TickTock 4:8d7759f4fe7a 508 bit=true;
TickTock 4:8d7759f4fe7a 509 sprintf(sTemp,"/fs/%02d%02d%04d.alc",fmon,fday,ftime);
TickTock 4:8d7759f4fe7a 510 if ((remove(sTemp)==NULL)) {
TickTock 4:8d7759f4fe7a 511 sprintf(sTemp,"Removed file %s\n",sTemp);
TickTock 4:8d7759f4fe7a 512 logMsg(sTemp);
TickTock 4:8d7759f4fe7a 513 }
TickTock 4:8d7759f4fe7a 514 }else{
TickTock 4:8d7759f4fe7a 515 fprintf(file,"/fs/%02d%02d%04d.alc\r\n",fmon,fday,ftime);
TickTock 4:8d7759f4fe7a 516 }
TickTock 2:71b1999a8ea5 517 }
TickTock 4:8d7759f4fe7a 518 fclose (file);
TickTock 4:8d7759f4fe7a 519 fclose (rfile);
TickTock 4:8d7759f4fe7a 520 if (bit) {
TickTock 4:8d7759f4fe7a 521 remove ("/fs/loglog.txt");
TickTock 4:8d7759f4fe7a 522 //rename not working so do it the hard way
TickTock 4:8d7759f4fe7a 523 //rename ("/fs/loglog.new","/fs/loglog.txt");
TickTock 4:8d7759f4fe7a 524 rfile = fopen("/fs/loglog.new", "r");
TickTock 4:8d7759f4fe7a 525 file = fopen("/fs/loglog.txt", "w");
TickTock 2:71b1999a8ea5 526 while (!feof(rfile)) {
TickTock 4:8d7759f4fe7a 527 fscanf(rfile,"%s\r\n",&sTemp);
TickTock 4:8d7759f4fe7a 528 fprintf(file,"%s\r\n",sTemp);
TickTock 2:71b1999a8ea5 529 }
TickTock 2:71b1999a8ea5 530 fclose (file);
TickTock 2:71b1999a8ea5 531 fclose (rfile);
TickTock 4:8d7759f4fe7a 532 }
TickTock 4:8d7759f4fe7a 533 remove ("/fs/loglog.new");
TickTock 4:8d7759f4fe7a 534 wait(5); // wait a few seconds to ensure fsRAM is done
TickTock 4:8d7759f4fe7a 535 } // if (logOpen)
TickTock 4:8d7759f4fe7a 536 sprintf(sTemp,"Putting uC to sleep.\n");
TickTock 4:8d7759f4fe7a 537 logMsg(sTemp);
TickTock 4:8d7759f4fe7a 538 //LPC_RTC->CIIR=0x00; // block RTC interrupts
TickTock 4:8d7759f4fe7a 539 led1=0;
TickTock 4:8d7759f4fe7a 540 led2=0;
TickTock 4:8d7759f4fe7a 541 led3=0;
TickTock 4:8d7759f4fe7a 542 led4=0;
TickTock 4:8d7759f4fe7a 543 dled=0; // turn off display
TickTock 4:8d7759f4fe7a 544 secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
TickTock 4:8d7759f4fe7a 545 while (secsNoMsg>canTimeout && secsNoTouch>userTimeout) {
TickTock 4:8d7759f4fe7a 546 //DeepPowerDown();
TickTock 4:8d7759f4fe7a 547 tt.wfi(); //enable touchpad input
TickTock 4:8d7759f4fe7a 548 //__wfi(); // freeze CPU and wait for interrupt (from canbus or touch)
TickTock 4:8d7759f4fe7a 549 Sleep();
TickTock 4:8d7759f4fe7a 550 //DeepPowerDown();
TickTock 4:8d7759f4fe7a 551 }
TickTock 4:8d7759f4fe7a 552 canIdle=secsNoMsg>canTimeout;
TickTock 4:8d7759f4fe7a 553 userIdle=userIdle>userTimeout;
TickTock 4:8d7759f4fe7a 554 dled=1; // turn on display LED
TickTock 4:8d7759f4fe7a 555 sprintf(sTemp,"Waking uC.\n");
TickTock 4:8d7759f4fe7a 556 logMsg(sTemp);
TickTock 4:8d7759f4fe7a 557 if (time(NULL)>(secs+1800)) {
TickTock 4:8d7759f4fe7a 558 logOpen = false; // Start new file if asleep for more than 30 minutes
TickTock 4:8d7759f4fe7a 559 if (secsNoTouch>100) secsNoTouch = 100; // also mostly reset user Idle counter
TickTock 4:8d7759f4fe7a 560 } else { // insert timestamp on each wake
TickTock 4:8d7759f4fe7a 561 logTS();
TickTock 4:8d7759f4fe7a 562 }
TickTock 4:8d7759f4fe7a 563 //LPC_RTC->CIIR=0x01; // re-enable RTC interrupts
TickTock 4:8d7759f4fe7a 564 } // if idle
TickTock 4:8d7759f4fe7a 565
TickTock 4:8d7759f4fe7a 566 if (!userIdle) {
TickTock 4:8d7759f4fe7a 567 if (secsNoTouch<2) {// Recently touched
TickTock 4:8d7759f4fe7a 568 secsNoTouch +=2; // increment to prevent double touch
TickTock 4:8d7759f4fe7a 569 if (lastTouch.x>320){
TickTock 4:8d7759f4fe7a 570 i=1;
TickTock 4:8d7759f4fe7a 571 lastTouch.x-=320;
TickTock 4:8d7759f4fe7a 572 } else {
TickTock 4:8d7759f4fe7a 573 i=0;
TickTock 4:8d7759f4fe7a 574 }
TickTock 4:8d7759f4fe7a 575 if (lastTouch.y>btn11y1 && lastTouch.y<btn11y2){
TickTock 5:ebf6fa994b78 576 if(sMode==1){
TickTock 5:ebf6fa994b78 577 if (lastTouch.x>btn31x1 && lastTouch.x<btn31x2) {
TickTock 5:ebf6fa994b78 578 dMode[i]=dMode[i]>0?dMode[i]-1:maxModes;
TickTock 5:ebf6fa994b78 579 } else if (lastTouch.x>btn32x1 && lastTouch.x<btn32x2) {
TickTock 5:ebf6fa994b78 580 secsNoTouch = userTimeout; // immediately exit config mode
TickTock 5:ebf6fa994b78 581 } else if (lastTouch.x>btn33x1 && lastTouch.x<btn33x2) {
TickTock 5:ebf6fa994b78 582 dMode[i]=dMode[i]<maxModes?dMode[i]+1:0;
TickTock 5:ebf6fa994b78 583 }
TickTock 5:ebf6fa994b78 584 } else sMode=1;
TickTock 5:ebf6fa994b78 585 } else {
TickTock 5:ebf6fa994b78 586 if (dMode[i]==monitorMode) {
TickTock 5:ebf6fa994b78 587 if (lastTouch.x>btn31x1 && lastTouch.x<btn31x2)
TickTock 5:ebf6fa994b78 588 indexOffset=indexOffset>4?indexOffset-4:1;
TickTock 5:ebf6fa994b78 589 else if (lastTouch.x>btn33x1 && lastTouch.x<btn33x2)
TickTock 5:ebf6fa994b78 590 indexOffset=indexOffset<77?indexOffset+4:80;
TickTock 2:71b1999a8ea5 591 }
TickTock 2:71b1999a8ea5 592 }
TickTock 4:8d7759f4fe7a 593 }
TickTock 5:ebf6fa994b78 594 secsNoMsg = 0;
TickTock 4:8d7759f4fe7a 595 } else { // userIdle
TickTock 4:8d7759f4fe7a 596 sMode=0;
TickTock 4:8d7759f4fe7a 597 }
TickTock 4:8d7759f4fe7a 598
TickTock 4:8d7759f4fe7a 599 wait(0.1); // We get >2K messages per second
TickTock 2:71b1999a8ea5 600 } //while (true)
TickTock 0:1596b8644523 601 }