Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Revision:
5:1775b4b13232
Parent:
4:682d96ff6d79
--- a/gmlan.cpp	Wed Sep 11 11:55:51 2013 +0000
+++ b/gmlan.cpp	Sat Apr 25 17:07:08 2015 +0000
@@ -1,5 +1,8 @@
 #include "gmlan.h"
 
+Timer   GMLANtimer;
+
+
 void GMLANTesterPresentAll()
 {
     char GMLANMsg[] = GMLANTesterPresentFunctional;
@@ -7,58 +10,61 @@
     ACTIVITYLEDON;
 }
 
-void GMLANTesterPresentT8()
+void GMLANTesterPresent(uint32_t ReqID, uint32_t RespID)
 {
     char GMLANMsg[] = GMLANTesterPresentPhysical;
-    can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT);
-    can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT);
+    can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT);
+    can_wait_timeout(RespID, GMLANMsg, 2, GMLANPTCT);
     ACTIVITYLEDON;
 }
 
 // All steps needed in preparation for using a bootloader ('Utility File' in GMLAN parlance)
-bool GMLANprogrammingSetupProcess()
+bool GMLANprogrammingSetupProcess(uint32_t ReqID, uint32_t RespID)
 {
+    GMLANTesterPresent(ReqID, RespID);
     printf("Starting Diagnostic session\r\n");
-    if (!GMLANinitiateDiagnostic(GMLANdisableAllDTCs)) {
+    if (!GMLANinitiateDiagnostic(ReqID, RespID, GMLANdisableAllDTCs)) {
         printf("Unable to start Diagnostic session\r\n");
         return FALSE;
     }
     printf("Disabling Normal Communincation Messages\r\n");
-    if (!GMLANdisableNormalCommunication()) {
+    if (!GMLANdisableNormalCommunication(ReqID, RespID)) {
         printf("Unable to tell T8 to disable normal communication messages\r\n");
         return FALSE;
     }
     printf("Report Programmed State\r\n");
-    if (!GMLANReportProgrammedState()) {
+    if (!GMLANReportProgrammedState(ReqID, RespID)) {
         printf("Unable to determine ECU programmed state\r\n");
-        return FALSE;
     }
     printf("Requesting program mode\r\n");
-    if (!GMLANProgrammingMode(GMLANRequestProgrammingNormal)) {
+    if (!GMLANProgrammingMode(ReqID, RespID, GMLANRequestProgrammingNormal)) {
         printf("Unable to request programming mode\r\n");
         return FALSE;
     }
     printf("Starting program session\r\n");
-    if (!GMLANProgrammingMode(GMLANEnableProgrammingMode)) {
+    if (!GMLANProgrammingMode(ReqID, RespID, GMLANEnableProgrammingMode)) {
         printf("Unable to start program session\r\n");
         return FALSE;
     }
+    wait_ms(500);   // was 5
     return TRUE;
 }
 
 
 // All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance)
-bool GMLANprogrammingUtilityFileProcess(char UtilityFile[])
+bool GMLANprogrammingUtilityFileProcess(uint32_t ReqID, uint32_t RespID, const uint8_t UtilityFile[])
 {
     uint16_t i = 0, j = 0, k = 0;
     uint32_t StartAddress = 0x102400;
     uint16_t txpnt = 0;
     char iFrameNumber = 0x21;
     char GMLANMsg[8];
-    //char BootLoader[] = T8Bootloader;
 //
+    GMLANTesterPresent(ReqID, RespID);
+    GMLANtimer.start();
     printf("Waiting for Permission to send bootloader\r\n");
-    if (!GMLANRequestDownload(GMLANRequestDownloadModeNormal)) {
+    wait_ms(500);
+    if (!GMLANRequestDownload(ReqID, RespID, GMLANRequestDownloadModeNormal)) {
         printf("Unable to request Bootloader Upload\r\n");
         return FALSE;
     }
@@ -66,7 +72,7 @@
     printf("  0.00 %% complete.\r");
 //
     for (i=0; i<0x46; i++) {
-        if (!GMLANDataTransferFirstFrame(0xF0, GMLANDOWNLOAD, StartAddress)) {
+        if (!GMLANDataTransferFirstFrame(ReqID, RespID, 0xF0, GMLANDOWNLOAD, StartAddress)) {
             printf("Unable to start Bootloader Upload\r\n");
             return FALSE;
         }
@@ -75,48 +81,24 @@
             GMLANMsg[0] = iFrameNumber;
             for (k=1; k<8; k++)
                 GMLANMsg[k] = UtilityFile[txpnt++];
-#ifdef DEBUG
-            for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-            printf("\r\n");
-#endif
-            if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) {
+            if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) {
                 printf("Unable to send Bootloader\r\n");
                 return FALSE;
             }
             ++iFrameNumber &= 0x2F;
-            wait_ms(1);
-//            wait_us(500);
-        }
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) {
-            printf("I didn't receive a block acknowledge message\r\n");
-            return FALSE;
-        }
-        while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) {
-            printf("I'm waiting for a BootLoader Block to upload\r\n");
-            if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) {
-                printf("I didn't receive a block acknowledge message after enhanced timeout\r\n");
-                return FALSE;
-            }
+            wait_ms(2);     // was 2
         }
-#ifdef DEBUG
-        for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-        printf("\r\n");
-#endif
-        if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) {
-            GMLANShowReturnCode(GMLANMsg[3]);
+        if (!GMLANDataTransferBlockAcknowledge(RespID))
             return FALSE;
+        if (GMLANtimer.read_ms() > 2000) {
+            GMLANTesterPresent(ReqID, RespID);
+            GMLANtimer.reset();
         }
-        if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) {
-            printf("EXITING due to an unexpected CAN message\r\n");
-            return FALSE;
-        }
-        GMLANTesterPresentT8();
-        ACTIVITYLEDON;
         StartAddress += 0xea;
         printf("%6.2f\r", 100*(float)txpnt/(float)(16384+(70*4)) );
     }
     wait_ms(1);
-    if (!GMLANDataTransferFirstFrame(0x0A, GMLANDOWNLOAD, StartAddress)) {
+    if (!GMLANDataTransferFirstFrame(ReqID, RespID, 0x0A, GMLANDOWNLOAD, StartAddress)) {
         printf("Unable to finish Bootloader Upload\r\n");
         return FALSE;
     }
@@ -125,195 +107,147 @@
     for (k=0; k<7; k++) {
         GMLANMsg[k+1] = UtilityFile[txpnt++];
     }
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) {
+    if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) {
         printf("Unable to finish sending Bootloader\r\n");
         return FALSE;
     }
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
-#ifdef DEBUG
-    for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
     printf("%6.2f\r\n", (float)100 );
     printf("Starting the bootloader\r\n");
-    if (!GMLANDataTransfer(0x06, GMLANEXECUTE, 0x00102460)) {
+    if (!GMLANDataTransfer(ReqID, RespID, 0x06, GMLANEXECUTE, 0x00102460)) {
         printf("Unable to start the Bootloader\r\n");
         return FALSE;
     }
-    wait_ms(500);
+    wait_ms(500);   // was 100
     return TRUE;
 }
 
-bool GMLANinitiateDiagnostic(char level)
+bool GMLANinitiateDiagnostic(uint32_t ReqID, uint32_t RespID, char level)
 {
     char GMLANMsg[] = GMLANinitiateDiagnosticOperation;
     GMLANMsg[2] = level;
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 3, GMLANPTCT))
+    if (!can_send_timeout(ReqID, GMLANMsg, 3, GMLANPTCT))
         return FALSE;
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
+    if (ReqID == T8USDTREQID) return TRUE;
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
     while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x10 && GMLANMsg[3] == 0x78)
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED))
+        if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED))
             return FALSE;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
     if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x10 )
         GMLANShowReturnCode(GMLANMsg[3]);
     return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x50) ? TRUE : FALSE;
 }
 
 
