Mini can app

Dependencies:   mbed mbed-STM32F103C8T6

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers heatcontrol.cpp Source File

heatcontrol.cpp

00001 #include "mbed.h"
00002 #include "heatcontrol.h"
00003 #include "globals.h" // includes CAN2
00004 #include "espar_can.h"
00005 /******************************************************
00006  *                    Constants
00007  ******************************************************/
00008 //#define EASYSTARTFORMAT 1
00009 #define LIN_BAUD              1200
00010 
00011 extern void DebugWrite(const char * str);
00012 extern char printbuff[256];
00013 
00014 extern unsigned long lifetimer;
00015 
00016 #define NOREPORTING 0
00017 #define HEATERCALLEDON 1
00018 
00019 char heaterDetected = 0;
00020 
00021 //const uint16_t HEATER1ID = 0x0054;
00022 //const uint16_t CTRLCHANNEL = 0x07A0;
00023 //#define EASYSTARTFORMAT
00024 #ifdef EASYSTARTFORMAT
00025 const uint16_t HEATER1ID = 0x0054; // 0x009C heater 1
00026 const uint16_t CTRLCHANNEL = 0x07A0;
00027 const uint16_t CTRLRESPONSE = 0x073C;// heater1 0x073C, response 0x073D heater 2
00028 
00029 const uint16_t HEATER2ID = 0x0057;// 0x009C heater 1
00030 const uint16_t CTRLCHANNEL2 = 0x07A1;
00031 const uint16_t CTRLRESPONSE2 = 0x073D;// heater1 0x073C, response 0x073D heater 2
00032 
00033 #else
00034 const uint16_t HEATER1ID = 0x009C; // 0x009C heater 1
00035 const uint16_t CTRLCHANNEL = 0x07A0;
00036 const uint16_t CTRLRESPONSE = 0x073C; // heater1 0x073C, response 0x073D heater 2
00037 
00038 const uint16_t HEATER2ID = 0x00F3; // 0x009C heater 1
00039 const uint16_t CTRLCHANNEL2 = 0x07A1;
00040 const uint16_t CTRLRESPONSE2 = 0x073D; // heater1 0x073C, response 0x073D heater 2
00041 
00042 #endif
00043 
00044 /******************************************************
00045  *                   Enumerations
00046  ******************************************************/
00047 
00048 /******************************************************
00049  *                 Type Definitions
00050  ******************************************************/
00051 
00052 /******************************************************
00053  *                    Structures
00054  ******************************************************/
00055 extern struct sSystemSettings Settings; // structure to hold system settings //
00056 /******************************************************
00057  *               Function Declarations
00058  ******************************************************/
00059 void printCAN(CANMessage *canMsg);
00060 void printCANTx(CANMessage *canMsg);
00061 
00062 void printPacketBuffer(unsigned int length, struct sHeatVars *s);
00063 void parseLINBuffer(struct sHeatVars *s);
00064 void readLINBuffer(struct sHeatVars *s);
00065 unsigned char fromHexAscii(char ascii);
00066 extern void resetTimerAsync(struct sHeatVars *s);
00067 extern void resetTimer(struct sHeatVars *s);
00068 int doFindExpectedResponse(CANMessage* msg, const uint16_t expectedID, const char* expectedResponse, int charsInMatch);
00069 /******************************************************
00070  *               Variable Definitions
00071  ******************************************************/
00072 
00073 // local vars
00074 // external timer variables to use for timing (ie 1 minute, etc.)
00075 extern volatile unsigned char idletimer;
00076 extern void DebugWrite(const char* str);
00077 struct sHeatVars heaterState[HEATERSTATECOUNT];
00078 
00079 char otherControllerDetected = 0;
00080 /******************************************************
00081  *               Function Definitions
00082  ******************************************************/
00083 
00084 /*
00085  * 0-ID,0054:00 00 FE FF FE FF 00 00
00086 
00087  0-ID,0625:25 00 B5 54 C0 BB E4 01
00088 
00089  0-ID,0054:00 00 FE FF FE FF 00 00
00090 
00091  0-ID,0057:00 00 FE FF FE FF 00 00
00092 
00093  0-ID,0625:25 00 B5 54 C0 BB E4 01
00094 
00095  0-ID,02C4:03 00 04 00 18 03 00 00
00096 
00097  0-ID,02C6:F4 01 84 03 00 00 00 00
00098 
00099  0-ID,0625:25 00 B5 54 C0 BB E4 01
00100 
00101  0-ID,02C6:F4 01 84 03 00 00 00 00
00102 
00103  0-ID,073C:02 7E 00 02 7B 00 02 11
00104 
00105  0-ID,02C6:F4 01 84 03 00 00 00 00
00106 
00107  0-ID,0625:25 00 B5 54 C0 BB E4 01
00108 
00109  0-ID,02C6:F4 01 84 03 00 00 00 00
00110 
00111  * */
00112 
00113 void initHeaterState(struct sHeatVars *s)
00114 {
00115     s->internalAltitude = 0;
00116     s->battV = 0;
00117     s->primeFuelPumpCount = 0;
00118     s->heatCallDetected = WICED_FALSE;
00119     s->heaterTemp = -9999;
00120     s->initTimer = 3; // 3s before we do anything other than "I'm here"
00121     s->tasksequence = 0;
00122     s->currentError = 0xff;
00123     s->heatOn = 0; // default 0
00124     //unsigned char errorHistory[8];
00125     s->errorChangeFlag = 0;
00126     s->heatcontrolstate = 0; // default 0
00127     s->lastRequest = 0; // default = 0;
00128     s->lastResponse = 0; //default = 0;
00129     s->noResponseCount = 0; //default = 0;
00130     s->retryHC = 0; // = 0;
00131     s->heatrunning = 0; // = 0;
00132     s->reset_fault_codes = WICED_FALSE; // WICED_FALSE
00133     s->isAnalogHeater = WICED_FALSE;
00134     s->heattime = 0;
00135     s->heatresettime = RESETHEATTIME;
00136     s->reportflag = 0;
00137     s->preheattime = 0;
00138     s->heaterSetpointChange = 0;
00139     s->primeFuelPump = WICED_FALSE;
00140     s->OBAltitude = WICED_FALSE;
00141     s->altitudeMode = WICED_TRUE;
00142 }
00143 // do checksum calc
00144 int testChecksum(unsigned int length, struct sHeatVars *s)
00145 {
00146     unsigned int checksum = 0;
00147     int i;
00148     for (i = s->working; i < (s->working + length + 3); i++)
00149     {
00150         checksum += s->linbuff[i];
00151     }
00152     // convert the last 2 bytes to checksum
00153     if ((checksum % 256) == (fromHexAscii(s->linbuff[s->working + length + 3]) * 16 + fromHexAscii(s->linbuff[s->working + length + 4])))
00154     {
00155         return 1;
00156     }
00157     return 0;
00158 }
00159 #define CANSPEED_500      500000 
00160 void InitCAN()
00161 {
00162     if ( can2.frequency(CANSPEED_500) ) {
00163            
00164     }
00165     otherControllerDetected = 0;
00166     DebugWrite("Init can\r\n");
00167     int result;
00168     // can is just there.
00169 }
00170 
00171 void setHeatSetpoint(struct sHeatVars* s, int setpoint)
00172 {
00173     printf("setting setpoint of %d\r\n", setpoint);
00174     if ((setpoint > 50) && (setpoint <= 380))
00175     {
00176         s->heaterSetpointChange = setpoint;
00177     }
00178 }
00179 void primeFuelPump(struct sHeatVars* s)
00180 {
00181     s->primeFuelPump = WICED_TRUE;
00182 }
00183 void resetFaultCodes(struct sHeatVars* s)
00184 {
00185     //printf("Reset Fault codes on\r\n");
00186     s->reset_fault_codes = WICED_TRUE;
00187 }
00188 void set_heat_con(struct sHeatVars* s, heatcall on_off)
00189 {
00190     resetTimerAsync(s);
00191     if (on_off == HEATCALLINIT)
00192     {
00193         s->heatOn = HEATCALLINIT;
00194         //heattime = 100; //60*Settings.DefaultHeaterRuntime;
00195         s->heattime = 24*60*60;
00196         s->heatresettime = RESETHEATTIME;
00197 
00198         s->preheattime = 0;
00199         //printf("Init heater, preheat %lu\n", preheattime);
00200     }
00201     else if (on_off == HEATCALLOFF)
00202     {
00203         s->heatOn = HEATCALLOFF;
00204         s->heattime = 0;
00205         s->heatresettime = RESETHEATTIME;
00206         s->preheattime = 0;
00207         ///printf("Turning heater OFF\n");
00208     }
00209     else if (on_off == HEATCALLON)
00210     {
00211         // skip preheat
00212         s->heatOn = HEATCALLON;
00213         s->heattime = 24*60*60;
00214         s->heatresettime = RESETHEATTIME;
00215         s->preheattime = 0;
00216         //printf("Turning heater ON (skip preheat)\n");
00217     }
00218     else
00219     {
00220         //printf("\n unknown command\n");
00221     }
00222 }
00223 
00224 void WakeHeater(struct sHeatVars* s)
00225 {
00226     if (s->heatcontrolstate == 0)
00227     {
00228         //InitDigHeater();
00229         s->retryHC = 0;
00230         s->heatcontrolstate = 1;
00231     }
00232 }
00233 
00234 void sendCANCommand(uint16_t id, const char*data, int length)
00235 {
00236     //return; // listen mode
00237 
00238     CANMessage TxMessage(id, data, length);
00239     can2.write(TxMessage);
00240     printCAN(&TxMessage);
00241 }
00242 
00243 void sendRepeatMode(struct sHeatVars* s)
00244 {
00245     const char wake[8] =
00246     { 0x0F, 0x11, 0xC9, 0x22, 0x00, 0x20, 0x60, 0x00 };
00247     if (s->heaternum == 1)
00248     {
00249         sendCANCommand(0x060F, wake, 8);
00250     }
00251     //else if (s->heaternum == 2)
00252     //{
00253     //  sendCANCommand(CTRLCHANNEL2, wake, 8);
00254     //}
00255 }
00256 void sendWakeCommand(struct sHeatVars* s)
00257 {
00258     //DebugWrite("Wake command\r\n");
00259     // "3e is "tester present"
00260     const char wake[8] =
00261     { 0x02, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00262     //{0x0F, 0x10, 0x03, 0x00, 0x20, 0x60, 0x00, 0x00};
00263     if (s->heaternum == 1)
00264     {
00265         sendCANCommand(CTRLCHANNEL, wake, 8);
00266     }
00267     else if (s->heaternum == 2)
00268     {
00269         sendCANCommand(CTRLCHANNEL2, wake, 8);
00270     }
00271 
00272     //const char wake2[8] = {0x0F, 0x10, 0x03, 0x00, 0x20, 0x60, 0x00, 0x00};
00273     //sendCANCommand(CTRLCHANNEL2, wake2, 8);
00274 }
00275 void sendHeatOffCommand(struct sHeatVars* s)
00276 {
00277     //DebugWrite("Heat Off command\r\n");
00278     const char heatoncmd[8] =
00279 #ifdef EASYSTARTFORMAT
00280             {   0x00, 0x00, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x00};
00281 #else
00282             { 0x05, 0x00, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x00 };
00283 #endif
00284     if (s->heaternum == 1)
00285     {
00286         sendCANCommand(HEATER1ID, heatoncmd, 8);
00287     }
00288     else if (s->heaternum == 2)
00289     {
00290         sendCANCommand(HEATER2ID, heatoncmd, 8);
00291     }
00292 }
00293 void sendHeatVentConmmand(struct sHeatVars* s)
00294 {
00295     DebugWrite("SENDHEATVENT\r\n");
00296     const char heatoncmd[8] =
00297     { 0x01, 0x02, 0xFE, 0xFF, 0xF8, 0x02, 0x00, 0x00 };
00298     if (s->heaternum == 1)
00299     {
00300         sendCANCommand(HEATER1ID, heatoncmd, 8);
00301     }
00302     else if (s->heaternum == 2)
00303     {
00304         sendCANCommand(HEATER2ID, heatoncmd, 8);
00305     }
00306 }
00307 
00308 void sendHeatOnCommand(struct sHeatVars* s)
00309 {
00310     DebugWrite("SENDHEATON\r\n");
00311     char heatoncmd[8] =
00312 #ifdef EASYSTARTFORMAT
00313             {   0x01, 0x01, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x00};  // works?
00314 #else
00315             { 0x07, 0x01, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x00 };  // works?
00316 #endif
00317     //{ 0x07, 0x01, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x00 };
00318 
00319     uint16_t setpointbytes = 65534;
00320     char *usetpoint = (char*) &setpointbytes;
00321     // heater 2 has setpoint in 2/3... heater1 in 3/4??????
00322     heatoncmd[2] = usetpoint[0];  // LSB in slot 2
00323     heatoncmd[3] = usetpoint[1];
00324     heatoncmd[4] = usetpoint[0];  // LSB in slot 2
00325     heatoncmd[5] = usetpoint[1];
00326     //{ 0x07, 0x01, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x00 }; // "mode is "preheating"?
00327     if (s->heaternum == 1)
00328     {
00329         //need to reintroduce this...
00330         if ((s->OBAltitude == WICED_FALSE))
00331         {
00332             char mysteryCommand[8] =
00333             { 0x0F, 0x00, 0xC9, 0x22, 0x00, 0x00, 0x00, 0x00 };
00334             sendCANCommand(0x060D, mysteryCommand, 8);
00335         }
00336 
00337         sendCANCommand(HEATER1ID, heatoncmd, 8);
00338     }
00339     else if (s->heaternum == 2)
00340     {
00341         sendCANCommand(HEATER2ID, heatoncmd, 8);
00342     }
00343 }
00344 void sendAltitudeMode(struct sHeatVars *s)
00345 {
00346     if (s->OBAltitude == WICED_TRUE)
00347     {
00348         return; // don't send if altitude mode on board.
00349     }
00350 
00351     char highAltitudeCmd[8] =
00352     { 0x4c, 0x1d, 0, 0, 0, 0, 0, 0 };
00353 
00354     // no idea what this is for?
00355     //5000      60D  205935687 0008 0D 11 C9 22 00 20 60 00
00356 //#ifdef EASYSTARTFORMAT
00357 
00358 //#endif
00359     // 4C,1D - 7500 for high altitude
00360     // 10,27 - 10000 for low altitude
00361 
00362     //uint16_t setpointbytes = 6800;
00363     uint16_t setpointbytes = 6800;
00364     if (s->internalAltitude > 0)
00365     {
00366         setpointbytes = (s->internalAltitude * 10);
00367         //sprintf(printbuff, "-- Internal alt\r\n %d\r\n", s->internalAltitude);
00368         //DebugWrite(printbuff);
00369     }
00370     else
00371     {
00372         setpointbytes = 6800;
00373     }
00374     char *usetpoint = (char*) &setpointbytes;
00375     highAltitudeCmd[0] = usetpoint[0];  // LSB in slot 2
00376     highAltitudeCmd[1] = usetpoint[1];
00377     char lowAltitudeCmd[8] =
00378     { 0x10, 0x27, 0, 0, 0, 0, 0, 0 };
00379 
00380     if (s->internalAltitude > 0)
00381     {
00382         setpointbytes = (s->internalAltitude * 10);
00383         //  sprintf(printbuff, "-- Internal alt %d\r\n", s->internalAltitude);
00384         //  DebugWrite(printbuff);
00385     }
00386     else
00387     {
00388         setpointbytes = 10000;
00389     }
00390 
00391     lowAltitudeCmd[0] = usetpoint[0];  // LSB in slot 2
00392     lowAltitudeCmd[1] = usetpoint[1];
00393 
00394     if (s->heaternum == 1)
00395     {
00396         if (s->altitudeMode == WICED_TRUE)
00397         {
00398 
00399             sendCANCommand(0x0055, highAltitudeCmd, 8);
00400 //          sendCANCommand(0x0056, highAltitudeCmd, 8);
00401             sendCANCommand(HEATER1ID + 1, highAltitudeCmd, 8);
00402         }
00403         else
00404         {
00405             sendCANCommand(0x0055, lowAltitudeCmd, 8);
00406 //          sendCANCommand(0x0056, lowAltitudeCmd, 8);
00407             sendCANCommand(HEATER1ID + 1, lowAltitudeCmd, 8);
00408         }
00409 
00410     }
00411     /*
00412      else if (s->heaternum == 2)
00413      {
00414      if (s->altitudeMode == WICED_TRUE)
00415      {
00416      sendCANCommand(HEATER2ID + 1, highAltitudeCmd, 8);
00417      sendCANCommand(0x0055, lowAltitudeCmd, 8);
00418      sendCANCommand(0x0056, highAltitudeCmd, 8);
00419      }
00420      else
00421      {
00422      sendCANCommand(HEATER2ID + 1, lowAltitudeCmd, 8);
00423      sendCANCommand(0x0055, lowAltitudeCmd, 8);
00424      sendCANCommand(0x0056, lowAltitudeCmd, 8);
00425      }
00426 
00427      }
00428      */
00429 }
00430 void sendHeatOnCommandSetpoint(struct sHeatVars* s)
00431 {
00432     DebugWrite("SENDHEATONSETPOINT\r\n");
00433     sprintf(printbuff, "Setpoint is %d", s->setpoint);
00434     DebugWrite(printbuff);
00435     char heatoncmd[8] =
00436     //{ 0x01, 0x04, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x00 }; // "mode is "setpoint with temp"?
00437             { 0x07, 0x04, 0xFE, 0xFF, 0xFF, 0xFE, 0x00, 0x00 }; // "mode is "setpoint with temp"?
00438 
00439     uint16_t setpointbytes = 65534;
00440     char *usetpoint = (char*) &setpointbytes;
00441     // heater 2 has setpoint in 2/3... heater1 in 3/4??????
00442     heatoncmd[2] = usetpoint[0];  // LSB in slot 2
00443     heatoncmd[3] = usetpoint[1];
00444     heatoncmd[4] = usetpoint[0];  // LSB in slot 2
00445     heatoncmd[5] = usetpoint[1];
00446 
00447     setpointbytes = s->setpoint;
00448     usetpoint = (char*) &setpointbytes;
00449     // heater 2 has setpoint in 2/3... heater1 in 3/4??????
00450     if (s->heaternum == 2)
00451     {
00452         heatoncmd[2] = usetpoint[0];  // LSB in slot 2
00453         heatoncmd[3] = usetpoint[1];
00454         //heatoncmd[4] = usetpoint[0];  // LSB in slot 2
00455         //heatoncmd[5] = usetpoint[1];
00456         sendCANCommand(HEATER2ID, heatoncmd, 8);
00457     }
00458     else
00459     {
00460         heatoncmd[4] = usetpoint[0];  // LSB in slot 2
00461         heatoncmd[5] = usetpoint[1];
00462         sendCANCommand(HEATER1ID, heatoncmd, 8);
00463     }
00464 
00465 }
00466 void doOtherResetSequence(struct sHeatVars* s)
00467 {
00468     //DebugWrite("**************\r\n");
00469     CANMessage msg;
00470 
00471     DebugWrite("Send wake\r\n");
00472     sendWakeCommand(s);
00473 
00474     int id = CTRLCHANNEL;
00475     int resp = CTRLRESPONSE;
00476     if (s->heaternum == 2)
00477     {
00478         id = CTRLCHANNEL2;
00479         resp = CTRLRESPONSE2;
00480     }
00481     char switchToSession[8] =
00482     { 0x10, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00483     sendCANCommand(id, switchToSession, 8);
00484     DebugWrite("Switch To Session\r\n");
00485     if (doFindExpectedResponse(&msg, resp, NULL, 0) > 0)
00486     {
00487         DebugWrite("Got a response!\r\n");
00488         printCAN(&msg);
00489         //return;
00490     }
00491     else
00492     {
00493 
00494     }
00495     // request seed
00496 
00497     //DebugWrite("**************\r\n");
00498 }
00499 void doPrimeSequence(struct sHeatVars* s)
00500 {
00501     int extrabyte = 0;
00502     int count;
00503     sendWakeCommand(s);
00504 
00505     CANMessage msg;
00506     int id = CTRLCHANNEL;
00507     int resp = CTRLRESPONSE;
00508     if (s->heaternum == 2)
00509     {
00510         id = CTRLCHANNEL2;
00511         resp = CTRLRESPONSE2;
00512     }
00513 
00514     char pump[8] =
00515     { 0x07, 0x31, 0x01, 0xF0, 0x00, 0x64, 0x00, 0x05 };
00516     char pump2[8] =
00517     { 0x04, 0x31, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00 };
00518 
00519     // read data F1F2 identifiers...
00520     char reset1[8] =
00521     { 0x03, 0x22, 0xF1, 0xF2, 0x00, 0x00, 0x00, 0x00 };
00522     char res1[5] =
00523     { 0x10, 0x09, 0x62, 0xF1, 0xF2 };
00524 
00525     // not sure
00526     char reset2[8] =
00527     { 0x30, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 };
00528     char res2[5] =
00529     { 0x21, 0x00, 0x00, 0x60, 0xF2 };
00530 
00531     // security access
00532     char reset3[8] =
00533     { 0x02, 0x27, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00 };
00534     // security response
00535     char res3[4] =
00536     { 0x06, 0x67, 0x63, 0x00 };
00537 
00538     char reset3a[8] =
00539     { 0x02, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
00540     char res3a[3] =
00541     { 0x06, 0x50, 0x01 };
00542 
00543     // change to session '60'
00544     char reset3b[8] =
00545     { 0x02, 0x10, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00 };
00546     char res3b[3] =
00547     { 0x06, 0x50, 0x60 };
00548 
00549     // scurity access
00550     char reset4a[8] =
00551     { 0x06, 0x27, 0x64, 0x00, 0x00, 0x10, 0x60, 0x00 };
00552     char res4a[4] =
00553     { 0x02, 0x67, 0x64, 0x00 };
00554     count = 0;
00555     DebugWrite("***RESET1\r\n");
00556     sendCANCommand(id, reset1, 8);
00557     while (count++ < 20)
00558     {
00559         if (doFindExpectedResponse(&msg, resp, res1, 3) > 0)
00560         {
00561             printf("1!\r\n");
00562             break;
00563         }
00564         else
00565         {
00566             if (msg.id == 0x073)
00567             {
00568                 DebugWrite("Got-");
00569                 printCAN(&msg);
00570             }
00571         }
00572     }
00573     if (count >= 20)
00574     {
00575         DebugWrite("FAILED(1)\r\n");
00576         return;
00577     }
00578     count = 0;
00579     sendCANCommand(id, reset2, 8);
00580     DebugWrite("***RESET2\r\n");
00581     while (count++ < 20)
00582     {
00583         if (doFindExpectedResponse(&msg, resp, res2, 3) > 0)
00584         {
00585             DebugWrite("2!\r\n");
00586             break;
00587         }
00588         else
00589         {
00590 
00591         }
00592     }
00593     if (count >= 20)
00594     {
00595         DebugWrite("FAILED(2)\r\n");
00596         return;
00597     }
00598 
00599     // check msg byte 4, if 01, additional commands
00600     extrabyte = msg.data[3];
00601     if (extrabyte > 0)
00602     {
00603         count = 0;
00604         sendCANCommand(id, reset3a, 8);
00605         while (count++ < 20)
00606         {
00607             if (doFindExpectedResponse(&msg, resp, res3a, 3) > 0)
00608             {
00609                 DebugWrite("3a!\r\n");
00610                 break;
00611             }
00612             else
00613             {
00614 
00615             }
00616         }
00617         if (count >= 20)
00618         {
00619             DebugWrite("FAILED(3)\r\n");
00620             return;
00621         }
00622         count = 0;
00623         sendCANCommand(id, reset3b, 8);
00624         while (count++ < 20)
00625         {
00626             if (doFindExpectedResponse(&msg, resp, res3b, 3) > 0)
00627             {
00628                 DebugWrite("3b!\r\n");
00629                 break;
00630             }
00631             else
00632             {
00633 
00634             }
00635         }
00636         if (count >= 20)
00637         {
00638             DebugWrite("FAILED(4)\r\n");
00639             return;
00640         }
00641     }
00642 
00643     count = 0;
00644     sendCANCommand(id, reset3, 8);
00645     while (count++ < 20)
00646     {
00647         if (doFindExpectedResponse(&msg, resp, res3, 3) > 0)
00648         {
00649             DebugWrite("3!\r\n");
00650             break;
00651         }
00652         else
00653         {
00654 
00655         }
00656     }
00657     if (count >= 20)
00658     {
00659         DebugWrite("FAILED(5)\r\n");
00660         return;
00661     }
00662     if (extrabyte > 0)
00663     {
00664         count = 0;
00665         sendCANCommand(id, reset4a, 8);
00666         while (count++ < 20)
00667         {
00668             if (doFindExpectedResponse(&msg, resp, res4a, 3) > 0)
00669             {
00670                 DebugWrite("4a!\r\n");
00671                 break;
00672             }
00673             else
00674             {
00675 
00676             }
00677         }
00678         if (count >= 20)
00679         {
00680             DebugWrite("FAILED(6)\r\n");
00681             return;
00682         }
00683     }
00684     count = 0;
00685 
00686     DebugWrite("SENDING PUMP COMMAND\r\n");
00687     sendCANCommand(id, pump, 8);
00688     DebugWrite("SEQUENCE ON COMMAND\r\n");
00689     sendCANCommand(id, pump2, 8);
00690     s->primeFuelPumpCount = 5;
00691 }
00692 
00693 void doResetSequence(struct sHeatVars* s)
00694 {
00695     int extrabyte = 0;
00696     int count;
00697     sendWakeCommand(s);
00698 
00699     CANMessage msg;
00700     int id = CTRLCHANNEL;
00701     int resp = CTRLRESPONSE;
00702     if (s->heaternum == 2)
00703     {
00704         id = CTRLCHANNEL2;
00705         resp = CTRLRESPONSE2;
00706     }
00707     // read data F1F2 identifiers...
00708     char reset1[8] =
00709     { 0x03, 0x22, 0xF1, 0xF2, 0x00, 0x00, 0x00, 0x00 };
00710     char res1[5] =
00711     { 0x10, 0x09, 0x62, 0xF1, 0xF2 };
00712 
00713     // not sure
00714     char reset2[8] =
00715     { 0x30, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 };
00716     char res2[5] =
00717     { 0x21, 0x00, 0x00, 0x60, 0xF2 };
00718 
00719     // security access
00720     char reset3[8] =
00721     { 0x02, 0x27, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00 };
00722     // security response
00723     char res3[4] =
00724     { 0x06, 0x67, 0x63, 0x00 };
00725 
00726     // clear diagnostics
00727     char reset4[8] =
00728     { 0x04, 0x14, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00 };
00729     // response
00730     char res4[4] =
00731     { 0x01, 0x54, 0x63, 0x00 };
00732 
00733     // routine control
00734     char reset5[8] =
00735     { 0x04, 0x31, 0x01, 0xF0, 0x05, 0x00, 0x00, 0x00 };
00736     char res5[5] =
00737     { 0x04, 0x71, 0x01, 0xF0, 0x05 };
00738 
00739     char reset3a[8] =
00740     { 0x02, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
00741     char res3a[3] =
00742     { 0x06, 0x50, 0x01 };
00743 
00744     // change to session '60'
00745     char reset3b[8] =
00746     { 0x02, 0x10, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00 };
00747     char res3b[3] =
00748     { 0x06, 0x50, 0x60 };
00749 
00750     // scurity access
00751     char reset4a[8] =
00752     { 0x06, 0x27, 0x64, 0x00, 0x00, 0x10, 0x60, 0x00 };
00753     char res4a[4] =
00754     { 0x02, 0x67, 0x64, 0x00 };
00755     count = 0;
00756     DebugWrite("***RESET1\r\n");
00757     sendCANCommand(id, reset1, 8);
00758     while (count++ < 20)
00759     {
00760         if (doFindExpectedResponse(&msg, resp, res1, 3) > 0)
00761         {
00762             printf("1!\r\n");
00763             break;
00764         }
00765         else
00766         {
00767             if (msg.id == 0x073)
00768             {
00769                 DebugWrite("Got-");
00770                 printCAN(&msg);
00771             }
00772         }
00773     }
00774     if (count >= 20)
00775     {
00776         DebugWrite("FAILED(1)\r\n");
00777         return;
00778     }
00779     count = 0;
00780     sendCANCommand(id, reset2, 8);
00781     DebugWrite("***RESET2\r\n");
00782     while (count++ < 20)
00783     {
00784         if (doFindExpectedResponse(&msg, resp, res2, 3) > 0)
00785         {
00786             DebugWrite("2!\r\n");
00787             break;
00788         }
00789         else
00790         {
00791 
00792         }
00793     }
00794     if (count >= 20)
00795     {
00796         DebugWrite("FAILED(2)\r\n");
00797         return;
00798     }
00799     // check msg byte 4, if 01, additional commands
00800     extrabyte = msg.data[3];
00801     if (extrabyte > 0)
00802     {
00803         count = 0;
00804         sendCANCommand(id, reset3a, 8);
00805         while (count++ < 20)
00806         {
00807             if (doFindExpectedResponse(&msg, resp, res3a, 3) > 0)
00808             {
00809                 DebugWrite("3a!\r\n");
00810                 break;
00811             }
00812             else
00813             {
00814 
00815             }
00816         }
00817         if (count >= 20)
00818         {
00819             DebugWrite("FAILED(3)\r\n");
00820             return;
00821         }
00822         count = 0;
00823         sendCANCommand(id, reset3b, 8);
00824         while (count++ < 20)
00825         {
00826             if (doFindExpectedResponse(&msg, resp, res3b, 3) > 0)
00827             {
00828                 DebugWrite("3b!\r\n");
00829                 break;
00830             }
00831             else
00832             {
00833 
00834             }
00835         }
00836         if (count >= 20)
00837         {
00838             DebugWrite("FAILED(4)\r\n");
00839             return;
00840         }
00841     }
00842     count = 0;
00843     sendCANCommand(id, reset3, 8);
00844     while (count++ < 20)
00845     {
00846         if (doFindExpectedResponse(&msg, resp, res3, 3) > 0)
00847         {
00848             DebugWrite("3!\r\n");
00849             break;
00850         }
00851         else
00852         {
00853 
00854         }
00855     }
00856     if (count >= 20)
00857     {
00858         DebugWrite("FAILED(5)\r\n");
00859         return;
00860     }
00861     if (extrabyte > 0)
00862     {
00863         count = 0;
00864         sendCANCommand(id, reset4a, 8);
00865         while (count++ < 20)
00866         {
00867             if (doFindExpectedResponse(&msg, resp, res4a, 3) > 0)
00868             {
00869                 DebugWrite("4a!\r\n");
00870                 break;
00871             }
00872             else
00873             {
00874 
00875             }
00876         }
00877         if (count >= 20)
00878         {
00879             DebugWrite("FAILED(6)\r\n");
00880             return;
00881         }
00882     }
00883     count = 0;
00884     sendCANCommand(id, reset4, 8);
00885     while (count++ < 20)
00886     {
00887         if (doFindExpectedResponse(&msg, resp, res4, 3) > 0)
00888         {
00889             printf("4!\r\n");
00890             break;
00891         }
00892         else
00893         {
00894 
00895         }
00896     }
00897     if (count >= 20)
00898     {
00899         printf("FAILED(7)\r\n");
00900         return;
00901     }
00902     count = 0;
00903     sendCANCommand(id, reset5, 8);
00904     while (count++ < 20)
00905     {
00906         if (doFindExpectedResponse(&msg, resp, res5, 3) > 0)
00907         {
00908             printf("5!\r\n");
00909             break;
00910         }
00911         else
00912         {
00913 
00914         }
00915     }
00916     if (count >= 20)
00917     {
00918         printf("FAILED(8)\r\n");
00919         return;
00920     }
00921     printf("SUCCESS\r\n");
00922 }
00923 int doFindExpectedResponse(CANMessage* msg, const uint16_t expectedID, const char* expectedResponse, int charsInMatch)
00924 {
00925     char buff[256];
00926     //printf("fe-a\r\n");
00927     int timeout = 0;
00928     wiced_bool_t couldRead = WICED_FALSE;
00929     int incoming = 0;
00930 
00931     while ((incoming == 0) && (timeout++ < 10))
00932     {
00933 
00934         incoming = can2.read(*msg);
00935         //printf("fe-b %d\r\n", incoming);
00936         if (incoming > 0)
00937         {
00938             couldRead = WICED_TRUE;
00939         }
00940         if (!couldRead)
00941         {
00942             wait(0.01);
00943         }
00944     }
00945     //printf("fe-c\r\n");
00946     if (incoming > 0)
00947     {
00948 
00949         //CAN_FIFORelease(CAN1, CAN_FIFO0);
00950         if (msg->id != expectedID)
00951         {
00952             //sprintf(buff, "No match: %04X\r\n", (unsigned int) msg->StdId);
00953             //DebugWrite(buff);
00954             return 0; // not a match
00955         }
00956         // ignore byte 1
00957         for (int i = 1; i < charsInMatch; i++)
00958         {
00959             if (!(msg->data[i] == expectedResponse[i]))
00960             {
00961                 // no match
00962                 return 0;
00963             }
00964             return 1; // match
00965         }
00966         // no chars in match, always a match?
00967         return 1;
00968     }
00969     else
00970     {
00971         return -1; // no read
00972     }
00973 }
00974 void printCAN(CANMessage *canMsg)
00975 {
00976     char buff[256];
00977     sprintf(buff, "ID,%04X:", (unsigned int) canMsg->id);
00978 
00979     DebugWrite(buff);
00980     for (int i = 0; i < canMsg->len; i++)
00981     {
00982         sprintf(buff, "%02X ", canMsg->data[i]);
00983         DebugWrite(buff);
00984     }
00985     DebugWrite("\r\n");
00986 }
00987 
00988 void printCANTx(CANMessage *canMsg)
00989 {
00990     char buff[256];
00991     sprintf(buff, "->ID,%04X:", (unsigned int) canMsg->id);
00992 
00993     DebugWrite(buff);
00994     for (int i = 0; i < canMsg->len; i++)
00995     {
00996         sprintf(buff, "%02X ", canMsg->data[i]);
00997         DebugWrite(buff);
00998     }
00999     DebugWrite("\r\n");
01000 }
01001 void sendGetRuntime(struct sHeatVars *s, char *buff)
01002 {
01003     int count = 0;
01004     CANMessage rxMsg;
01005     int id;
01006     int resp;
01007     id = CTRLCHANNEL;
01008     resp = CTRLRESPONSE;
01009     if (s->heaternum == 2)
01010     {
01011         id = CTRLCHANNEL2;
01012         resp = CTRLRESPONSE2;
01013     }
01014 
01015     const char msgbytes[8] =
01016     { 0x03, 0x22, 0xFD, 0x17, 0x00, 0x00, 0x00, 0x00 };
01017     const char continuePacket[8] =
01018     { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
01019 
01020     sendCANCommand(id, msgbytes, 8);
01021     //The control unit reads out the operating hours counter using the UDS service 22 ID: FD17
01022     while (count++ < 10)
01023     {
01024         // just expect the ID (0
01025         if (doFindExpectedResponse(&rxMsg, resp, msgbytes, 0) > 0)
01026         {
01027             printCAN(&rxMsg);
01028             // response in the format 59
01029             // the first byte dictates the length
01030 
01031             //073C:03 59 02 7B 05 48 C3 01
01032 
01033             if (rxMsg.data[0] < 0x10)
01034             {
01035                 DebugWrite("Single Message. Shouldn't happen\r\n");
01036             }
01037             else if (rxMsg.data[0] < 0x20)
01038             {
01039 
01040                 int totalLength = rxMsg.data[1];
01041                 unsigned int totalExpectedPackets = ((totalLength - 7) / 7) + 1;
01042                 unsigned char dataBytes[6 + totalExpectedPackets * 7];
01043                 memset(dataBytes, 0, 6 + totalExpectedPackets * 7);
01044 
01045                 // first packet contains 6 bytes of data, additional contain 7
01046                 // length 11: 1 extra packet        ((11 - 6 - 1) \ 7) + = 4\7 + 1 = 1
01047                 // length 13: 1 extra packet        ((13 - 6 - 1) \ 7) + = 6\7 + 1 = 1
01048                 // length 14: 2 packets             ((14 - 6 - 1) \ 7) + = 7\7 + 1 = 2
01049                 // length 20: 2 packets             ((20 - 6 - 1) \ 7) + = 7\7 + 1 = 2
01050                 // length 21: 3 packets             ((21 - 6 - 1) \ 7) + = 7\7 + 1 = 3
01051                 // Packets = lenght is ((length - 7) \ 7) + 1
01052 
01053               sprintf(buff, "multi message start, length %d\r\n", rxMsg.data[1]);
01054               DebugWrite(buff);
01055 
01056                 printCAN(&rxMsg);
01057                 /*Query 03 19 02 08
01058                  * ID,073C:[10 0B] [59 02] [7B] 00 02 11]
01059                  * ID,073C:21 2B 00 02 A1 2A xx xx
01060                  * 10: Multi message start packet
01061                  * 0B: Length (11 DATA bytes).  x'd out non-data
01062                  * 59: response type 59
01063                  * 02: subfunction 2
01064                  * 7B: mask
01065                  * 00 02 11: first 3 bytes of fault.  Need next part
01066                  */
01067                 // get the first fault code, bytes 4-7
01068                 sendCANCommand(id, continuePacket, 8);
01069                 CANMessage additionalRxMsg[totalExpectedPackets];
01070                 int currentPacket = 0;
01071                 while (count++ < 10)
01072                 {
01073 
01074                     if (doFindExpectedResponse(&(additionalRxMsg[currentPacket]), resp, msgbytes, 0) > 0)
01075                     {
01076                         count = 0;
01077                         currentPacket++;
01078                         if (currentPacket >= totalExpectedPackets)
01079                         {
01080                             DebugWrite("Found all additional packets\r\n");
01081 
01082                             memcpy(dataBytes, rxMsg.data + 2, 6); // 6 initial data bytes
01083                             for (int i = 0; i < totalExpectedPackets; i++)
01084                             {
01085                                 memcpy(dataBytes + 6 + (totalExpectedPackets * i), additionalRxMsg[i].data + 1, 7);
01086                             }
01087 
01088                             DebugWrite("Runtime Data bytes: ");
01089                             for (int i = 0; i < totalLength; i++)
01090                             {
01091                                 sprintf(buff, "%02X ", dataBytes[i]);
01092                                 DebugWrite(buff);
01093                             }
01094                             //DebugWrite("\r\n");
01095 
01096                             long runtime = -1;
01097                             // bytes 3-6 are runtime
01098                             if (totalLength > 6)
01099                             {
01100                                 runtime = dataBytes[3];
01101                                 runtime = runtime << 8;
01102                                 runtime = runtime + dataBytes[4];
01103                                 runtime = runtime << 8;
01104                                 runtime = runtime + dataBytes[5];
01105                                 runtime = runtime << 8;
01106                                 runtime = runtime + dataBytes[6];
01107                                 s->heaterRuntime = runtime;
01108                             }
01109                             s->heaterRuntime = runtime;
01110                             break;
01111                         }
01112 
01113                     }
01114                 } // outer while
01115             }
01116         }
01117     } // while
01118     printf("f-b\r\n");
01119     if (count >= 10)
01120     {
01121         printf("FAILED or done\r\n");
01122         return;
01123     }
01124     return;
01125 }
01126 wiced_result_t sendGetGeneric(struct sHeatVars *s, char *buff, const char msgbytes[8], CANMessage* rxMsg)
01127 {
01128     int id;
01129     int resp = CTRLRESPONSE;
01130     id = CTRLCHANNEL;
01131     if (s->heaternum == 2)
01132     {
01133         id = CTRLCHANNEL2;
01134         resp = CTRLRESPONSE2;
01135     }
01136 
01137     const char continuePacket[8] =
01138     { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
01139 
01140     //DebugWrite("************\r\n");
01141     sendCANCommand(id, msgbytes, 8);
01142     if (doFindExpectedResponse(rxMsg, resp, msgbytes, 0) > 0)
01143     {
01144         return WICED_SUCCESS;
01145     }
01146     return WICED_NOT_FOUND;
01147 }
01148 void sendGetTemperatures(struct sHeatVars *s, char *buff)
01149 {
01150 
01151     int id;
01152     int count;
01153     int resp = CTRLRESPONSE;
01154     id = CTRLCHANNEL;
01155     if (s->heaternum == 2)
01156     {
01157         id = CTRLCHANNEL2;
01158         resp = CTRLRESPONSE2;
01159     }
01160     CANMessage rxMsg;
01161     const char msgbytes[8] =
01162     { 0x03, 0x22, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00 };
01163 
01164     const char continuePacket[8] =
01165     { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
01166 
01167     count = 0;
01168 
01169     //DebugWrite("************\r\n");
01170     sendCANCommand(id, msgbytes, 8);
01171     // just expect the ID (0
01172 
01173     if (doFindExpectedResponse(&rxMsg, resp, msgbytes, 0) > 0)
01174     {
01175         //DebugWrite("********(a)****\r\n");
01176         printCAN(&rxMsg);
01177 
01178         // response is a multi part
01179         if (rxMsg.data[0] < 0x10)
01180         {
01181             DebugWrite("Single Message. Shouldn't happen\r\n");
01182         }
01183         else if (rxMsg.data[0] < 0x20)
01184         {
01185             int totalLength = rxMsg.data[1];
01186             unsigned int totalExpectedPackets = ((totalLength - 7) / 7) + 1;
01187             unsigned char dataBytes[6 + totalExpectedPackets * 7];
01188             memset(dataBytes, 0, 6 + totalExpectedPackets * 7);
01189 
01190             // first packet contains 6 bytes of data, additional contain 7
01191             // length 11: 1 extra packet        ((11 - 6 - 1) \ 7) + = 4\7 + 1 = 1
01192             // length 13: 1 extra packet        ((13 - 6 - 1) \ 7) + = 6\7 + 1 = 1
01193             // length 14: 2 packets             ((14 - 6 - 1) \ 7) + = 7\7 + 1 = 2
01194             // length 20: 2 packets             ((20 - 6 - 1) \ 7) + = 7\7 + 1 = 2
01195             // length 21: 3 packets             ((21 - 6 - 1) \ 7) + = 7\7 + 1 = 3
01196             // Packets = lenght is ((length - 7) \ 7) + 1
01197 
01198             sprintf(buff, "multi message start, length %d\r\n", rxMsg.data[1]);
01199             DebugWrite(buff);
01200 
01201             printCAN(&rxMsg);
01202             /*Query 03 19 02 08
01203              * ID,073C:[10 0B] [59 02] [7B] 00 02 11]
01204              * ID,073C:21 2B 00 02 A1 2A xx xx
01205              * 10: Multi message start packet
01206              * 0B: Length (11 DATA bytes).  x'd out non-data
01207              * 59: response type 59
01208              * 02: subfunction 2
01209              * 7B: mask
01210              * 00 02 11: first 3 bytes of fault.  Need next part
01211              */
01212             // get the first fault code, bytes 4-7
01213             sendCANCommand(id, continuePacket, 8);
01214             CANMessage additionalRxMsg[totalExpectedPackets];
01215             int currentPacket = 0;
01216             while (count++ < 10)
01217             {
01218 
01219                 if (doFindExpectedResponse(&(additionalRxMsg[currentPacket]), resp, msgbytes, 0) > 0)
01220                 {
01221                     count = 0;
01222                     currentPacket++;
01223                     if (currentPacket >= totalExpectedPackets)
01224                     {
01225                         //DebugWrite("Found all additional packets\r\n");
01226 
01227                         memcpy(dataBytes, rxMsg.data + 2, 6); // 6 initial data bytes
01228                         for (int i = 0; i < totalExpectedPackets; i++)
01229                         {
01230                             memcpy(dataBytes + 6 + (totalExpectedPackets * i), additionalRxMsg[i].data + 1, 7);
01231                         }
01232 
01233                         s->flameTemp = dataBytes[3];
01234                         s->flameTemp = s->flameTemp << 8;
01235                         s->flameTemp += dataBytes[4];
01236                         s->flameTemp -= 5000;
01237 
01238                         s->inletTemp = dataBytes[5];
01239                         s->inletTemp = s->inletTemp << 8;
01240                         s->inletTemp += dataBytes[6];
01241                         s->inletTemp -= 5000;
01242 
01243                         s->outletTemp = dataBytes[7];
01244                         s->outletTemp = s->outletTemp << 8;
01245                         s->outletTemp += dataBytes[8];
01246                         s->outletTemp -= 5000;
01247 
01248                         DebugWrite(" **\r\n");
01249                         //DebugWrite("\r\n");
01250 
01251                         //long runtime = -1;
01252                         // bytes 3-6 are runtime
01253                         /*
01254                          if (totalLength > 6)
01255                          {
01256                          runtime = dataBytes[3];
01257                          runtime = runtime << 8;
01258                          runtime = runtime + dataBytes[4];
01259                          runtime = runtime << 8;
01260                          runtime = runtime + dataBytes[5];
01261                          runtime = runtime << 8;
01262                          runtime = runtime + dataBytes[6];
01263                          s->heaterRuntime = runtime;
01264                          }
01265                          s->heaterRuntime = runtime;
01266                          */
01267                         break;
01268                     }
01269                 }
01270             }
01271         }
01272     }
01273     printf("f-b\r\n");
01274     if (count >= 10)
01275     {
01276         printf("FAILED\r\n");
01277         return;
01278     }
01279     return;
01280 }
01281 void sendGetBattery(struct sHeatVars *s, char *buff)
01282 {
01283     int count;
01284     CANMessage rxMsg;
01285     char msgbytes[8] =
01286     { 0x03, 0x22, 0xFD, 0x04, 0x00, 0x00, 0x00, 0x00 };
01287 // response is on 73C: 0x05, 0x62, 0xFD, 0x04, [0x00, 0x7D], 0xB0, 0x1C
01288     int id;
01289     int resp = CTRLRESPONSE;
01290     id = CTRLCHANNEL;
01291     if (s->heaternum == 2)
01292     {
01293         id = CTRLCHANNEL2;
01294         resp = CTRLRESPONSE2;
01295     }
01296     count = 0;
01297     sendCANCommand(id, msgbytes, 8);
01298     int batt = 0;
01299     msgbytes[1] = 0x62;
01300     while (count++ < 10)
01301     {
01302 // just expect the ID (0
01303         if (doFindExpectedResponse(&rxMsg, resp, msgbytes, 4) > 0)
01304         {
01305             printCAN(&rxMsg);
01306             batt = rxMsg.data[4];
01307             batt = batt << 8;
01308             batt += rxMsg.data[5];
01309             s->battV = batt;
01310         }
01311     }
01312 }
01313 void sendGetAltitude(struct sHeatVars *s, char *buff)
01314 {
01315     //DebugWrite("ALTITUDE******\r\n");
01316     int count;
01317     CANMessage rxMsg;
01318     char msgbytes[8] =
01319     { 0x03, 0x22, 0xFD, 0x36, 0x00, 0x00, 0x00, 0x00 };
01320 // response is on 73C: 0x05, 0x62, 0xFD, 0x04, [0x00, 0x7D], 0xB0, 0x1C
01321     int id;
01322     int resp = CTRLRESPONSE;
01323     id = CTRLCHANNEL;
01324     if (s->heaternum == 2)
01325     {
01326         id = CTRLCHANNEL2;
01327         resp = CTRLRESPONSE2;
01328     }
01329     count = 0;
01330     sendCANCommand(id, msgbytes, 8);
01331     int alt = 0;
01332     msgbytes[1] = 0x62;
01333     while (count++ < 10)
01334     {
01335 // just expect the ID (0
01336         if (doFindExpectedResponse(&rxMsg, resp, msgbytes, 4) > 0)
01337         {
01338             printCAN(&rxMsg);
01339             alt = rxMsg.data[4];
01340             alt = alt << 8;
01341             alt += rxMsg.data[5];
01342             s->altitude = alt / 10;
01343         }
01344     }
01345     //DebugWrite("ALTITUDE******\r\n");
01346 }
01347 
01348 void sendGetFault(struct sHeatVars *s, char *buff)
01349 {
01350     //DebugWrite("Fault command\r\n");
01351     CANMessage rxMsg;
01352     int count;
01353     // 3 bytes, function 19, command 2, mask 8 (all confirmed errors) (failed this cycle)
01354     const char msgbytes[8] =
01355     { 0x03, 0x19, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00 };
01356     const char continuePacket[8] =
01357     { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
01358 
01359     int id;
01360     int resp = CTRLRESPONSE;
01361     id = CTRLCHANNEL;
01362     if (s->heaternum == 2)
01363     {
01364         id = CTRLCHANNEL2;
01365         resp = CTRLRESPONSE2;
01366     }
01367     count = 0;
01368     sendCANCommand(id, msgbytes, 8);
01369 
01370     while (count++ < 10)
01371     {
01372         // just expect the ID (0
01373         if (doFindExpectedResponse(&rxMsg, resp, msgbytes, 0) > 0)
01374         {
01375             printCAN(&rxMsg);
01376             // response in the format 59
01377             // the first byte dictates the length
01378 
01379             //073C:03 59 02 7B 05 48 C3 01
01380 
01381             if (rxMsg.data[0] < 0x10)
01382             {
01383                 DebugWrite("Single Message. ");
01384                 if (rxMsg.data[0] == 0x03)
01385                 {
01386                     // 59 is a resonse.  Mask info isnt useful because no faults
01387                     if (rxMsg.data[1] == 0x59)
01388                     {
01389                         // no faults
01390                         if (s->currentError != 0)
01391                         {
01392                             s->errorChangeFlag = 1;
01393                         }
01394                         sprintf(buff, "NO FAULTS (reset)\r\n");
01395                         DebugWrite(buff);
01396                         s->currentError = 0x00;
01397                         s->errorHistory[0] = 0x0;
01398                         s->errorHistory[1] = 0x0;
01399                         s->errorHistory[2] = 0x0;
01400                         s->errorHistory[3] = 0x0;
01401                         s->errorHistory[4] = 0x0;
01402                         s->errorHistory[5] = 0x0;
01403                         break; // out of the loop
01404                     }
01405                 }
01406                 else if ((rxMsg.data[0] == 0x07) && rxMsg.data[1] == 0x59)
01407                 {
01408 
01409                     //ID,073C:07 59 02 7B 00 02 11 2A
01410                     // 07 length
01411                     // 59 response
01412 
01413                     // one fault.  Is it a current fault?
01414                     if ((rxMsg.data[5] == 0x00) && (rxMsg.data[6] == 0x00))
01415                     {
01416                         // the fault isn't a fault.
01417                         sprintf(buff, "NO FAULTS\r\n");
01418                         DebugWrite(buff);
01419                         if (s->currentError != 0)
01420                         {
01421                             s->errorChangeFlag = 1;
01422                         }
01423                         s->currentError = 0x00;
01424                         s->errorHistory[0] = 0x0;
01425                         s->errorHistory[1] = 0x0;
01426                         s->errorHistory[2] = 0x0;
01427                         s->errorHistory[3] = 0x0;
01428                         s->errorHistory[4] = 0x0;
01429                         s->errorHistory[5] = 0x0;
01430                     }
01431                     else
01432                     {
01433 
01434                         //A: 0010 1010 bit 1 is test failed this cycle
01435                         //B: 0010 1011 bit 0 is test failed.  Seems to be considered
01436                         //                   active if bit 0 is '1'
01437 
01438                         // bit 5 test failed since last clear
01439 
01440                         //07 59 02 7B 00 02 11 2A
01441 
01442                         uint16_t newError = rxMsg.data[5];
01443                         newError *= 256;
01444                         newError += rxMsg.data[6];
01445                         wiced_bool_t gotAnError = WICED_FALSE;
01446                         // is it a current fault?
01447                         if ((rxMsg.data[7] & 0x01) == 0x01)
01448                         {
01449                             gotAnError = WICED_TRUE;
01450                             if (s->currentError != newError)
01451                             {
01452                                 s->errorChangeFlag = 1;
01453                             }
01454                             // active fault
01455                             s->currentError = newError;
01456                         }
01457                         if (!gotAnError)
01458                         {
01459                             s->currentError = 0;
01460                         }
01461                         // also first history fault
01462                         s->errorHistory[0] = newError;
01463 
01464                         sprintf(buff, "FAULT(h%d): %02X%02X\r\n", s->heaternum, rxMsg.data[5], rxMsg.data[6]);
01465                         DebugWrite(buff);
01466 
01467 //                      if (s->currentError != newError)
01468 //                      {
01469 //                          s->errorChangeFlag = 1;
01470 //                      }
01471                         //errorChangeFlag
01472                     }
01473                 }
01474             }
01475             else if (rxMsg.data[0] < 0x20)
01476             {
01477 
01478                 int totalLength = rxMsg.data[1];
01479                 unsigned int totalExpectedPackets = ((totalLength - 7) / 7) + 1;
01480                 unsigned char dataBytes[6 + totalExpectedPackets * 7];
01481                 memset(dataBytes, 0, 6 + totalExpectedPackets * 7)
01482 
01483                 ;
01484                 // first packet contains 6 bytes of data, additional contain 7
01485                 // length 11: 1 extra packet        ((11 - 6 - 1) \ 7) + = 4\7 + 1 = 1
01486                 // length 13: 1 extra packet        ((13 - 6 - 1) \ 7) + = 6\7 + 1 = 1
01487                 // length 14: 2 packets             ((14 - 6 - 1) \ 7) + = 7\7 + 1 = 2
01488                 // length 20: 2 packets             ((20 - 6 - 1) \ 7) + = 7\7 + 1 = 2
01489                 // length 21: 3 packets             ((21 - 6 - 1) \ 7) + = 7\7 + 1 = 3
01490                 // Packets = lenght is ((length - 7) \ 7) + 1
01491 
01492 //              sprintf(buff, "multi message start, length %d\r\n", rxMsg.data[1]);
01493 //              DebugWrite(buff);
01494 
01495                 printCAN(&rxMsg);
01496                 /*Query 03 19 02 08
01497                  * ID,073C:[10 0B] [59 02] [7B] 00 02 11]
01498                  * ID,073C:21 2B 00 02 A1 2A xx xx
01499                  * 10: Multi message start packet
01500                  * 0B: Length (11 DATA bytes).  x'd out non-data
01501                  * 59: response type 59
01502                  * 02: subfunction 2
01503                  * 7B: mask
01504                  * 00 02 11: first 3 bytes of fault.  Need next part
01505                  */
01506                 // get the first fault code, bytes 4-7
01507                 sendCANCommand(id, continuePacket, 8);
01508                 CANMessage additionalRxMsg[totalExpectedPackets];
01509                 int currentPacket = 0;
01510                 while (count++ < 10)
01511                 {
01512                     if (doFindExpectedResponse(&(additionalRxMsg[currentPacket]), resp, msgbytes, 0) > 0)
01513                     {
01514                         count = 0;
01515                         currentPacket++;
01516                         if (currentPacket >= totalExpectedPackets)
01517                         {
01518                             DebugWrite("Found all additional packets\r\n");
01519 
01520                             memcpy(dataBytes, rxMsg.data + 2, 6); // 6 initial data bytes
01521                             for (int i = 0; i < totalExpectedPackets; i++)
01522                             {
01523                                 sprintf(printbuff, "- copying packet %d to databytes + %d\r\n", i, 6 + (i) * 7);
01524                                 DebugWrite(printbuff);
01525                                 memcpy(dataBytes + 6 + ((i) * 7), additionalRxMsg[i].data + 1, 7);
01526 
01527                             }
01528                             DebugWrite("Data bytes: ");
01529                             for (int i = 0; i < totalLength; i++)
01530                             {
01531                                 sprintf(buff, "%02X ", dataBytes[i]);
01532                                 DebugWrite(buff);
01533                             }
01534                             DebugWrite("\r\n");
01535 
01536                             uint16_t newError;
01537                             wiced_bool_t gotAnError = WICED_FALSE;
01538                             //Data bytes: 59 02 7B [00 02 11 2B] [00 02 A1 28]
01539 
01540                             for (int i = 0; i < 6; i++)
01541                             {
01542                                 s->errorHistory[i] = 0;
01543                             }
01544                             for (int i = 3; i < totalLength; i += 4)
01545                             {
01546                                 newError = dataBytes[i + 1];
01547                                 newError *= 256;
01548                                 newError += dataBytes[i + 2];
01549 
01550                                 // is it a current fault?
01551                                 if ((dataBytes[i + 3] & 0x01) == 0x01)
01552                                 {
01553                                     gotAnError = WICED_TRUE;
01554                                     if (s->currentError != newError)
01555                                     {
01556                                         s->errorChangeFlag = 1;
01557                                     }
01558                                     // active fault
01559                                     s->currentError = newError;
01560                                 }
01561                                 // history fault
01562                                 if (((i - 3) / 4) < 6)
01563                                 {
01564                                     s->errorHistory[(i - 3) / 4] = newError;
01565                                 }
01566 
01567                                 sprintf(buff, "FAULT: %02X%02X\r\n", dataBytes[i + 1], dataBytes[i + 2]);
01568                                 DebugWrite(buff);
01569                             }
01570                             if (!gotAnError)
01571                             {
01572                                 s->currentError = 0; // no error to start.
01573                             }
01574                             // clear the remainder
01575                             break;
01576                         }
01577                     }
01578                 }
01579             }
01580         }
01581     } // while
01582     printf("f-b\r\n");
01583     if (count >= 10)
01584     {
01585         printf("FAILED\r\n");
01586         return;
01587     }
01588     printf("f-c\r\n");
01589     if ((rxMsg.data[0] == 0x03) && (rxMsg.data[1] == 0x59) && (rxMsg.data[5] == 0x56) && (rxMsg.data[6] == 0x78))
01590     {
01591 
01592         if (s->currentError != 0)
01593         {
01594             s->errorChangeFlag = 1;
01595         }
01596         sprintf(buff, "NO FAULTS (reset)\r\n");
01597         DebugWrite(buff);
01598         s->currentError = 0x00;
01599         s->errorHistory[0] = 0x0;
01600         s->errorHistory[0] = 0x0;
01601         s->errorHistory[0] = 0x0;
01602         s->errorHistory[0] = 0x0;
01603         s->errorHistory[0] = 0x0;
01604         s->errorHistory[0] = 0x0;
01605     }
01606     else if ((rxMsg.data[0] == 0x03) && (rxMsg.data[1] == 0x59) && (rxMsg.data[5] == 0x00) && (rxMsg.data[6] == 0x00))
01607     {
01608         if (s->currentError != 0)
01609         {
01610             s->errorChangeFlag = 1;
01611         }
01612         sprintf(buff, "NO FAULTS(1)\r\n");
01613         DebugWrite(buff);
01614         s->currentError = 0x00;
01615         s->errorHistory[0] = 0x0;
01616         s->errorHistory[0] = 0x0;
01617         s->errorHistory[0] = 0x0;
01618         s->errorHistory[0] = 0x0;
01619         s->errorHistory[0] = 0x0;
01620         s->errorHistory[0] = 0x0;
01621     }
01622     else if ((rxMsg.data[0] == 0x07) && (rxMsg.data[1] == 0x59) && (rxMsg.data[2] == 0x02))
01623     {
01624         if ((rxMsg.data[5] == 0x00) && (rxMsg.data[6] == 0x00))
01625         {
01626             sprintf(buff, "NO FAULTS\r\n");
01627             DebugWrite(buff);
01628             if (s->currentError != 0)
01629             {
01630                 s->errorChangeFlag = 1;
01631             }
01632             s->currentError = 0x00;
01633             s->errorHistory[0] = 0x0;
01634             s->errorHistory[1] = 0x0;
01635             s->errorHistory[2] = 0x0;
01636             s->errorHistory[3] = 0x0;
01637             s->errorHistory[4] = 0x0;
01638             s->errorHistory[5] = 0x0;
01639         }
01640         else
01641         {
01642             sprintf(buff, "FAULT: %02X%02X\r\n", rxMsg.data[5], rxMsg.data[6]);
01643             DebugWrite(buff);
01644             uint16_t newError = rxMsg.data[5];
01645             newError *= 256;
01646             newError += rxMsg.data[6];
01647             if (s->currentError != newError)
01648             {
01649                 s->errorChangeFlag = 1;
01650             }
01651             //errorChangeFlag
01652             s->currentError = newError;
01653             s->errorHistory[0] = newError;
01654         }
01655         printf("SUCCESS\r\n");
01656     }
01657     else if ((rxMsg.data[0] == 0x03) && (rxMsg.data[1] == 0x59) && (rxMsg.data[2] == 0x02))
01658     {
01659         // this means cleared in both cases!
01660         if (s->currentError != 0)
01661         {
01662             s->errorChangeFlag = 1;
01663         }
01664         sprintf(buff, "NO FAULTS(2)\r\n");
01665         DebugWrite(buff);
01666         s->currentError = 0x00;
01667         s->errorHistory[0] = 0x0;
01668         s->errorHistory[1] = 0x0;
01669         s->errorHistory[2] = 0x0;
01670         s->errorHistory[3] = 0x0;
01671         s->errorHistory[4] = 0x0;
01672         s->errorHistory[5] = 0x0;
01673     }
01674     else if ((rxMsg.data[0] == 0x10) && (rxMsg.data[1] == 0x0B))
01675     {
01676         sprintf(buff, " MULTI FAULT: %02X%02X\r\n", rxMsg.data[6], rxMsg.data[7]);
01677         DebugWrite(buff);
01678         uint16_t newError = rxMsg.data[6];
01679         newError *= 256;
01680         newError += rxMsg.data[7];
01681         if (s->currentError != newError)
01682         {
01683             s->errorChangeFlag = 1;
01684         }
01685         s->currentError = newError;
01686         s->errorHistory[0] = newError;
01687     }
01688     else
01689     {
01690         sprintf(buff, "OTHER RESPONSE\r\n");
01691         DebugWrite(buff);
01692         printCAN(&rxMsg);
01693     }
01694     printf("f-d\r\n");
01695 }
01696 
01697 void readCAN(struct sHeatVars *s)
01698 {
01699     // find the heater to update in some cases
01700     int count = 0;
01701     struct sHeatVars* heaterToUpdate = NULL;
01702     //DebugWrite("read\r\n");
01703     CANMessage canMsg;
01704     
01705     int incoming = can2.read(canMsg);
01706     while ((incoming > 0) && (count++ < 10))
01707     {
01708        led1 = 1;
01709         // start blank
01710         if ((canMsg.id == 0x0055)) {
01711             // sub our own
01712             DebugWrite("SUBSTITUTE ALTITUDE CMD\r\n");
01713             sendAltitudeMode(s);
01714         }
01715         if ((canMsg.id == 0x07A0) || (canMsg.id == 0x060D) || (canMsg.id == 0x0057) )
01716         {
01717             otherControllerDetected = 300;
01718             DebugWrite("\r\n****OTHER CONTROLLER ON NETWORK*****\r\n");
01719         }
01720         if (((canMsg.id != 0x0625) && (canMsg.id != 0x02C4)) && (canMsg.id != 0x02C6) && (canMsg.id != 0x0626) && (canMsg.id != 0x02D0)
01721                 && (canMsg.id != 0x02CE))
01722         {
01723             
01724             DebugWrite("0-");
01725             printCAN(&canMsg);
01726         }
01727         else if ((canMsg.id == 0x0625) || (canMsg.id == 0x0626))
01728         {
01729             if ((canMsg.id == 0x0625) && (heaterState[0].bustype == HEATERTYPECAN) && (heaterState[0].heaternum == 1))
01730             {
01731                 heaterToUpdate = &(heaterState[0]);
01732             }
01733             else if ((canMsg.id == 0x0626) && (heaterState[0].bustype == HEATERTYPECAN) && (heaterState[0].heaternum == 2))
01734             {
01735                 heaterToUpdate = &(heaterState[0]);
01736             }
01737             heaterToUpdate->heaterDetected = 60; // preserve for a min.
01738             // unpack and document
01739             NM_Heater_1_t heaterInfo;
01740             Unpack_NM_Heater_1_mydbc(&heaterInfo, canMsg.data, 0);
01741             //DebugWrite("NM_HEATER_");
01742 
01743             /*
01744              sprintf(printbuff, "%d,%lu,", heaterToUpdate->heaternum, heaterInfo.SerialNumber);
01745              DebugWrite(printbuff);
01746              if (heaterInfo.HeaterInitFinished)
01747              {
01748              DebugWrite("DoneInit,");
01749              }
01750              else
01751              {
01752              DebugWrite("NOINIT,");
01753              }
01754              */
01755             if (heaterInfo.HeaterType == 0)
01756             {
01757 //              DebugWrite("Air,");
01758                 if (heaterToUpdate->setpoint == 0)
01759                 {
01760                     heaterToUpdate->setpoint = 250;
01761                 }
01762             }
01763             else if (heaterInfo.HeaterType == 1)
01764             {
01765 //              DebugWrite("Water,");
01766                 heaterToUpdate->setpoint = 0;
01767             }
01768             else
01769             {
01770 //              DebugWrite("Unknown,");
01771             }
01772             if (heaterInfo.AltitudeSensorOnBoard)
01773             {
01774 //              DebugWrite("OB Alt,");
01775                 heaterToUpdate->OBAltitude = WICED_TRUE;
01776             }
01777             else
01778             {
01779 //              DebugWrite("NO OB ALT,");
01780                 heaterToUpdate->OBAltitude = WICED_FALSE;
01781             }
01782             /*(
01783              if (heaterInfo.OperateEasyFan)
01784              {
01785              DebugWrite("EZFAN,");
01786              }
01787              else
01788              {
01789              DebugWrite("NO-EZFAN,");
01790              }
01791              sprintf(printbuff, "Op:%u,", heaterInfo.OperatingModes);
01792              DebugWrite(printbuff);
01793 
01794              DebugWrite(",");
01795              DebugWrite("\r\n");
01796              */
01797         }
01798         else if ((canMsg.id == 0x02C6) || (canMsg.id == 0x02D0))
01799         {
01800 
01801             if (canMsg.id == 0x02C6)
01802             {
01803                 if ((heaterState[0].bustype == HEATERTYPECAN) && (heaterState[0].heaternum == 1))
01804                 {
01805                     heaterToUpdate = &(heaterState[0]);
01806                 }
01807                 else
01808                 {
01809                     DebugWrite("Unable to update 0x02C6\r\n");
01810                 }
01811             }
01812             else if (canMsg.id == 0x02D0)
01813             {
01814                 if ((heaterState[0].bustype == HEATERTYPECAN) && (heaterState[0].heaternum == 2))
01815                 {
01816                     heaterToUpdate = &(heaterState[0]);
01817                 }
01818                 else
01819                 {
01820                     DebugWrite("Unable to update 0x02D0\r\n");
01821                 }
01822             }
01823             if (heaterToUpdate == NULL)
01824             {
01825                 DebugWrite("HEATERTOUPDATENULL\r\n");
01826                 return;
01827             }
01828             int lowRange = canMsg.data[1];
01829             lowRange = lowRange << 8;
01830             lowRange += canMsg.data[0];
01831 
01832             int highRange = canMsg.data[3];
01833             highRange = highRange << 8;
01834             highRange += canMsg.data[2];
01835             if (lowRange > highRange)
01836             {
01837                 int temp = lowRange;
01838                 lowRange = highRange;
01839                 highRange = temp;
01840             }
01841 
01842             //sprintf(printbuff, "Temp range %d - %d heater %d\r\n", lowRange, highRange, heaterToUpdate->heaternum);
01843             //DebugWrite(printbuff);
01844             //printCAN(&canMsg);
01845 
01846             /*
01847              * now detected by heater NM command
01848              if (heaterToUpdate->heaternum == 2)
01849              {
01850              // eventually replace with the equivalent of 0x0625
01851              if (highRange > 500)
01852              {
01853              //sprintf(printbuff, "heater %d setpoint > 500\r\n", heaterToUpdate->heaternum);
01854              //DebugWrite(printbuff);
01855              heaterToUpdate->setpoint = 0;
01856 
01857              // fluid heater
01858              }
01859              else
01860              {
01861              //
01862              if (heaterToUpdate->setpoint == 0)
01863              {
01864              // sprintf(printbuff, "heater %d setpoint 250", heaterToUpdate->heaternum);
01865              // DebugWrite(printbuff);
01866 
01867              heaterToUpdate->setpoint = 250; // default value.  Ignored mostly in CAN land.
01868              }
01869              }
01870              }
01871              */
01872         }
01873         else if ((canMsg.id == 0x02C4) || (canMsg.id == 0x02CE))
01874         {
01875             int heater = 1;
01876             if (canMsg.id == 0x02CE)
01877             {
01878                 heater = 2;
01879             }
01880             if ((heaterState[0].bustype == HEATERTYPECAN) && (heaterState[0].heaternum == heater))
01881             {
01882                 heaterToUpdate = &(heaterState[0]);
01883             }
01884             else
01885             {
01886                 DebugWrite("Unable to update 0x02C6\r\n");
01887             }
01888             //DebugWrite("OBK_STATUS_HEATER_1\r\n");
01889             OBK_Status_Heater_1_t heaterStatus;
01890             Unpack_OBK_Status_Heater_1_mydbc(&heaterStatus, canMsg.data, 0);
01891 
01892             heaterToUpdate->heaterTemp = heaterStatus.HeaterTemperature;
01893             //sprintf(printbuff, "OBK_STATUS_HEATER_%d,temp %ld,", heater, heaterStatus.HeaterTemperature);
01894             //DebugWrite(printbuff);
01895             if (heaterStatus.isValid)
01896             {
01897                 DebugWrite("Valid,");
01898             }
01899             else
01900             {
01901                 DebugWrite("!Valid,");
01902             }
01903             if (heaterStatus.noHeatModeActive)
01904             {
01905                 DebugWrite("NOHEAT,");
01906                 heaterToUpdate->heatCallDetected = WICED_FALSE;
01907             }
01908             if (heaterStatus.standbyHeatingActive)
01909             {
01910                 DebugWrite("STANBYHEAT,");
01911                 heaterToUpdate->heatCallDetected = WICED_TRUE;
01912             }
01913             if (heaterStatus.standbyHeatingWithSetpointActive)
01914             {
01915                 DebugWrite("STANDBYHEATSETPOINT,");
01916                 heaterToUpdate->heatCallDetected = WICED_TRUE;
01917             }
01918             if (heaterStatus.ResidualHeat > 0)
01919             {
01920                 DebugWrite("RESIDUAL,");
01921             }
01922             if (heaterStatus.ErrorClass1)
01923             {
01924                 DebugWrite("F1,");
01925             }
01926             if (heaterStatus.ErrorClass2)
01927             {
01928                 DebugWrite("F2,");
01929             }
01930             if (heaterStatus.ErrorClass3)
01931             {
01932                 DebugWrite("F3,");
01933             }
01934             if (heaterStatus.ErrorClass4)
01935             {
01936                 DebugWrite("F4,");
01937             }
01938             if (heaterStatus.ErrorClass5)
01939             {
01940                 DebugWrite("F5,");
01941             }
01942             if (heaterStatus.ErrorClass6)
01943             {
01944                 DebugWrite("F6,");
01945             }
01946             if (heaterStatus.HeatingUpActive)
01947             {
01948                 DebugWrite("HUA,");
01949             }
01950             if (heaterStatus.SetpointInvalid)
01951             {
01952                 DebugWrite("SetpointInvalid,");
01953             }
01954             else
01955             {
01956                 DebugWrite("SetpointValid,");
01957             }
01958             if (heaterStatus.AltitudeModeActive)
01959             {
01960                 DebugWrite("!!**ALT**!!,");
01961             }
01962             else
01963             {
01964                 DebugWrite("NoALT,");
01965             }
01966 
01967             DebugWrite("V");
01968             sprintf(printbuff, "%d", heaterStatus.ventilationActive);
01969             DebugWrite(printbuff);
01970             DebugWrite("\r\n");
01971 
01972         }
01973         incoming = can2.read(canMsg);
01974     }
01975     //incoming = CAN_MessagePending(CAN1, CAN_FIFO1);
01976 
01977     //DebugWrite("doneread\r\n");
01978 }
01979 
01980 //#define LISTENONLY
01981 /* primary heat task start */
01982 
01983 wiced_bool_t repeatSent = WICED_FALSE;
01984 
01985 void doHeatTaskCAN(struct sHeatVars *s)
01986 {
01987     if (!(s->bustype == HEATERTYPECAN))
01988     {
01989         return;
01990     }
01991 
01992     char buff[256];
01993 
01994 #ifdef LISTENONLY
01995 //  sprintf(buff,"heattask %d\r\n", s->tasksequence);
01996 //  DebugWrite(buff);
01997 #endif
01998   sprintf(buff,"heattask %d\r\n", s->tasksequence);
01999   DebugWrite(buff);
02000     //DebugWrite("Listen Only\r\n");
02001 
02002     readCAN(s);
02003     if ((otherControllerDetected > 0))
02004     {
02005         s->tasksequence = 0;
02006         s->heatOn = HEATCALLOFF;
02007         
02008         return; // don't send anything.
02009     }
02010 #ifdef LISTENONLY
02011     return;
02012 #endif
02013     //return; // listen only.
02014     idletimer = 60; // disable idle
02015     if ((s->heatOn != HEATCALLOFF))
02016     {
02017         idletimer = 60;
02018     }
02019     if ((idletimer <= 0) && (s->heatOn == HEATCALLOFF))
02020     {
02021         s->tasksequence = -1;
02022         DebugWrite("*idle*\r\n");
02023         return;
02024     }
02025     if (s->initTimer > 0)
02026     {
02027         sprintf(printbuff,"InitTimer %d\r\n", s->initTimer);
02028         DebugWrite(printbuff);
02029         s->tasksequence = 0;
02030     }
02031     else if (s->primeFuelPump == WICED_TRUE)
02032     {
02033         s->tasksequence = 2;
02034     }
02035     else if (s->reset_fault_codes == WICED_TRUE)
02036     {
02037         s->tasksequence = 2;
02038     }
02039     switch (s->tasksequence++)
02040     {
02041         case 4:
02042             //60F: 0F 11 C9 22 00 20 60 00
02043             if ((s->heaterDetected > 0) && s->heaternum == 1) // only send if heater is detected.
02044             {
02045                 if (!repeatSent)
02046                 {
02047                     repeatSent = WICED_TRUE;
02048                     sendRepeatMode(s);
02049                     break;
02050                 }
02051             }
02052             //no break
02053         case 0:
02054         case 8:
02055         case 12:
02056             printf("SendWake\r\n");
02057             sendWakeCommand(s);
02058 
02059             break;
02060         case 1:
02061         case 5:
02062         case 9:
02063         case 13:
02064             sendGetBattery(s, buff);
02065             sendAltitudeMode(s);
02066             if ((s->heatOn == HEATCALLINIT) || (s->heatOn == HEATCALLON))
02067             {
02068 
02069                 // a cyclic heat call is always required.
02070                 if (s->setpoint > 0)
02071                 {
02072                     if (s->heaterSetpointChange != s->setpoint)
02073                     {
02074                         s->setpoint = s->heaterSetpointChange;
02075                     }
02076                     sendHeatOnCommandSetpoint(s);
02077                 }
02078                 else
02079                 {
02080                     sendHeatOnCommand(s);
02081                 }
02082 
02083                 if (s->heatOn == HEATCALLINIT)
02084                 {
02085                     s->heatOn = HEATCALLON;
02086                 }
02087             }
02088             else if (s->heatOn == HEATCALLOFF)
02089             {
02090                 sendHeatOffCommand(s);
02091                 // double-if just for clarity
02092                 if ((s->OBAltitude == WICED_FALSE) && (s->heatCallDetected))
02093                 {
02094                     if ((s->altitudeMode == WICED_TRUE) || (s->internalAltitude > 0))
02095                     {
02096                         // send ONLY if heater is in "ON" state.
02097                         char mysteryCommand[8] =
02098                         { 0x0F, 0x00, 0xC9, 0x22, 0x00, 0x00, 0x00, 0x00 };
02099                         sendCANCommand(0x060D, mysteryCommand, 8);
02100                     }
02101 
02102                 }
02103             }
02104             break;
02105         case 2:
02106         case 6:
02107         case 10:
02108         case 14:
02109             if ((s->heatOn == HEATCALLOFF) && (s->primeFuelPump == WICED_TRUE))
02110             {
02111                 DebugWrite("IN prime call\r\n");
02112                 s->primeFuelPump = WICED_FALSE; // no prime allowed if heat on
02113                 doPrimeSequence(s);
02114             }
02115             else if (s->primeFuelPump == WICED_TRUE)
02116             {
02117                 DebugWrite("IN prime call FORCED FALSE\r\n");
02118                 s->primeFuelPump = WICED_FALSE; // no prime allowed if heat on
02119             }
02120             if (s->reset_fault_codes == WICED_TRUE)
02121             {
02122 //              doPrimeSequence(s);
02123 //              s->reset_fault_codes = WICED_FALSE;
02124 
02125                 printf("RESET faults\r\n");
02126                 s->reset_fault_codes = WICED_FALSE;
02127                 doResetSequence(s);
02128                 // reset fault codes
02129                 printf("****sendGetFaults***\r\n");
02130                 sendGetFault(s, buff);
02131                 printf("***doneGetFaults***\r\n");
02132             }
02133             else
02134             {
02135                 printf("****sendGetFaults***\r\n");
02136                 sendGetFault(s, buff);
02137                 if ((s->errorHistory[0] == 0) || (s->errorHistory[0] == 255))
02138                 {
02139                     s->reset_fault_codes = WICED_FALSE;
02140                 }
02141                 printf("***doneGetFaults***\r\n");
02142             }
02143             // check faults
02144             break;
02145         case 3:
02146             sendGetTemperatures(s, buff);
02147             break;
02148         case 7:
02149             sendGetRuntime(s, buff);
02150             break;
02151         case 11:
02152             sendGetBattery(s, buff);
02153             break;
02154             //case 4:
02155         case 15:
02156             sendGetAltitude(s, buff);
02157             break;
02158         default:
02159             s->tasksequence = 0;
02160             break;
02161     }
02162     printf("/done\r\n");
02163     // start with "Wake" message
02164 
02165     return;
02166 }
02167 
02168 
02169 
02170 // imported from picus
02171 
02172 void doHeatLogicTask(struct sHeatVars* s)
02173 {
02174 // error flag valid after LINPulse 0.
02175     if (s->errorChangeFlag == 1)
02176     {
02177         s->errorChangeFlag = 0;
02178         //printf("Error Change %d \r\n",currentError);
02179 
02180         //printf("History %d,%d,%d,%d,%d\r\n",errorHistory[0],errorHistory[1],errorHistory[2],errorHistory[3],errorHistory[4]);
02181 
02182         // reset timer
02183         resetTimer(s);
02184         s->reportflag = 1;
02185         //UARTWrite(1,"Timer reset\r\n");
02186     }
02187     //sprintf(printbuff, "tickcount: %d, heaton: %d, heattime: %d\n", s->tickcount, s->heatOn, s->heattime);
02188     //DebugWrite(printbuff);
02189 // if the error is stable for 15 seconds, report.
02190     if (s->reportflag == 1 && s->tickcount > 15000 && s->heatOn > 0 && (s->heatcontrolstate != IDLE) && s->resettick == 0)
02191     {
02192         // stable for 15 seconds, do report
02193         if (s->currentError == 0 && s->heatOn > 0)
02194         {
02195             s->reportflag = 0;
02196         }
02197         else if (s->currentError != 0xFF)
02198         {
02199             //printf("Error (heatOn & currentError !=0xFF) \r\n");
02200             s->reportflag = 0;
02201             s->heatOn = HEATCALLOFF;
02202             // disabled retry function per neil at this point.
02203         }
02204         else
02205         {
02206             //printf( "Error FF: No communication.  Allow heat to continue, but report\r\n");
02207             // -OR-
02208             // Retry algorighm on LIN pulse
02209             s->reportflag = 0;
02210         }
02211     }
02212     else
02213     {
02214         //sprintf(printbuff,"%d\r\n",tickcount);
02215         //UARTWrite(1,printbuff);
02216     }
02217     if (s->heatOn == HEATCALLON && (s->heattime == 0 || s->heattime > 86400))
02218     {
02219         //printf("Heat off due to time expiry.");
02220         // no final report.
02221 
02222         if (s->heattime > 0)
02223         {
02224             s->heatOn = HEATCALLLONGRUN;
02225             s->heatresettime = RESETHEATTIME
02226             ; // reset heat timer
02227         }
02228         else
02229         {
02230             s->heatOn = HEATCALLOFF;
02231         }
02232 
02233         s->reportflag = 0;
02234     }
02235 }
02236 
02237 //=========================================================
02238 unsigned char fromHexAscii(char ascii)
02239 {
02240     if (ascii >= '0' && ascii <= '9')
02241     {
02242         return ascii - '0';
02243     }
02244     else if (ascii >= 'A' && ascii <= 'F')
02245     {
02246         return ascii - 'A' + 10;
02247     }
02248     else
02249     {
02250         return 255;
02251     }
02252 }
02253 
02254