Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Revision:
6:2fbcbebed28c
Parent:
5:1775b4b13232
--- a/t7utils.cpp	Sat Apr 25 17:07:08 2015 +0000
+++ b/t7utils.cpp	Sat Apr 23 18:31:40 2016 +0000
@@ -29,7 +29,8 @@
 //
 
 
-bool t7_initialise() {
+bool t7_initialise()
+{
     // send a can message to the T7 requesting that it initialises CAN communication with Just4Trionic
     char T7TxMsg[] = T7INITMSG;
     if (!can_send_timeout (T7CMNDID, T7TxMsg, 8, T7MESSAGETIMEOUT))
@@ -56,7 +57,8 @@
 // return:    bool TRUE if there was a message, FALSE if no message.
 //
 
-bool t7_authenticate() {
+bool t7_authenticate()
+{
     uint16_t seed, key;
 //    uint16_t i;
     char T7TxAck[] = T7ACK_MSG;
@@ -130,7 +132,8 @@
 // return:    bool TRUE if there was a message, FALSE if no message.
 //
 
-bool t7_dump() {
+bool t7_dump(bool blockmode)
+{
     uint32_t received;
     uint8_t byte_count, retries, i;
     char T7_dump_jumpa[] = T7DMPJP1A;
@@ -275,10 +278,11 @@
     return TRUE;
 }
 
-bool t7_erase() {
-    char T7_erase_msga[]   = { 0x40, 0xA1, 0x02, 0x31, 0x52, 0x00, 0x00, 0x00 };
-    char T7_erase_msgb[]   = { 0x40, 0xA1, 0x02, 0x31, 0x53, 0x00, 0x00, 0x00 };
-    char T7_erase_confirm[]   = { 0x40, 0xA1, 0x01, 0x3E, 0x00, 0x00, 0x00, 0x00 };
+bool t7_erase()
+{
+    char T7_erase_msga[]    = { 0x40, 0xA1, 0x02, 0x31, 0x52, 0x00, 0x00, 0x00 };
+    char T7_erase_msgb[]    = { 0x40, 0xA1, 0x02, 0x31, 0x53, 0x00, 0x00, 0x00 };
+    char T7_erase_confirm[] = { 0x40, 0xA1, 0x01, 0x3E, 0x00, 0x00, 0x00, 0x00 };
     char T7_erase_ack[]     = { 0x40, 0xA1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00 };
     char data[8];
     int i;
@@ -290,16 +294,16 @@
     while ( data[3] != 0x71 && i < 10) {
         // Send "Request to ERASE" to Trionic
         if (!can_send_timeout (T7SEC_ID, T7_erase_msga, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
+            printf("err %s line: %d\r\n", __FILE__, __LINE__ );
             return FALSE;
         }
         if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
+            printf("err %s line: %d\r\n", __FILE__, __LINE__ );
             return FALSE;
         }
         T7_erase_ack[3] = data[0] & 0xBF;
         if (!can_send_timeout (T7ACK_ID, T7_erase_ack, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
+            printf("err %s line: %d\r\n", __FILE__, __LINE__ );
             return FALSE;
         }
         wait_ms(100);
@@ -317,16 +321,16 @@
     while ( data[3] != 0x71 && i < 200) {
         // Send "Request to ERASE" to Trionic
         if (!can_send_timeout (T7SEC_ID, T7_erase_msgb, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
+            printf("err %s line: %d\r\n", __FILE__, __LINE__ );
             return FALSE;
         }
         if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
+            printf("err %s line: %d\r\n", __FILE__, __LINE__ );
             return FALSE;
         }
         T7_erase_ack[3] = data[0] & 0xBF;
         if (!can_send_timeout (T7ACK_ID, T7_erase_ack, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
+            printf("err %s line: %d\r\n", __FILE__, __LINE__ );
             return FALSE;
         }
         wait_ms(100);
@@ -343,487 +347,341 @@
     // Confirm erase was successful?
     // (Note: no acknowledgements used for some reason)
     if (!can_send_timeout (T7SEC_ID, T7_erase_confirm, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     if ( data[3] != 0x7E ) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     wait_ms(100);
     if (!can_send_timeout (T7SEC_ID, T7_erase_confirm, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     if ( data[3] != 0x7E ) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
+        printf("FAILURE: Unable to erase the FLASH .\r\n");
         return FALSE;
     }
     printf("SUCCESS: The FLASH has been erased.\r\n");
     return TRUE;
 }
 
-bool t7_flash_raw() {
-    char T7_flash_jumpa[]   = T7FLAJP1A;
-    char T7_flash_jumpb[]   = T7FLAJP1B;
-    char T7_flash_end[]     = T7FLA_END;
-    char T7_flash_exit[]    = T7FLAEXIT;
-    char T7_flash_ack[]     = T7FLA_ACK;
-    char data[8];
-    int i, k;
 
-    // fopen modified.bin here?
-    // need lots of fcloses though
+/// Open and check the bin file to make sure that it is a valid T7 BIN file
+///
+/// params  full filename including path of the T7 BIN file
+///
+/// returns a pointer to the T7 BIN file
+///         or a null pointer if it is invalid in some way
+
+FILE * t7_file_open(const char* fname)
+{
     printf("Checking the FLASH BIN file...\r\n");
-    FILE *fp = fopen("/local/modified.bin", "r");    // Open "modified.bin" on the local file system for reading
+    FILE *fp = fopen(fname, "r");    // Open "modified.bin" on the local file system for reading
     if (!fp) {
         printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");;
-        return TERM_ERR;
+        return NULL;
     }
     // obtain file size - it should match the size of the FLASH chips:
     fseek (fp , 0 , SEEK_END);
     uint32_t file_size = ftell (fp);
     rewind (fp);
+    if (file_size != T7FLASHSIZE) {
+        fclose(fp);
+        printf("The BIN file does not appear to be for a T7 ECU :-(\r\n");
+        printf("T7's FLASH chip size is: %#010x bytes.\r\n", T7FLASHSIZE);
+        printf("The BIN's file size is: %#010x bytes.\r\n", file_size);
+        return NULL;
+    }
 
     // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU
     uint8_t stack_byte = 0;
     uint32_t stack_long = 0;
-    if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
-    stack_long |= (stack_byte << 24);
-    if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
-    stack_long |= (stack_byte << 16);
-    if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
-    stack_long |= (stack_byte << 8);
-    if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
-    stack_long |= stack_byte;
+    for (uint32_t i=0; i<4; i++) {
+        if (!fread(&stack_byte,1,1,fp)) {
+            printf("Error reading the BIN file MODIFIED.BIN\r\n");
+            return NULL;
+        }
+        stack_long <<= 8;
+        stack_long |= stack_byte;
+    }
     rewind (fp);
-
-    if (file_size != T7FLASHSIZE || stack_long != T7POINTER) {
+    if (stack_long != T7POINTER) {
         fclose(fp);
         printf("The BIN file does not appear to be for a T7 ECU :-(\r\n");
-        printf("BIN file size: %#010x, FLASH chip size: %#010x, Pointer: %#010x.\r\n", file_size, T7FLASHSIZE, stack_long);
-        return TERM_ERR;
+        printf("A T7 BIN file should start with: %#010x.\r\n", T7POINTER);
+        printf("This file starts with : %#010x.\r\n", stack_long);
+        return NULL;
+    }
+    printf("The BIN file appears to OK :-)\r\n");
+    return fp;
+}
+
+
+bool t7_flash_segment(FILE *fp, uint32_t address, uint32_t size, bool blockmode)
+{
+    char T7_flash_start[]   = T7FLASTRT;
+    char T7_flash_size[]    = T7FLASIZE;
+    char T7_flash_ack[]     = T7FLA_ACK;
+    char data[8];
+
+    int32_t i, k;
+
+    uint32_t current_address = address;
+    uint32_t segment_end = address + size;
+
+    if ((current_address > T7FLASHSIZE) || (segment_end > T7FLASHSIZE)) {
+        printf("Attempting to FLASH outside of FLASH region\r\n");
+        printf("Start Address: %#010x, End Address: %#010x.\r\n", current_address, segment_end);
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
+        return FALSE;
     }
 
-    timer.reset();
-    timer.start();
+    // blocksize can be any size between 1 and 250 (0x01 - 0xFA)
+    // Better performance is realised with a bigger blocksize
+    //
+    // The following convenient sizes to use for testing
+    //     0x04, 0x10 and 0x40
+    // A value of 0x70 is useful when programming the BIN region
+    //uint32_t blocksize = (blockmode == true) ? 0x70 : 0x04;
+    uint32_t blocksize = (blockmode == true) ? 0xFA : 0x04;
+    // Sanity check 
+    if (blocksize < 0x01) blocksize = 0x01;
+    if (blocksize > 0xFA) blocksize = 0xFA;
+    uint32_t blockquantity, blockremainder, blockfirst, blockduring;
 
-    // Send "Request Download - tool to module" to Trionic
-    if (!can_send_timeout (T7SEC_ID, T7_flash_jumpa, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+    if (fseek (fp , address , SEEK_SET) != 0x0) {
+        printf("Cannot move to file position %#010x.\r\n", current_address);
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
-    if (!can_send_timeout (T7SEC_ID, T7_flash_jumpb, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+    for(i=0; i<3; i++) {
+        T7_flash_start[6-i] = (address >> (8*i)) & 0xff;
+        T7_flash_size[4-i] = (size >> (8*i)) & 0xff;
+    }
+
+    // Send "Request Download - tool to module" to Trionic for the BIN file code and 'cal' data
+    if (!can_send_timeout (T7SEC_ID, T7_flash_start, 8, T7MESSAGETIMEOUT)) {
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
+        return FALSE;
+    }
+    if (!can_send_timeout (T7SEC_ID, T7_flash_size, 8, T7MESSAGETIMEOUT)) {
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     T7_flash_ack[3] = data[0] & 0xBF;
     if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     if ( data[3] != 0x74 ) {
         printf("Cannot Update FLASH, message refused.\r\n");
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
 
-    uint32_t address = 0;
-
+// FLASH main Binary image up to address + size
     printf("  0.00 %% complete.\r");
-    while (address < T7FLASHSIZE) {
+    while (current_address < segment_end) {
+        if ((segment_end - current_address) < blocksize) {
+            blocksize = (segment_end - current_address);
+            wait_ms(T7MESSAGETIMEOUT);
+        }
+        if (blocksize > 4) {
+            blockfirst = 4;
+            blockquantity = (blocksize - blockfirst) / 6;
+            blockremainder = (blocksize - blockfirst) % 6;
+            if (blockremainder != 0) {
+                blockquantity++;
+            }
+        } else {
+            blockfirst = blocksize;
+            blockquantity = 0;
+            blockremainder = 0;
+        }
 
-//        data[0] = 0x4A; // 0x40 send, | 0x0A (10) messages to follow
-//        data[0] = 0x42; // 0x40 send, | 0x02 (2) messages to follow
-        data[0] = 0x40; // 0x40 send, | 0x00 (0) messages to follow
+        data[0] = 0x40 + blockquantity; // e.g 0x40 send, | 0x0A (10) messages to follow
         data[1] = 0xA1;
-//        data[2] = 0x41; // length+1 (64 Bytes)
-//        data[2] = 0x11; // length+1 (16 Bytes)
-        data[2] = 0x05; // length+1 (4 Bytes)
+        data[2] = blocksize + 1; // length+1 (64 Bytes)
         data[3] = 0x36; // Data Transfer
-        for ( k = 4; k < 8; k++ )
-            //data[k] = *(bin + bin_count++);
-            if (!fread(&data[k],1,1,fp)) {
-                fclose(fp);
-                printf("Error reading the BIN file MODIFIED.BIN\r\n");
-                return FALSE;
-            }
-//      /* DEBUG info...
-//        for (k = 0; k < 8; k++ ) printf("0x%02X ", data[k] );
-//        for (k = 2; k < 8; k++ ) printf("%c ", data[k] );
-//        printf(" data\r\n");
-
-        if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
+        if (!fread((data+4),1,blockfirst,fp)) {
+            printf("\nError reading the BIN file MODIFIED.BIN\r\n");
             return FALSE;
         }
-        /*
-                for (i = 9; i>=0; i--) {
-        //        for (i = 1; i>=0; i--) {
-                    data[0] = i;
-                    // data[1] = 0xA1;
-                    for ( k = 2; k < 8; k++ )
-                        //data[k] = *(bin + bin_count++);
-                        if (!fread(&data[k],1,1,fp)) {
-                            fclose(fp);
-                            printf("Error reading the BIN file MODIFIED.BIN\r\n");
-                            return FALSE;
-                        }
-        //            /* DEBUG info...
-        //            for (k = 0; k < 8; k++ ) printf("0x%02X ", data[k] );
-        //            for (k = 2; k < 8; k++ ) printf("%c ", data[k] );
-        //            printf(" data\r\n");
-
-        //            printf("%6.2f\r", 100*(float)address/(float)T7FLASHSIZE );
-                    wait_ms(1);
-        //            wait_ms(10);   // 31/3/12 this longer wait might be needed for i-bus connections...
-                    if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
-                        printf("err t7utils line: %d\r\n", __LINE__ );
-                        fclose(fp);
-                        return FALSE;
-                    }
+#ifdef DEBUG
+// DEBUG info...
+        for (k = 0; k < 8; k++ ) printf("0x%02X ", data[k] );
+        for (k = 2; k < 8; k++ ) printf("%c ", data[k] );
+        printf(" data\r\n");
+#endif
+        if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
+            printf("\nerr %s line: %d\r\n", __FILE__, __LINE__ );
+            return FALSE;
+        }
+        if (blocksize > 4) {
+            for (i = (blockquantity-1); i>=0; i--) {
+                data[0] = i;
+                if ((i == 0) && (blockremainder != 0)) {
+                    blockduring = blockremainder;
+                } else {
+                    blockduring = 6;
                 }
-        */
-//        address += 0x40;
-//        address += 0x10;
-        address += 0x04;
+                if (!fread((data+2),1,blockduring,fp)) {
+                    printf("\nError reading the BIN file MODIFIED.BIN\r\n");
+                    return FALSE;
+                }
+#ifdef DEBUG
+//  DEBUG info...
+                for (k = 0; k < 8; k++ ) printf("0x%02X ", data[k] );
+                for (k = 2; k < 8; k++ ) printf("%c ", data[k] );
+                printf(" data\r\n");
+                printf("%6.2f\r", 100*(float)current_address/(float)T7FLASHSIZE );
+#endif
+                wait_us(300);
+//                wait_ms(10);   // 31/3/12 this longer wait might be needed for i-bus connections...
+                if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
+                    printf("\nerr %s line: %d\r\n", __FILE__, __LINE__ );
+                    return FALSE;
+                }
+            }
+        }
         if (!can_wait_timeout(T7SEC_RX, data, 8, T7LONGERTIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
+            printf("\nerr %s line: %d\r\n", __FILE__, __LINE__ );
             return FALSE;
         }
         // Send acknowledgement
         T7_flash_ack[3] = data[0] & 0xBF;
         if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
+            printf("\nerr %s line: %d\r\n", __FILE__, __LINE__ );
             return FALSE;
         }
         if ( data[3] != 0x76 ) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if (!(address % 0x80))
-            printf("%6.2f\r", 100*(float)address/(float)T7FLASHSIZE );
-    }
-    printf("\n");
-    /*
-        // Send "Request Data Transfer Exit" to Trionic
-        if (!can_send_timeout (T7SEC_ID, T7_flash_end, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        T7_flash_ack[3] = data[0] & 0xBF;
-        if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
+            printf ("\n");
+//#ifdef DEBUG
+//  DEBUG info...
+            for (k = 0; k < 8; k++ ) printf("%#04x ", data[k] );
+            for (k = 2; k < 8; k++ ) printf("%c ", data[k] );
+            printf(" data\r\n");
+//#endif
+            printf("Cannot Program Address %#010x.\r\n", current_address);
+            printf("Block Size %#04x, First %#04x, Quantity %#04x, Remainder %#04x\r\n", blocksize, blockfirst, blockquantity, blockremainder);
+            printf("\nerr %s line: %d\r\n", __FILE__, __LINE__ );
             return FALSE;
         }
-        if ( data[3] != 0x77 ) {
-            printf("Cannot Update FLASH, message refused.\r\n");
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        // Send "Request Data Transfer Exit" to Trionic
-        if (!can_send_timeout (T7SEC_ID, T7_flash_exit, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        T7_flash_ack[3] = data[0] & 0xBF;
-        if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if ( data[3] != 0x71 ) {
-            printf("Cannot Update FLASH, message refused.\r\n");
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-    */
-    timer.stop();
-    printf("SUCCESS! Programming the FLASH took %#.1f seconds.\r\n",timer.read());
-    fclose(fp);
+        current_address += blocksize;
+//        if (!(current_address % 0x80))
+            printf("%6.2f\r", 100*(float)current_address/(float)T7FLASHSIZE );
+    }
+    if (blockmode == true) wait_ms(T7MESSAGETIMEOUT);
     return TRUE;
 }
 
+bool t7_flash(FILE *fp, bool blockmode)
+{
+    timer.reset();
+    timer.start();
+    printf("T7 program and caldata\r\n");
+    if (t7_flash_segment(fp, 0x000000, 0x070000, blockmode)) {              // T7 program and caldata
+        printf("\nAdaptation data 1\r\n");
+        if (t7_flash_segment(fp, 0x070000, 0x002000, blockmode)) {          // Adaptation data 1
+            printf("\nAdaptation data 2\r\n");
+            if (t7_flash_segment(fp, 0x07C000, 0x00280, blockmode)) {       // Adaptation data 2
+                printf("\nT7Suite watermark\r\n");
+                if (t7_flash_segment(fp, 0x07FD00, 0x000020, blockmode)) {      // T7Suite watermark
+                    printf("\nT7 Header\r\n");
+                    if (t7_flash_segment(fp, 0x07FF00, 0x000100, blockmode)) {  // T7 Header
+                        timer.stop();
+                        printf("100.00\r\n");
+                        printf("SUCCESS! Programming the FLASH took %#.1f seconds.\r\n",timer.read());
+                        return true;
+                    }
+                }
+            }
+        }
+    }
+    timer.stop();
+    printf("\nFAILURE! Unable to program FLASH after %#.1f seconds.\r\n",timer.read());
+    return false;
+}
 
-bool t7_flash() {
-    char T7_flash_jumpa[]   = T7FLABINA;
-    char T7_flash_jumpb[]   = T7FLABINB;
-    char T7_flash_jumpc[]   = T7FLAHDRA;
-    char T7_flash_jumpd[]   = T7FLAHDRB;
-    char T7_flash_end[]     = T7FLA_END;
+bool t7_recover(FILE *fp)
+{
+    timer.reset();
+    timer.start();
+    if (t7_flash_segment(fp, 0x000000, 0x080000, false)) {              // Entire T7 BIN File
+        timer.stop();
+        printf("100.00\r\n");
+        printf("SUCCESS! Programming the FLASH took %#.1f seconds.\r\n",timer.read());
+        return true;
+    }
+    timer.stop();
+    printf("\nFAILURE! Unable to program FLASH after %#.1f seconds.\r\n",timer.read());
+    return false;
+}
+
+
+/// Reset and restart a T7 ECU after a FLASH operation
+///
+/// NOTE: DOESN't WORK !!!
+///
+bool t7_reset()
+{
     char T7_flash_exit[]    = T7FLAEXIT;
     char T7_flash_ack[]     = T7FLA_ACK;
+    char T7_flash_end[]     = T7FLA_END;
     char data[8];
-    int i, k;
-
-    // fopen modified.bin here?
-    // need lots of fcloses though
-    printf("Checking the FLASH BIN file...\r\n");
-    FILE *fp = fopen("/local/modified.bin", "r");    // Open "modified.bin" on the local file system for reading
-    if (!fp) {
-        printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");;
-        return TERM_ERR;
-    }
-    // obtain file size - it should match the size of the FLASH chips:
-    fseek (fp , 0 , SEEK_END);
-    uint32_t file_size = ftell (fp);
-    rewind (fp);
 
-    // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU
-    uint8_t stack_byte = 0;
-    uint32_t stack_long = 0;
-    if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
-    stack_long |= (stack_byte << 24);
-    if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
-    stack_long |= (stack_byte << 16);
-    if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
-    stack_long |= (stack_byte << 8);
-    if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
-    stack_long |= stack_byte;
-    rewind (fp);
-
-    if (file_size != T7FLASHSIZE || stack_long != T7POINTER) {
-        fclose(fp);
-        printf("The BIN file does not appear to be for a T7 ECU :-(\r\n");
-        printf("BIN file size: %#010x, FLASH chip size: %#010x, Pointer: %#010x.\r\n", file_size, T7FLASHSIZE, stack_long);
-        return TERM_ERR;
-    }
-
-    timer.reset();
-    timer.start();
-
-    // Send "Request Download - tool to module" to Trionic
-    if (!can_send_timeout (T7SEC_ID, T7_flash_jumpa, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
-        return FALSE;
-    }
-    if (!can_send_timeout (T7SEC_ID, T7_flash_jumpb, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+    printf("Restarting T7 ECU");
+    // Send "Request Data Transfer Exit" to Trionic
+    if (!can_send_timeout (T7SEC_ID, T7_flash_end, 8, T7MESSAGETIMEOUT)) {
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     T7_flash_ack[3] = data[0] & 0xBF;
     if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
-        return FALSE;
-    }
-    if ( data[3] != 0x74 ) {
-        printf("Cannot Update FLASH, message refused.\r\n");
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
-
-    uint32_t address = 0;
-
-    printf("  0.00 %% complete.\r");
-// FLASH main Binary image up to address 0x7B000
-    while (address < 0x70000) {
-        data[0] = 0x40; // 0x40 send, | 0x00 (0) messages to follow
-        data[1] = 0xA1;
-        data[2] = 0x05; // length+1 (4 Bytes)
-        data[3] = 0x36; // Data Transfer
-        for ( k = 4; k < 8; k++ )
-            if (!fread(&data[k],1,1,fp)) {
-                fclose(fp);
-                printf("Error reading the BIN file MODIFIED.BIN\r\n");
-                return FALSE;
-            }
-        if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        address += 0x04;
-        if (!can_wait_timeout(T7SEC_RX, data, 8, T7LONGERTIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        // Send acknowledgement
-        T7_flash_ack[3] = data[0] & 0xBF;
-        if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if ( data[3] != 0x76 ) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if (!(address % 0x80))
-            printf("%6.2f\r", 100*(float)address/(float)T7FLASHSIZE );
-    }
-
-    // Send "Request Download - tool to module" to Trionic
-    if (!can_send_timeout (T7SEC_ID, T7_flash_jumpc, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+    if ( data[3] != 0x77 ) {
+        printf("Cannot Update FLASH, message refused.\r\n");
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
-    if (!can_send_timeout (T7SEC_ID, T7_flash_jumpd, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+    //
+    // Send "Request Data Transfer Exit" to Trionic
+    if (!can_send_timeout (T7SEC_ID, T7_flash_exit, 8, T7MESSAGETIMEOUT)) {
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
     T7_flash_ack[3] = data[0] & 0xBF;
     if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
-        return FALSE;
-    }
-    if ( data[3] != 0x74 ) {
-        printf("Cannot Update FLASH, message refused.\r\n");
-        printf("err t7utils line: %d\r\n", __LINE__ );
-        fclose(fp);
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
         return FALSE;
     }
-
-    address = 0x7FF00;
-    fseek (fp , 0x7FF00 , SEEK_SET);
-
-// FLASH BIN file Header
-    while (address < T7FLASHSIZE) {
-        data[0] = 0x40; // 0x40 send, | 0x00 (0) messages to follow
-        data[1] = 0xA1;
-        data[2] = 0x05; // length+1 (4 Bytes)
-        data[3] = 0x36; // Data Transfer
-        for ( k = 4; k < 8; k++ )
-            if (!fread(&data[k],1,1,fp)) {
-                fclose(fp);
-                printf("Error reading the BIN file MODIFIED.BIN\r\n");
-                return FALSE;
-            }
-        if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        address += 0x04;
-        if (!can_wait_timeout(T7SEC_RX, data, 8, T7LONGERTIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        // Send acknowledgement
-        T7_flash_ack[3] = data[0] & 0xBF;
-        if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if ( data[3] != 0x76 ) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if (!(address % 0x80))
-            printf("%6.2f\r", 100*(float)address/(float)T7FLASHSIZE );
+    if ( data[3] != 0x71 ) {
+        printf("err %s line: %d\r\n", __FILE__, __LINE__ );
+        return FALSE;
     }
-
-
-    printf("\n");
-    printf("Restarting T7 ECU");
-/*
-        // Send "Request Data Transfer Exit" to Trionic
-        if (!can_send_timeout (T7SEC_ID, T7_flash_end, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        T7_flash_ack[3] = data[0] & 0xBF;
-        if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if ( data[3] != 0x77 ) {
-            printf("Cannot Update FLASH, message refused.\r\n");
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-//
-        // Send "Request Data Transfer Exit" to Trionic
-        if (!can_send_timeout (T7SEC_ID, T7_flash_exit, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        T7_flash_ack[3] = data[0] & 0xBF;
-        if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-        if ( data[3] != 0x71 ) {
-            printf("Cannot Update FLASH, message refused.\r\n");
-            printf("err t7utils line: %d\r\n", __LINE__ );
-            fclose(fp);
-            return FALSE;
-        }
-*/
-    timer.stop();
-    printf("SUCCESS! Programming the FLASH took %#.1f seconds.\r\n",timer.read());
-    fclose(fp);
-    return TRUE;
-}
\ No newline at end of file
+    return true;
+}