-bool GMLANdisableNormalCommunication()
+bool GMLANdisableNormalCommunication(uint32_t ReqID, uint32_t RespID)
 {
     char GMLANMsg[] = GMLANdisableCommunication;
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 2, GMLANPTCT))
-        return FALSE;
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
+    if (!can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT))
         return FALSE;
-    while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78)
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED))
+    if (ReqID == T8USDTREQID) return TRUE;
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
+        return FALSE;
+    while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x28 && GMLANMsg[3] == 0x78)
+        if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED))
             return FALSE;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
     if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x28 )
         GMLANShowReturnCode(GMLANMsg[3]);
     return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x68) ? TRUE : FALSE;
 }
 
 
-bool GMLANReportProgrammedState()
+bool GMLANReportProgrammedState(uint32_t ReqID, uint32_t RespID)
 {
     char GMLANMsg[] = GMLANReportProgrammed;
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 2, GMLANPTCT))
+    if (!can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT))
         return FALSE;
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
-    while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78)
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED))
+    while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA2 && GMLANMsg[3] == 0x78)
+        if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED))
             return FALSE;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
     if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA2 )
         GMLANShowReturnCode(GMLANMsg[3]);
     return (GMLANMsg[0] == 0x02 && GMLANMsg[1] == 0xE2) ? TRUE : FALSE;
 }
 
 
