Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
gmlan.cpp
00001 #include "gmlan.h" 00002 00003 Timer GMLANtimer; 00004 00005 00006 void GMLANTesterPresentAll() 00007 { 00008 char GMLANMsg[] = GMLANTesterPresentFunctional; 00009 can_send_timeout(GMLANALLNODES, GMLANMsg, 3, GMLANPTCT); 00010 ACTIVITYLEDON; 00011 } 00012 00013 void GMLANTesterPresent(uint32_t ReqID, uint32_t RespID) 00014 { 00015 char GMLANMsg[] = GMLANTesterPresentPhysical; 00016 can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT); 00017 can_wait_timeout(RespID, GMLANMsg, 2, GMLANPTCT); 00018 ACTIVITYLEDON; 00019 } 00020 00021 // All steps needed in preparation for using a bootloader ('Utility File' in GMLAN parlance) 00022 bool GMLANprogrammingSetupProcess(uint32_t ReqID, uint32_t RespID) 00023 { 00024 GMLANTesterPresent(ReqID, RespID); 00025 printf("Starting Diagnostic session\r\n"); 00026 if (!GMLANinitiateDiagnostic(ReqID, RespID, GMLANdisableAllDTCs)) { 00027 printf("Unable to start Diagnostic session\r\n"); 00028 return FALSE; 00029 } 00030 printf("Disabling Normal Communincation Messages\r\n"); 00031 if (!GMLANdisableNormalCommunication(ReqID, RespID)) { 00032 printf("Unable to tell T8 to disable normal communication messages\r\n"); 00033 return FALSE; 00034 } 00035 printf("Report Programmed State\r\n"); 00036 if (!GMLANReportProgrammedState(ReqID, RespID)) { 00037 printf("Unable to determine ECU programmed state\r\n"); 00038 } 00039 printf("Requesting program mode\r\n"); 00040 if (!GMLANProgrammingMode(ReqID, RespID, GMLANRequestProgrammingNormal)) { 00041 printf("Unable to request programming mode\r\n"); 00042 return FALSE; 00043 } 00044 printf("Starting program session\r\n"); 00045 if (!GMLANProgrammingMode(ReqID, RespID, GMLANEnableProgrammingMode)) { 00046 printf("Unable to start program session\r\n"); 00047 return FALSE; 00048 } 00049 wait_ms(500); // was 5 00050 return TRUE; 00051 } 00052 00053 00054 // All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance) 00055 bool GMLANprogrammingUtilityFileProcess(uint32_t ReqID, uint32_t RespID, const uint8_t UtilityFile[]) 00056 { 00057 uint16_t i = 0, j = 0, k = 0; 00058 uint32_t StartAddress = 0x102400; 00059 uint16_t txpnt = 0; 00060 char iFrameNumber = 0x21; 00061 char GMLANMsg[8]; 00062 // 00063 GMLANTesterPresent(ReqID, RespID); 00064 GMLANtimer.start(); 00065 printf("Waiting for Permission to send bootloader\r\n"); 00066 wait_ms(500); 00067 if (!GMLANRequestDownload(ReqID, RespID, GMLANRequestDownloadModeNormal)) { 00068 printf("Unable to request Bootloader Upload\r\n"); 00069 return FALSE; 00070 } 00071 printf("Sending Bootloader\r\n"); 00072 printf(" 0.00 %% complete.\r"); 00073 // 00074 for (i=0; i<0x46; i++) { 00075 if (!GMLANDataTransferFirstFrame(ReqID, RespID, 0xF0, GMLANDOWNLOAD, StartAddress)) { 00076 printf("Unable to start Bootloader Upload\r\n"); 00077 return FALSE; 00078 } 00079 iFrameNumber = 0x21; 00080 for (j=0; j < 0x22; j++) { 00081 GMLANMsg[0] = iFrameNumber; 00082 for (k=1; k<8; k++) 00083 GMLANMsg[k] = UtilityFile[txpnt++]; 00084 if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) { 00085 printf("Unable to send Bootloader\r\n"); 00086 return FALSE; 00087 } 00088 ++iFrameNumber &= 0x2F; 00089 wait_ms(2); // was 2 00090 } 00091 if (!GMLANDataTransferBlockAcknowledge(RespID)) 00092 return FALSE; 00093 if (GMLANtimer.read_ms() > 2000) { 00094 GMLANTesterPresent(ReqID, RespID); 00095 GMLANtimer.reset(); 00096 } 00097 StartAddress += 0xea; 00098 printf("%6.2f\r", 100*(float)txpnt/(float)(16384+(70*4)) ); 00099 } 00100 wait_ms(1); 00101 if (!GMLANDataTransferFirstFrame(ReqID, RespID, 0x0A, GMLANDOWNLOAD, StartAddress)) { 00102 printf("Unable to finish Bootloader Upload\r\n"); 00103 return FALSE; 00104 } 00105 iFrameNumber = 0x21; 00106 GMLANMsg[0] = iFrameNumber; 00107 for (k=0; k<7; k++) { 00108 GMLANMsg[k+1] = UtilityFile[txpnt++]; 00109 } 00110 if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) { 00111 printf("Unable to finish sending Bootloader\r\n"); 00112 return FALSE; 00113 } 00114 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00115 return FALSE; 00116 printf("%6.2f\r\n", (float)100 ); 00117 printf("Starting the bootloader\r\n"); 00118 if (!GMLANDataTransfer(ReqID, RespID, 0x06, GMLANEXECUTE, 0x00102460)) { 00119 printf("Unable to start the Bootloader\r\n"); 00120 return FALSE; 00121 } 00122 wait_ms(500); // was 100 00123 return TRUE; 00124 } 00125 00126 bool GMLANinitiateDiagnostic(uint32_t ReqID, uint32_t RespID, char level) 00127 { 00128 char GMLANMsg[] = GMLANinitiateDiagnosticOperation; 00129 GMLANMsg[2] = level; 00130 if (!can_send_timeout(ReqID, GMLANMsg, 3, GMLANPTCT)) 00131 return FALSE; 00132 if (ReqID == T8USDTREQID) return TRUE; 00133 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00134 return FALSE; 00135 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x10 && GMLANMsg[3] == 0x78) 00136 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) 00137 return FALSE; 00138 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x10 ) 00139 GMLANShowReturnCode(GMLANMsg[3]); 00140 return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x50) ? TRUE : FALSE; 00141 } 00142 00143 00144 bool GMLANdisableNormalCommunication(uint32_t ReqID, uint32_t RespID) 00145 { 00146 char GMLANMsg[] = GMLANdisableCommunication; 00147 if (!can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT)) 00148 return FALSE; 00149 if (ReqID == T8USDTREQID) return TRUE; 00150 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00151 return FALSE; 00152 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x28 && GMLANMsg[3] == 0x78) 00153 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) 00154 return FALSE; 00155 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x28 ) 00156 GMLANShowReturnCode(GMLANMsg[3]); 00157 return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x68) ? TRUE : FALSE; 00158 } 00159 00160 00161 bool GMLANReportProgrammedState(uint32_t ReqID, uint32_t RespID) 00162 { 00163 char GMLANMsg[] = GMLANReportProgrammed; 00164 if (!can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT)) 00165 return FALSE; 00166 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00167 return FALSE; 00168 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA2 && GMLANMsg[3] == 0x78) 00169 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) 00170 return FALSE; 00171 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA2 ) 00172 GMLANShowReturnCode(GMLANMsg[3]); 00173 return (GMLANMsg[0] == 0x02 && GMLANMsg[1] == 0xE2) ? TRUE : FALSE; 00174 } 00175 00176 00177 bool GMLANProgrammingMode(uint32_t ReqID, uint32_t RespID, char mode) 00178 { 00179 char GMLANMsg[] = GMLANProgramming; 00180 GMLANMsg[2] = mode; 00181 if (!can_send_timeout(ReqID, GMLANMsg, 3, GMLANPTCT)) 00182 return FALSE; 00183 if (mode == GMLANEnableProgrammingMode) 00184 return TRUE; // No response expected when enabling program mode 00185 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00186 return FALSE; 00187 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA5 && GMLANMsg[3] == 0x78) 00188 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) 00189 return FALSE; 00190 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA5 ) 00191 GMLANShowReturnCode(GMLANMsg[3]); 00192 return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0xE5) ? TRUE : FALSE; 00193 } 00194 00195 bool GMLANSecurityAccessRequest(uint32_t ReqID, uint32_t RespID, char level, uint16_t& seed) 00196 { 00197 char GMLANMsg[] = GMLANSecurityAccessSeed; 00198 GMLANMsg[2] = level; 00199 if (!can_send_timeout(ReqID, GMLANMsg, 3, GMLANPTCT)) 00200 return FALSE; 00201 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00202 return FALSE; 00203 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 && GMLANMsg[3] == 0x78) 00204 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) 00205 return FALSE; 00206 seed = GMLANMsg[3] << 8 | GMLANMsg[4]; 00207 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 ) 00208 GMLANShowReturnCode(GMLANMsg[3]); 00209 return (GMLANMsg[0] == 0x04 && GMLANMsg[1] == 0x67 && GMLANMsg[2] == level) ? TRUE : FALSE; 00210 } 00211 00212 bool GMLANSecurityAccessSendKey(uint32_t ReqID, uint32_t RespID, char level, uint16_t key) 00213 { 00214 char GMLANMsg[] = GMLANSecurityAccessKey; 00215 GMLANMsg[2] = level+1; 00216 GMLANMsg[3] = (key >> 8) & 0xFF; 00217 GMLANMsg[4] = key & 0xFF; 00218 if (!can_send_timeout(ReqID, GMLANMsg, 5, GMLANPTCT)) 00219 return FALSE; 00220 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00221 return FALSE; 00222 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 && GMLANMsg[3] == 0x78) 00223 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) 00224 return FALSE; 00225 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 ) 00226 GMLANShowReturnCode(GMLANMsg[3]); 00227 return (GMLANMsg[0] == 0x02 && GMLANMsg[1] == 0x67 && GMLANMsg[2] == level+1) ? TRUE : FALSE; 00228 } 00229 00230 bool GMLANRequestDownload(uint32_t ReqID, uint32_t RespID, char dataFormatIdentifier) 00231 { 00232 char GMLANMsg[] = GMLANRequestDownloadMessage; 00233 GMLANMsg[2] = dataFormatIdentifier; 00234 if (!can_send_timeout(ReqID, GMLANMsg, 7, GMLANPTCT)) 00235 return FALSE; 00236 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00237 return FALSE; 00238 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x34 && GMLANMsg[3] == 0x78) { 00239 printf("Waiting\r\n"); 00240 GMLANTesterPresent(T8REQID, T8RESPID); 00241 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) 00242 return FALSE; 00243 } 00244 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x34 ) 00245 GMLANShowReturnCode(GMLANMsg[3]); 00246 return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x74) ? TRUE : FALSE; 00247 } 00248 00249 00250 bool GMLANDataTransfer(uint32_t ReqID, uint32_t RespID, char length, char function, uint32_t address) 00251 { 00252 char GMLANMsg[8]; 00253 GMLANMsg[0] = length; 00254 GMLANMsg[1] = 0x36; 00255 GMLANMsg[2] = function; 00256 GMLANMsg[3] = (char) (address >> 24); 00257 GMLANMsg[4] = (char) (address >> 16); 00258 GMLANMsg[5] = (char) (address >> 8); 00259 GMLANMsg[6] = (char) (address); 00260 GMLANMsg[7] = 0xaa; 00261 if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) 00262 return FALSE; 00263 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00264 return FALSE; 00265 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) 00266 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) 00267 return FALSE; 00268 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) 00269 GMLANShowReturnCode(GMLANMsg[3]); 00270 return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x76) ? TRUE : FALSE; 00271 } 00272 00273 00274 bool GMLANDataTransferFirstFrame(uint32_t ReqID, uint32_t RespID, char length, char function, uint32_t address) 00275 { 00276 char GMLANMsg[8]; 00277 GMLANMsg[0] = 0x10; 00278 GMLANMsg[1] = length; 00279 GMLANMsg[2] = 0x36; 00280 GMLANMsg[3] = function; 00281 GMLANMsg[4] = (char) (address >> 24); 00282 GMLANMsg[5] = (char) (address >> 16); 00283 GMLANMsg[6] = (char) (address >> 8); 00284 GMLANMsg[7] = (char) (address); 00285 if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) 00286 return FALSE; 00287 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00288 return FALSE; 00289 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) 00290 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) 00291 return FALSE; 00292 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) 00293 GMLANShowReturnCode(GMLANMsg[3]); 00294 return (GMLANMsg[0] == 0x30 && GMLANMsg[1] == 0x00 && GMLANMsg[2] == 0x00) ? TRUE : FALSE; 00295 } 00296 00297 00298 bool GMLANDataTransferConsecutiveFrame(uint32_t ReqID, char framenumber, char data[8]) 00299 { 00300 char GMLANMsg[8]; 00301 GMLANMsg[0] = framenumber; 00302 for (char k = 0; k < 7; k++ ) 00303 GMLANMsg[k+1] = data[k]; 00304 return (can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) ? TRUE : FALSE; 00305 } 00306 00307 bool GMLANDataTransferBlockAcknowledge(uint32_t RespID) 00308 { 00309 char GMLANMsg[8]; 00310 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) { 00311 printf("\r\nI did not receive a block acknowledge message\r\n"); 00312 return FALSE; 00313 } 00314 if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) { 00315 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) { 00316 printf("\r\nI'm waiting for a block acknowledge message\r\n"); 00317 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) { 00318 printf("I did not receive a block acknowledge message after enhanced timeout\r\n"); 00319 return FALSE; 00320 } 00321 } 00322 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) { 00323 GMLANShowReturnCode(GMLANMsg[3]); 00324 return FALSE; 00325 } 00326 if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) { 00327 printf("\r\nEXITING due to an unexpected CAN message\r\n"); 00328 return FALSE; 00329 } 00330 } 00331 return TRUE; 00332 } 00333 00334 bool GMLANReturnToNormalMode(uint32_t ReqID, uint32_t RespID) 00335 { 00336 char GMLANMsg[] = GMLANReturnToNormalModeMessage; 00337 if (!can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT)) 00338 return FALSE; 00339 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) 00340 return FALSE; 00341 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x20 && GMLANMsg[3] == 0x78) 00342 if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) 00343 return FALSE; 00344 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x20 ) 00345 GMLANShowReturnCode(GMLANMsg[3]); 00346 return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x60) ? TRUE : FALSE; 00347 } 00348 00349 00350 void GMLANShowReturnCode(char returnCode) 00351 { 00352 switch (returnCode) { 00353 case 0x11 : 00354 printf("0x11 - ServiceNotSupported\r\n"); 00355 break; 00356 case 0x12 : 00357 printf("0x12 - SubFunctionNotSupported-InvalidFormat\r\n"); 00358 break; 00359 case 0x22 : 00360 printf("0x22 - ConditionsNotCorrectOrRequestSequenceError\r\n"); 00361 break; 00362 case 0x31 : 00363 printf("0x31 - RequestOutOfRange\r\n"); 00364 break; 00365 case 0x35 : 00366 printf("0x35 - InvalidKey\r\n"); 00367 break; 00368 case 0x36 : 00369 printf("0x36 - ExceededNumberOfAttempts, ECU is now locked!\r\n"); 00370 break; 00371 case 0x37 : 00372 printf("0x37 - RequiredTimeDelayNotExpired\r\n"); 00373 break; 00374 case 0x78 : 00375 printf("0x78 - RequestCorrectlyReceived-ResponsePending\r\n"); 00376 break; 00377 case 0x81 : 00378 printf("0x81 - SchedulerFull\r\n"); 00379 break; 00380 case 0x83 : 00381 printf("0x83 - VoltageOutOfRangeFault\r\n"); 00382 break; 00383 case 0x85 : 00384 printf("0x85 - GeneralProgrammingFailure\r\n"); 00385 break; 00386 case 0x99 : 00387 printf("0x99 - ReadyForDownload-DTCStored\r\n"); 00388 break; 00389 case 0xE3 : 00390 printf("0xE3 - DeviceControlLimitsExceeded\r\n"); 00391 break; 00392 default : 00393 printf("Unknown failure Return Code ?!?\r\n"); 00394 } 00395 }
Generated on Thu Jul 14 2022 04:28:18 by
1.7.2