-bool GMLANProgrammingMode(char mode)
+bool GMLANProgrammingMode(uint32_t ReqID, uint32_t RespID, char mode)
 {
     char GMLANMsg[] = GMLANProgramming;
     GMLANMsg[2] = mode;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 3, GMLANPTCT))
+    if (!can_send_timeout(ReqID, GMLANMsg, 3, GMLANPTCT))
         return FALSE;
     if (mode == GMLANEnableProgrammingMode)
         return TRUE;                            // No response expected when enabling program mode
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
-    while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78)
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED))
+    while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA5 && GMLANMsg[3] == 0x78)
+        if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED))
             return FALSE;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
     if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA5 )
         GMLANShowReturnCode(GMLANMsg[3]);
     return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0xE5) ? TRUE : FALSE;
 }
 
-bool GMLANSecurityAccessRequest(char level, uint16_t& seed)
+bool GMLANSecurityAccessRequest(uint32_t ReqID, uint32_t RespID, char level, uint16_t& seed)
 {
     char GMLANMsg[] = GMLANSecurityAccessSeed;
     GMLANMsg[2] = level;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 3, GMLANPTCT))
+    if (!can_send_timeout(ReqID, GMLANMsg, 3, GMLANPTCT))
         return FALSE;
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
-    while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78)
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED))
+    while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 && GMLANMsg[3] == 0x78)
+        if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED))
             return FALSE;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
     seed = GMLANMsg[3] << 8 | GMLANMsg[4];
     if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 )
         GMLANShowReturnCode(GMLANMsg[3]);
     return (GMLANMsg[0] == 0x04 && GMLANMsg[1] == 0x67 && GMLANMsg[2] == level) ? TRUE : FALSE;
 }
 
-bool GMLANSecurityAccessSendKey(char level, uint16_t key)
+bool GMLANSecurityAccessSendKey(uint32_t ReqID, uint32_t RespID, char level, uint16_t key)
 {
     char GMLANMsg[] = GMLANSecurityAccessKey;
     GMLANMsg[2] = level+1;
     GMLANMsg[3] = (key >> 8) & 0xFF;
     GMLANMsg[4] = key & 0xFF;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 5, GMLANPTCT))
+    if (!can_send_timeout(ReqID, GMLANMsg, 5, GMLANPTCT))
         return FALSE;
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
-    while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78)
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED))
+    while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 && GMLANMsg[3] == 0x78)
+        if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED))
             return FALSE;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
     if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 )
         GMLANShowReturnCode(GMLANMsg[3]);
     return (GMLANMsg[0] == 0x02 && GMLANMsg[1] == 0x67 && GMLANMsg[2] == level+1) ? TRUE : FALSE;
 }
 
-bool GMLANRequestDownload(char dataFormatIdentifier)
+bool GMLANRequestDownload(uint32_t ReqID, uint32_t RespID, char dataFormatIdentifier)
 {
     char GMLANMsg[] = GMLANRequestDownloadMessage;
     GMLANMsg[2] = dataFormatIdentifier;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 7, GMLANPTCT))
+    if (!can_send_timeout(ReqID, GMLANMsg, 7, GMLANPTCT))
+        return FALSE;
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
-        return FALSE;
-//    while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78)
     while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x34 && GMLANMsg[3] == 0x78) {
-        printf("Erasing\r\n");
-        GMLANTesterPresentT8();
-        ACTIVITYLEDON;
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED))
+        printf("Waiting\r\n");
+        GMLANTesterPresent(T8REQID, T8RESPID);
+        if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED))
             return FALSE;
     }
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
     if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x34 )
         GMLANShowReturnCode(GMLANMsg[3]);
     return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x74) ? TRUE : FALSE;
 }
 
 
-bool GMLANDataTransfer(char length, char function, uint32_t address)
+bool GMLANDataTransfer(uint32_t ReqID, uint32_t RespID, char length, char function, uint32_t address)
 {
     char GMLANMsg[8];
     GMLANMsg[0] = length;
@@ -324,28 +258,20 @@
     GMLANMsg[5] = (char) (address >> 8);
     GMLANMsg[6] = (char) (address);
     GMLANMsg[7] = 0xaa;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT))
+    if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
-    while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78)
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED))
+    while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78)
+        if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED))
             return FALSE;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
     if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 )
         GMLANShowReturnCode(GMLANMsg[3]);
     return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x76) ? TRUE : FALSE;
 }
 
 
-bool GMLANDataTransferFirstFrame(char length, char function, uint32_t address)
+bool GMLANDataTransferFirstFrame(uint32_t ReqID, uint32_t RespID, char length, char function, uint32_t address)
 {
     char GMLANMsg[8];
     GMLANMsg[0] = 0x10;
@@ -356,55 +282,66 @@
     GMLANMsg[5] = (char) (address >> 16);
     GMLANMsg[6] = (char) (address >> 8);
     GMLANMsg[7] = (char) (address);
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT))
+    if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
         return FALSE;
-    while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78)
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED))
+    while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78)
+        if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED))
             return FALSE;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
     if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 )
         GMLANShowReturnCode(GMLANMsg[3]);
     return (GMLANMsg[0] == 0x30 && GMLANMsg[1] == 0x00 && GMLANMsg[2] == 0x00) ? TRUE : FALSE;
 }
 
 
-bool GMLANDataTransferConsecutiveFrame(char framenumber, char data[7])
+bool GMLANDataTransferConsecutiveFrame(uint32_t ReqID, char framenumber, char data[8])
 {
     char GMLANMsg[8];
     GMLANMsg[0] = framenumber;
     for (char k = 0; k < 7; k++ )
         GMLANMsg[k+1] = data[k];
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
-    return (can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) ? TRUE : FALSE;
+    return (can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) ? TRUE : FALSE;
 }
 
-bool GMLANReturnToNormalMode()
+bool GMLANDataTransferBlockAcknowledge(uint32_t RespID)
 {
-    char GMLANMsg[] = GMLANRetrunToNormalModeMessage;
-    if (!can_send_timeout(T8RequestId, GMLANMsg, 2, GMLANPTCT))
-        return FALSE;
-    if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT))
+    char GMLANMsg[8];
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) {
+        printf("\r\nI did not receive a block acknowledge message\r\n");
         return FALSE;
-    while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78)
-        if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED))
+    }
+    if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) {
+        while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) {
+            printf("\r\nI'm waiting for a block acknowledge message\r\n");
+            if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) {
+                printf("I did not receive a block acknowledge message after enhanced timeout\r\n");
+                return FALSE;
+            }
+        }
+        if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) {
+            GMLANShowReturnCode(GMLANMsg[3]);
+            return FALSE;
+        }
+        if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) {
+            printf("\r\nEXITING due to an unexpected CAN message\r\n");
             return FALSE;
-#ifdef DEBUG
-    for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
-    printf("\r\n");
-#endif
-    if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x28 )
+        }
+    }
+    return TRUE;
+}
+
+bool GMLANReturnToNormalMode(uint32_t ReqID, uint32_t RespID)
+{
+    char GMLANMsg[] = GMLANReturnToNormalModeMessage;
+    if (!can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT))
+        return FALSE;
+    if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT))
+        return FALSE;
+    while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x20 && GMLANMsg[3] == 0x78)
+        if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED))
+            return FALSE;
+    if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x20 )
         GMLANShowReturnCode(GMLANMsg[3]);
     return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x60) ? TRUE : FALSE;
 }