Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Revision:
5:1775b4b13232
Parent:
4:682d96ff6d79
Child:
6:2fbcbebed28c
--- a/bdmtrionic.cpp	Wed Sep 11 11:55:51 2013 +0000
+++ b/bdmtrionic.cpp	Sat Apr 25 17:07:08 2015 +0000
@@ -65,6 +65,7 @@
 bool flash_am28(const uint32_t* addr, uint16_t value);
 bool get_flash_id(uint8_t* make, uint8_t* type);
 
+bool run_bdm_driver(uint32_t addr, uint32_t maxtime);
 
 //-----------------------------------------------------------------------------
 /**
@@ -160,7 +161,14 @@
             flash_size = T7FLASHSIZE;
             break;
         case AMD29F010:
-            printf("I have found AMD29F010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n");
+        case SST39SF010:
+        case AMICA29010L:
+            printf("I have found 29/39F010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n");
+            reset_func = &reset_am29;
+            flash_size = T55FLASHSIZE;
+            break;
+        case ATMEL29C010:
+            printf("I have found Atmel 29C010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n");
             reset_func = &reset_am29;
             flash_size = T55FLASHSIZE;
             break;
@@ -176,6 +184,11 @@
             reset_func = &reset_am28;
             flash_size = T52FLASHSIZE;
             break;
+        case ATMEL29C512:
+            printf("I have found Atmel 29C512 type FLASH chips; I must be connected to a repaired T5.2 ECU :-)\r\n");
+            reset_func = &reset_am28;
+            flash_size = T52FLASHSIZE;
+            break;
         default:
             // unknown flash type
             printf("I could not work out what FLASH chips or TRIONIC ECU I am connected to :-(\r\n");
@@ -207,15 +220,11 @@
         while (byte_count < FILE_BUF_LENGTH) {
             // get long word
             if (memget_long(&long_value) != TERM_OK) return TERM_ERR;
-            addr += 4;
             // send memory value to file_buffer before saving to mbed 'disk'
-            file_buffer[byte_count] = ((uint8_t)(long_value >> 24));
-            file_buffer[byte_count+1] = ((uint8_t)(long_value >> 16));
-            file_buffer[byte_count+2] = ((uint8_t)(long_value >> 8));
-            file_buffer[byte_count+3] = ((uint8_t)long_value);
-            byte_count +=4;
-            // make the activity led twinkle
-            ACTIVITYLEDON;
+            file_buffer[byte_count++] = ((uint8_t)(long_value >> 24));
+            file_buffer[byte_count++] = ((uint8_t)(long_value >> 16));
+            file_buffer[byte_count++] = ((uint8_t)(long_value >> 8));
+            file_buffer[byte_count++] = ((uint8_t)long_value);
         }
         fwrite(file_buffer, 1, FILE_BUF_LENGTH, fp);
         if (ferror (fp)) {
@@ -224,8 +233,11 @@
             return TERM_ERR;
         }
         printf("%6.2f\r", 100*(float)addr/(float)flash_size );
+        // make the activity led twinkle
+        ACTIVITYLEDON;
+        addr += FILE_BUF_LENGTH;
     }
-    printf("\n");
+    printf("100.00\r\n");
     // should 'clear' the BDM connection here but bdm_clear won't compile from here
     // instead do a memread (or anything really) but ignore the result because it's not needed for anything
     memread_long(&long_value, &addr);
@@ -408,11 +420,19 @@
             flash_size = T7FLASHSIZE;
             break;
         case AMD29F010:
-            printf("I have found AMD29F010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n");
+        case SST39SF010:
+        case AMICA29010L:
+            printf("I have found 29/39F010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n");
             reset_func = &reset_am29;
             flash_func = &flash_am29;
             flash_size = T55FLASHSIZE;
             break;
+        case ATMEL29C010:
+            printf("I have found Atmel 29C010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n");
+            reset_func = &reset_am29;
+            flash_func = NULL;
+            flash_size = T55FLASHSIZE;
+            break;
         case AMD28F010:
         case INTEL28F010:
             printf("I have found 28F010 type FLASH chips; I must be connected to a T5.5 ECU :-)\r\n");
@@ -427,20 +447,26 @@
             flash_func = &flash_am28;
             flash_size = T52FLASHSIZE;
             break;
+        case ATMEL29C512:
+            printf("I have found Atmel 29C512 type FLASH chips; I must be connected to a repaired T5.2 ECU :-)\r\n");
+            reset_func = &reset_am29;
+            flash_func = NULL;
+            flash_size = T52FLASHSIZE;
+            break;
         default:
             // unknown flash type
             printf("I could not work out what FLASH chips or TRIONIC ECU I am connected to :-(\r\n");
             return TERM_ERR;
     }
-
     // reset the FLASH chips
-    printf("Reset the FLASH chip(s) to prepare them for Erasing\r\n");
     if (!reset_func()) return TERM_ERR;
 
+
     printf("Checking the FLASH BIN file...\r\n");
-    FILE *fp = fopen("/local/modified.hex", "r");    // Open "modified.hex" on the local file system for reading
+    FILE *fp = fopen("/local/modified.bin", "r");    // Open "modified.bin" on the local file system for reading
+//    FILE *fp = fopen("/local/original.bin", "r");    // Open "original.bin" on the local file system for reading
     if (!fp) {
-        printf("Error: I could not find the BIN file MODIFIED.HEX\r\n");;
+        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:
@@ -449,17 +475,13 @@
     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;
+    uint8_t stack_bytes[4] = {0, 0, 0, 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;
+    if (!fread(&stack_bytes[0],1,4,fp)) return TERM_ERR;
     rewind (fp);
+    for(uint32_t i=0; i<4; i++) {
+        (stack_long <<= 8) |= stack_bytes[i];
+    }
 
     if (flash_size == T52FLASHSIZE && (file_size != T52FLASHSIZE || stack_long != T5POINTER)) {
         fclose(fp);
@@ -486,86 +508,801 @@
         return TERM_ERR;
     }
 
-    timer.reset();
-    timer.start();
-
     uint32_t curr_addr = 0;
 
     switch (type) {
-            // AM29Fxxx chips (retrofitted to Trionic 5.x; original to T7)
         case AMD29BL802C:
-        case AMD29F400B:
         case AMD29F400T:
         case AMD29F010:
-            printf("Erasing 29BL802/F400/010 type FLASH chips...\r\n");
-            if (!erase_am29()) {
-                printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n");
-                return TERM_ERR;
-            }
-            break;
-            // AM28F010 chip (Trionic 5.x original)
+        case SST39SF010:
+        case AMICA29010L:
+        case ATMEL29C010:
         case AMD28F010:
         case INTEL28F010:
         case AMD28F512:
         case INTEL28F512:
-            printf("Erasing 28F010/512 type FLASH chips...\r\n");
-            if (!erase_am28(&curr_addr, &flash_size)) {
-                printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n");
-                return TERM_ERR;
-            }
-            break;
-        default:
-            // unknown flash type - shouldn't get here hence "Strange!"
-            printf("Strange! I couldn't work out how to erase the FLASH chips in the TRIONIC ECU that I am connected to :-(\r\n");
-            return TERM_ERR;
-    }
+        case ATMEL29C512: {
+            // BDM FLASH Driver
+            /*
+                        uint8_t flashDriver5[] = {\
+                                                 0x60,0x00,0x04,0x08,\
+                                                 0x7C,0x2F,0x2D,0x5C,0x2A,0x0D,0x00,0x00,\
+                                                 0x02,0x03,0x00,0x03,0x41,0xFA,0xFF,0xF6,\
+                                                 0x10,0xBB,0x30,0xEE,0x70,0x01,0x52,0x43,\
+                                                 0x4E,0x75,\
+                                                 0x20,0x7C,0x00,0xFF,0xFA,0x00,0x08,0x10,\
+                                                 0x00,0x04,0x66,0x4E,0xD0,0xFC,0x00,0x04,\
+                                                 0x10,0xFC,0x00,0x7F,0x08,0x10,0x00,0x03,\
+                                                 0x67,0xFA,0xD0,0xFC,0x00,0x1C,0x42,0x10,\
+                                                 0xD0,0xFC,0x00,0x23,0x30,0xBC,0x3F,0xFF,\
+                                                 0xD0,0xFC,0x00,0x04,0x70,0x07,0x30,0xC0,\
+                                                 0x30,0xBC,0x68,0x70,0xD0,0xFC,0x00,0x06,\
+                                                 0x30,0xC0,0x30,0xFC,0x30,0x30,0x30,0xC0,\
+                                                 0x30,0xBC,0x50,0x30,0xD0,0xFC,0x01,0xBE,\
+                                                 0x70,0x40,0x30,0xC0,0x30,0x80,0x30,0x3C,\
+                                                 0x55,0xF0,0x4E,0x71,0x51,0xC8,0xFF,0xFC,\
+                                                 0x60,0x18,0xD0,0xFC,0x00,0x08,0x30,0xFC,\
+                                                 0x69,0x08,0x08,0x10,0x00,0x09,0x67,0xFA,\
+                                                 0x31,0x3C,0x68,0x08,0xD0,0xFC,0x00,0x48,\
+                                                 0x42,0x50,0x4E,0x75,\
+                                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+                                                 0x00,0x00,0x2C,0x3C,0x00,0x00,0x55,0x55,\
+                                                 0x2E,0x3C,0x00,0x00,0xAA,0xAA,0x2A,0x46,\
+                                                 0x53,0x8D,0x2C,0x47,0x45,0xF8,0x00,0x00,\
+                                                 0x47,0xFA,0xFF,0xDE,0x3C,0x87,0x3A,0x86,\
+                                                 0x3C,0xBC,0x90,0x90,0x36,0xDA,0x36,0x92,\
+                                                 0x3C,0x87,0x3A,0x86,0x3C,0xBC,0xF0,0xF0,\
+                                                 0x20,0x3A,0xFF,0xC6,0x72,0x02,0x48,0x41,\
+                                                 0x74,0x01,0x0C,0x00,0x00,0x25,0x67,0x50,\
+                                                 0x0C,0x00,0x00,0xB8,0x67,0x4A,0x74,0x04,\
+                                                 0x0C,0x00,0x00,0x5D,0x67,0x42,0x74,0x01,\
+                                                 0xE3,0x99,0x0C,0x00,0x00,0xA7,0x67,0x38,\
+                                                 0x0C,0x00,0x00,0xB4,0x67,0x32,0x74,0x02,\
+                                                 0x0C,0x00,0x00,0x20,0x67,0x2A,0x0C,0x00,\
+                                                 0x00,0xA4,0x67,0x24,0x0C,0x00,0x00,0xB5,\
+                                                 0x67,0x1E,0x74,0x04,0x0C,0x00,0x00,0xD5,\
+                                                 0x67,0x16,0x74,0x03,0xE3,0x99,0x0C,0x00,\
+                                                 0x00,0x23,0x67,0x0C,0xE3,0x99,0x0C,0x00,\
+                                                 0x00,0x81,0x67,0x04,0x72,0x00,0x74,0x00,\
+                                                 0x47,0xFA,0xFF,0x6A,0x26,0x81,0x47,0xFA,\
+                                                 0xFF,0x68,0x16,0x82,0x4E,0x75,\
+                                                 0x45,0x72,0x61,0x73,0x69,0x6E,0x67,0x20,\
+                                                 0x46,0x4C,0x41,0x53,0x48,0x20,0x63,0x68,\
+                                                 0x69,0x70,0x73,0x0D,0x0A,0x00,0x41,0xFA,\
+                                                 0xFF,0xE8,0x70,0x01,0x12,0x3A,0xFF,0x44,\
+                                                 0x53,0x01,0x67,0x16,0x53,0x01,0x67,0x00,\
+                                                 0x00,0xB8,0x53,0x01,0x67,0x00,0x01,0x0A,\
+                                                 0x53,0x01,0x67,0x00,0x01,0x3A,0x60,0x00,\
+                                                 0x01,0x3A,0x4B,0xF8,0x00,0x00,0x24,0x3A,\
+                                                 0xFF,0x1E,0x26,0x02,0x3A,0xBC,0xFF,0xFF,\
+                                                 0x3A,0xBC,0xFF,0xFF,0x42,0x55,0x4A,0x35,\
+                                                 0x28,0xFF,0x67,0x28,0x7A,0x19,0x1B,0xBC,\
+                                                 0x00,0x40,0x28,0xFF,0x42,0x35,0x28,0xFF,\
+                                                 0x72,0x15,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+                                                 0x1B,0xBC,0x00,0xC0,0x28,0xFF,0x72,0x0C,\
+                                                 0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x4A,0x35,\
+                                                 0x28,0xFF,0x66,0x06,0x53,0x82,0x66,0xCC,\
+                                                 0x60,0x04,0x53,0x45,0x66,0xD0,0x42,0x55,\
+                                                 0x4A,0x55,0x4A,0x05,0x67,0x00,0x00,0xE4,\
+                                                 0x24,0x03,0x50,0xC4,0x2A,0x3C,0x03,0xE8,\
+                                                 0x03,0xE8,0x72,0x20,0x1B,0x81,0x28,0xFF,\
+                                                 0x1B,0x81,0x28,0xFF,0x32,0x3C,0x55,0xF0,\
+                                                 0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x4E,0xBA,\
+                                                 0xFE,0x24,0x1B,0xBC,0x00,0xA0,0x28,0xFF,\
+                                                 0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+                                                 0xB8,0x35,0x28,0xFF,0x66,0x08,0x48,0x45,\
+                                                 0x53,0x82,0x66,0xE6,0x60,0x04,0x53,0x45,\
+                                                 0x66,0xC8,0x42,0x55,0x4A,0x55,0x4A,0x45,\
+                                                 0x67,0x00,0x00,0x98,0x60,0x00,0x00,0x90,\
+                                                 0x70,0x01,0x42,0x83,0x1D,0x87,0x08,0x00,\
+                                                 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0x80,\
+                                                 0x08,0x00,0x1D,0x87,0x08,0x00,0x1B,0x86,\
+                                                 0x08,0x00,0x1D,0xBC,0x00,0x10,0x08,0x00,\
+                                                 0x2A,0x00,0x4E,0xBA,0xFD,0xD0,0x20,0x05,\
+                                                 0x1A,0x30,0x09,0x90,0x08,0x05,0x00,0x07,\
+                                                 0x66,0x20,0x08,0x05,0x00,0x05,0x67,0xE8,\
+                                                 0x1A,0x30,0x09,0x90,0x08,0x05,0x00,0x07,\
+                                                 0x66,0x10,0x1D,0x87,0x08,0x00,0x1B,0x86,\
+                                                 0x08,0x00,0x1D,0xBC,0x00,0xF0,0x08,0x00,\
+                                                 0x60,0x40,0x53,0x80,0x67,0xAE,0x60,0x36,\
+                                                 0x42,0x83,0x3C,0x87,0x3A,0x86,0x3C,0xBC,\
+                                                 0x00,0x80,0x3C,0x87,0x3A,0x86,0x3C,0xBC,\
+                                                 0x00,0x10,0x4E,0xBA,0xFD,0x88,0x3A,0x15,\
+                                                 0x08,0x05,0x00,0x07,0x66,0x18,0x08,0x05,\
+                                                 0x00,0x05,0x67,0xEE,0x3A,0x15,0x08,0x05,\
+                                                 0x00,0x07,0x66,0x0A,0x3C,0x87,0x3A,0x86,\
+                                                 0x3C,0xBC,0x00,0xF0,0x60,0x04,0x42,0x80,\
+                                                 0x60,0x02,0x70,0x01,0x4E,0x75,\
+                                                 0x47,0xFB,0x01,0x70,0x00,0x00,0x04,0x50,\
+                                                 0x28,0x49,0x24,0x3C,0x00,0x00,0x01,0x00,\
+                                                 0x12,0x3A,0xFD,0xDA,0x53,0x01,0x67,0x14,\
+                                                 0x53,0x01,0x67,0x5A,0x53,0x01,0x67,0x00,\
+                                                 0x00,0xBC,0x53,0x01,0x67,0x00,0x01,0x00,\
+                                                 0x60,0x00,0x01,0x2E,0x10,0x33,0x28,0xFF,\
+                                                 0x0C,0x00,0x00,0xFF,0x67,0x28,0x7A,0x19,\
+                                                 0x19,0xBC,0x00,0x40,0x28,0xFF,0x19,0x80,\
+                                                 0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\
+                                                 0xFF,0xFC,0x19,0xBC,0x00,0xC0,0x28,0xFF,\
+                                                 0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+                                                 0xB0,0x34,0x28,0xFF,0x66,0x06,0x53,0x82,\
+                                                 0x66,0xCA,0x60,0x04,0x53,0x05,0x66,0xD0,\
+                                                 0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\
+                                                 0x00,0xE8,0x60,0x00,0x00,0xE0,0x20,0x0C,\
+                                                 0xD0,0x82,0xC0,0xBC,0x00,0x00,0x00,0x01,\
+                                                 0x08,0x40,0x00,0x00,0x16,0x33,0x28,0xFF,\
+                                                 0x0C,0x03,0x00,0xFF,0x67,0x48,0x1D,0x87,\
+                                                 0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\
+                                                 0x00,0xA0,0x08,0x00,0x19,0x83,0x28,0xFF,\
+                                                 0xC6,0x3C,0x00,0x80,0x18,0x34,0x28,0xFF,\
+                                                 0x1A,0x04,0xC8,0x3C,0x00,0x80,0xB8,0x03,\
+                                                 0x67,0x24,0x08,0x05,0x00,0x05,0x67,0xEC,\
+                                                 0x18,0x34,0x28,0xFF,0xC8,0x3C,0x00,0x80,\
+                                                 0xB8,0x03,0x67,0x12,0x1D,0x87,0x08,0x00,\
+                                                 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\
+                                                 0x08,0x00,0x60,0x00,0x00,0x84,0x53,0x82,\
+                                                 0x66,0xA6,0x60,0x78,0x36,0x33,0x28,0xFE,\
+                                                 0x0C,0x43,0xFF,0xFF,0x67,0x3A,0x3C,0x87,\
+                                                 0x3A,0x86,0x3C,0xBC,0x00,0xA0,0x39,0x83,\
+                                                 0x28,0xFE,0xC6,0x7C,0x00,0x80,0x38,0x34,\
+                                                 0x28,0xFE,0x3A,0x04,0xC8,0x7C,0x00,0x80,\
+                                                 0xB8,0x43,0x67,0x1C,0x08,0x05,0x00,0x05,\
+                                                 0x67,0xEC,0x38,0x34,0x28,0xFE,0xC8,0x7C,\
+                                                 0x00,0x80,0xB8,0x43,0x67,0x0A,0x3C,0x87,\
+                                                 0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x38,\
+                                                 0x55,0x82,0x66,0xB8,0x60,0x2E,0x3C,0x87,\
+                                                 0x3A,0x86,0x3C,0xBC,0xA0,0xA0,0x39,0xB3,\
+                                                 0x28,0xFE,0x28,0xFE,0x55,0x82,0x66,0xF6,\
+                                                 0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,\
+                                                 0xFF,0xFC,0x34,0x3C,0x01,0x00,0x36,0x33,\
+                                                 0x28,0xFE,0xB6,0x74,0x28,0xFE,0x66,0x08,\
+                                                 0x55,0x82,0x66,0xF2,0x42,0x80,0x60,0x02,\
+                                                 0x70,0x01,0x4E,0x75,\
+                                                 0x4F,0xFB,0x01,0x70,0x00,0x00,0x02,0xF4,\
+                                                 0x4E,0xBA,0xFC,0x0A,0x4E,0xBA,0xFC,0x84,\
+                                                 0x4E,0xBA,0xFD,0x32,0x4A,0xFA,0x42,0x80,\
+                                                 0x22,0x40,0x4E,0xBA,0xFE,0x88,0x4A,0xFA,\
+                                                 0xD2,0xFC,0x01,0x00,0x60,0xF4
+                                                };
 
-    timer.stop();
-    printf("Erasing took %#.1f seconds.\r\n",timer.read());
-
-    printf("Programming the FLASH chips...\r\n");
+                        uint8_t flashDriver6[] = {\
+                                                0x60,0x00,0x04,0x0A,\
+                                                0x7C,0x2F,0x2D,0x5C,0x2A,0x0D,0x00,0x00,\
+                                                0x02,0x03,0x00,0x03,0x41,0xFA,0xFF,0xF6,\
+                                                0x10,0xBB,0x30,0xEE,0x70,0x01,0x4A,0xFA,\
+                                                0x52,0x43,0x4E,0x75,\
+                                                0x20,0x7C,0x00,0xFF,0xFA,0x00,0x08,0x10,\
+                                                0x00,0x04,0x66,0x4E,0xD0,0xFC,0x00,0x04,\
+                                                0x10,0xFC,0x00,0x7F,0x08,0x10,0x00,0x03,\
+                                                0x67,0xFA,0xD0,0xFC,0x00,0x1C,0x42,0x10,\
+                                                0xD0,0xFC,0x00,0x23,0x30,0xBC,0x3F,0xFF,\
+                                                0xD0,0xFC,0x00,0x04,0x70,0x07,0x30,0xC0,\
+                                                0x30,0xBC,0x68,0x70,0xD0,0xFC,0x00,0x06,\
+                                                0x30,0xC0,0x30,0xFC,0x30,0x30,0x30,0xC0,\
+                                                0x30,0xBC,0x50,0x30,0xD0,0xFC,0x01,0xBE,\
+                                                0x70,0x40,0x30,0xC0,0x30,0x80,0x30,0x3C,\
+                                                0x55,0xF0,0x4E,0x71,0x51,0xC8,0xFF,0xFC,\
+                                                0x60,0x18,0xD0,0xFC,0x00,0x08,0x30,0xFC,\
+                                                0x69,0x08,0x08,0x10,0x00,0x09,0x67,0xFA,\
+                                                0x31,0x3C,0x68,0x08,0xD0,0xFC,0x00,0x48,\
+                                                0x42,0x50,0x4E,0x75,\
+                                                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+                                                0x00,0x00,0x2C,0x3C,0x00,0x00,0x55,0x55,\
+                                                0x2E,0x3C,0x00,0x00,0xAA,0xAA,0x2A,0x46,\
+                                                0x53,0x8D,0x2C,0x47,0x45,0xF8,0x00,0x00,\
+                                                0x47,0xFA,0xFF,0xDE,0x3C,0x87,0x3A,0x86,\
+                                                0x3C,0xBC,0x90,0x90,0x36,0xDA,0x36,0x92,\
+                                                0x3C,0x87,0x3A,0x86,0x3C,0xBC,0xF0,0xF0,\
+                                                0x20,0x3A,0xFF,0xC6,0x72,0x02,0x48,0x41,\
+                                                0x74,0x01,0x0C,0x00,0x00,0x25,0x67,0x50,\
+                                                0x0C,0x00,0x00,0xB8,0x67,0x4A,0x74,0x04,\
+                                                0x0C,0x00,0x00,0x5D,0x67,0x42,0x74,0x01,\
+                                                0xE3,0x99,0x0C,0x00,0x00,0xA7,0x67,0x38,\
+                                                0x0C,0x00,0x00,0xB4,0x67,0x32,0x74,0x02,\
+                                                0x0C,0x00,0x00,0x20,0x67,0x2A,0x0C,0x00,\
+                                                0x00,0xA4,0x67,0x24,0x0C,0x00,0x00,0xB5,\
+                                                0x67,0x1E,0x74,0x04,0x0C,0x00,0x00,0xD5,\
+                                                0x67,0x16,0x74,0x03,0xE3,0x99,0x0C,0x00,\
+                                                0x00,0x23,0x67,0x0C,0xE3,0x99,0x0C,0x00,\
+                                                0x00,0x81,0x67,0x04,0x72,0x00,0x74,0x00,\
+                                                0x47,0xFA,0xFF,0x6A,0x26,0x81,0x47,0xFA,\
+                                                0xFF,0x68,0x16,0x82,0x4E,0x75,\
+                                                0x45,0x72,0x61,0x73,0x69,0x6E,0x67,0x20,\
+                                                0x46,0x4C,0x41,0x53,0x48,0x20,0x63,0x68,\
+                                                0x69,0x70,0x73,0x0D,0x0A,0x00,0x41,0xFA,\
+                                                0xFF,0xE8,0x70,0x01,0x12,0x3A,0xFF,0x44,\
+                                                0x53,0x01,0x67,0x16,0x53,0x01,0x67,0x00,\
+                                                0x00,0xB8,0x53,0x01,0x67,0x00,0x01,0x0A,\
+                                                0x53,0x01,0x67,0x00,0x01,0x3A,0x60,0x00,\
+                                                0x01,0x3A,0x4B,0xF8,0x00,0x00,0x24,0x3A,\
+                                                0xFF,0x1E,0x26,0x02,0x3A,0xBC,0xFF,0xFF,\
+                                                0x3A,0xBC,0xFF,0xFF,0x42,0x55,0x4A,0x35,\
+                                                0x28,0xFF,0x67,0x28,0x7A,0x19,0x1B,0xBC,\
+                                                0x00,0x40,0x28,0xFF,0x42,0x35,0x28,0xFF,\
+                                                0x72,0x15,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+                                                0x1B,0xBC,0x00,0xC0,0x28,0xFF,0x72,0x0C,\
+                                                0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x4A,0x35,\
+                                                0x28,0xFF,0x66,0x06,0x53,0x82,0x66,0xCC,\
+                                                0x60,0x04,0x53,0x45,0x66,0xD0,0x42,0x55,\
+                                                0x4A,0x55,0x4A,0x05,0x67,0x00,0x00,0xE4,\
+                                                0x24,0x03,0x50,0xC4,0x2A,0x3C,0x03,0xE8,\
+                                                0x03,0xE8,0x72,0x20,0x1B,0x81,0x28,0xFF,\
+                                                0x1B,0x81,0x28,0xFF,0x32,0x3C,0x55,0xF0,\
+                                                0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x4E,0xBA,\
+                                                0xFE,0x22,0x1B,0xBC,0x00,0xA0,0x28,0xFF,\
+                                                0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+                                                0xB8,0x35,0x28,0xFF,0x66,0x08,0x48,0x45,\
+                                                0x53,0x82,0x66,0xE6,0x60,0x04,0x53,0x45,\
+                                                0x66,0xC8,0x42,0x55,0x4A,0x55,0x4A,0x45,\
+                                                0x67,0x00,0x00,0x98,0x60,0x00,0x00,0x90,\
+                                                0x70,0x01,0x42,0x83,0x1D,0x87,0x08,0x00,\
+                                                0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0x80,\
+                                                0x08,0x00,0x1D,0x87,0x08,0x00,0x1B,0x86,\
+                                                0x08,0x00,0x1D,0xBC,0x00,0x10,0x08,0x00,\
+                                                0x2A,0x00,0x4E,0xBA,0xFD,0xCE,0x20,0x05,\
+                                                0x1A,0x30,0x09,0x90,0x08,0x05,0x00,0x07,\
+                                                0x66,0x20,0x08,0x05,0x00,0x05,0x67,0xE8,\
+                                                0x1A,0x30,0x09,0x90,0x08,0x05,0x00,0x07,\
+                                                0x66,0x10,0x1D,0x87,0x08,0x00,0x1B,0x86,\
+                                                0x08,0x00,0x1D,0xBC,0x00,0xF0,0x08,0x00,\
+                                                0x60,0x40,0x53,0x80,0x67,0xAE,0x60,0x36,\
+                                                0x42,0x83,0x3C,0x87,0x3A,0x86,0x3C,0xBC,\
+                                                0x00,0x80,0x3C,0x87,0x3A,0x86,0x3C,0xBC,\
+                                                0x00,0x10,0x4E,0xBA,0xFD,0x86,0x3A,0x15,\
+                                                0x08,0x05,0x00,0x07,0x66,0x18,0x08,0x05,\
+                                                0x00,0x05,0x67,0xEE,0x3A,0x15,0x08,0x05,\
+                                                0x00,0x07,0x66,0x0A,0x3C,0x87,0x3A,0x86,\
+                                                0x3C,0xBC,0x00,0xF0,0x60,0x04,0x42,0x80,\
+                                                0x60,0x02,0x70,0x01,0x4E,0x75,\
+                                                0x47,0xFB,0x01,0x70,0x00,0x00,0x04,0x4E,\
+                                                0x28,0x49,0x24,0x3C,0x00,0x00,0x01,0x00,\
+                                                0x12,0x3A,0xFD,0xDA,0x53,0x01,0x67,0x14,\
+                                                0x53,0x01,0x67,0x5A,0x53,0x01,0x67,0x00,\
+                                                0x00,0xBC,0x53,0x01,0x67,0x00,0x01,0x00,\
+                                                0x60,0x00,0x01,0x2E,0x10,0x33,0x28,0xFF,\
+                                                0x0C,0x00,0x00,0xFF,0x67,0x28,0x7A,0x19,\
+                                                0x19,0xBC,0x00,0x40,0x28,0xFF,0x19,0x80,\
+                                                0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\
+                                                0xFF,0xFC,0x19,0xBC,0x00,0xC0,0x28,0xFF,\
+                                                0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+                                                0xB0,0x34,0x28,0xFF,0x66,0x06,0x53,0x82,\
+                                                0x66,0xCA,0x60,0x04,0x53,0x05,0x66,0xD0,\
+                                                0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\
+                                                0x00,0xE8,0x60,0x00,0x00,0xE0,0x20,0x0C,\
+                                                0xD0,0x82,0xC0,0xBC,0x00,0x00,0x00,0x01,\
+                                                0x08,0x40,0x00,0x00,0x16,0x33,0x28,0xFF,\
+                                                0x0C,0x03,0x00,0xFF,0x67,0x48,0x1D,0x87,\
+                                                0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\
+                                                0x00,0xA0,0x08,0x00,0x19,0x83,0x28,0xFF,\
+                                                0xC6,0x3C,0x00,0x80,0x18,0x34,0x28,0xFF,\
+                                                0x1A,0x04,0xC8,0x3C,0x00,0x80,0xB8,0x03,\
+                                                0x67,0x24,0x08,0x05,0x00,0x05,0x67,0xEC,\
+                                                0x18,0x34,0x28,0xFF,0xC8,0x3C,0x00,0x80,\
+                                                0xB8,0x03,0x67,0x12,0x1D,0x87,0x08,0x00,\
+                                                0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\
+                                                0x08,0x00,0x60,0x00,0x00,0x84,0x53,0x82,\
+                                                0x66,0xA6,0x60,0x78,0x36,0x33,0x28,0xFE,\
+                                                0x0C,0x43,0xFF,0xFF,0x67,0x3A,0x3C,0x87,\
+                                                0x3A,0x86,0x3C,0xBC,0x00,0xA0,0x39,0x83,\
+                                                0x28,0xFE,0xC6,0x7C,0x00,0x80,0x38,0x34,\
+                                                0x28,0xFE,0x3A,0x04,0xC8,0x7C,0x00,0x80,\
+                                                0xB8,0x43,0x67,0x1C,0x08,0x05,0x00,0x05,\
+                                                0x67,0xEC,0x38,0x34,0x28,0xFE,0xC8,0x7C,\
+                                                0x00,0x80,0xB8,0x43,0x67,0x0A,0x3C,0x87,\
+                                                0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x38,\
+                                                0x55,0x82,0x66,0xB8,0x60,0x2E,0x3C,0x87,\
+                                                0x3A,0x86,0x3C,0xBC,0xA0,0xA0,0x39,0xB3,\
+                                                0x28,0xFE,0x28,0xFE,0x55,0x82,0x66,0xF6,\
+                                                0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,\
+                                                0xFF,0xFC,0x34,0x3C,0x01,0x00,0x36,0x33,\
+                                                0x28,0xFE,0xB6,0x74,0x28,0xFE,0x66,0x08,\
+                                                0x55,0x82,0x66,0xF2,0x42,0x80,0x60,0x02,\
+                                                0x70,0x01,0x4E,0x75,\
+                                                0x4F,0xFB,0x01,0x70,0x00,0x00,0x02,0xF2,\
+                                                0x4E,0xBA,0xFC,0x0A,0x4E,0xBA,0xFC,0x84,\
+                                                0x4E,0xBA,0xFD,0x32,0x4A,0xFA,0x42,0x80,\
+                                                0x22,0x40,0x4E,0xBA,0xFE,0x88,0x4A,0xFA,\
+                                                0xD2,0xFC,0x01,0x00,0x60,0xF4,0x00,0x00
+                                                };
+            */
+            uint8_t flashDriver[] = {\
+                                     0x60,0x00,0x04,0x0C,\
+                                     0x7C,0x2F,0x2D,0x5C,0x2A,0x0D,0x00,0x00,\
+                                     0x02,0x03,0x00,0x03,0x41,0xFA,0xFF,0xF6,\
+                                     0x10,0xBB,0x30,0xEE,0x70,0x01,0x4A,0xFA,\
+                                     0x52,0x43,0x4E,0x75,\
+                                     0x20,0x7C,0x00,0xFF,0xFA,0x00,0x08,0x10,\
+                                     0x00,0x04,0x66,0x4E,0xD0,0xFC,0x00,0x04,\
+                                     0x10,0xFC,0x00,0x7F,0x08,0x10,0x00,0x03,\
+                                     0x67,0xFA,0xD0,0xFC,0x00,0x1C,0x42,0x10,\
+                                     0xD0,0xFC,0x00,0x23,0x30,0xBC,0x3F,0xFF,\
+                                     0xD0,0xFC,0x00,0x04,0x70,0x07,0x30,0xC0,\
+                                     0x30,0xBC,0x68,0x70,0xD0,0xFC,0x00,0x06,\
+                                     0x30,0xC0,0x30,0xFC,0x30,0x30,0x30,0xC0,\
+                                     0x30,0xBC,0x50,0x30,0xD0,0xFC,0x01,0xBE,\
+                                     0x70,0x40,0x30,0xC0,0x30,0x80,0x30,0x3C,\
+                                     0x55,0xF0,0x4E,0x71,0x51,0xC8,0xFF,0xFC,\
+                                     0x60,0x18,0xD0,0xFC,0x00,0x08,0x30,0xFC,\
+                                     0x69,0x08,0x08,0x10,0x00,0x09,0x67,0xFA,\
+                                     0x31,0x3C,0x68,0x08,0xD0,0xFC,0x00,0x48,\
+                                     0x42,0x50,0x4E,0x75,\
+                                     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+                                     0x00,0x00,0x2C,0x3C,0x00,0x00,0x55,0x55,\
+                                     0x2E,0x3C,0x00,0x00,0xAA,0xAA,0x2A,0x46,\
+                                     0x53,0x8D,0x2C,0x47,0x45,0xF8,0x00,0x00,\
+                                     0x47,0xFA,0xFF,0xDE,0x3C,0x87,0x3A,0x86,\
+                                     0x3C,0xBC,0x90,0x90,0x36,0xDA,0x36,0x92,\
+                                     0x3C,0x87,0x3A,0x86,0x3C,0xBC,0xF0,0xF0,\
+                                     0x20,0x3A,0xFF,0xC6,0x72,0x02,0x48,0x41,\
+                                     0x74,0x01,0x0C,0x00,0x00,0x25,0x67,0x50,\
+                                     0x0C,0x00,0x00,0xB8,0x67,0x4A,0x74,0x04,\
+                                     0x0C,0x00,0x00,0x5D,0x67,0x42,0x74,0x01,\
+                                     0xE3,0x99,0x0C,0x00,0x00,0xA7,0x67,0x38,\
+                                     0x0C,0x00,0x00,0xB4,0x67,0x32,0x74,0x02,\
+                                     0x0C,0x00,0x00,0x20,0x67,0x2A,0x0C,0x00,\
+                                     0x00,0xA4,0x67,0x24,0x0C,0x00,0x00,0xB5,\
+                                     0x67,0x1E,0x74,0x04,0x0C,0x00,0x00,0xD5,\
+                                     0x67,0x16,0x74,0x03,0xE3,0x99,0x0C,0x00,\
+                                     0x00,0x23,0x67,0x0C,0xE3,0x99,0x0C,0x00,\
+                                     0x00,0x81,0x67,0x04,0x72,0x00,0x74,0x00,\
+                                     0x47,0xFA,0xFF,0x6A,0x26,0x81,0x47,0xFA,\
+                                     0xFF,0x68,0x16,0x82,0x4E,0x75,\
+                                     0x45,0x72,0x61,0x73,0x69,0x6E,0x67,0x20,\
+                                     0x46,0x4C,0x41,0x53,0x48,0x20,0x63,0x68,\
+                                     0x69,0x70,0x73,0x0D,0x0A,0x00,0x41,0xFA,\
+                                     0xFF,0xE8,0x70,0x01,0x4A,0xFA,0x12,0x3A,\
+                                     0xFF,0x42,0x53,0x01,0x67,0x16,0x53,0x01,\
+                                     0x67,0x00,0x00,0xB8,0x53,0x01,0x67,0x00,\
+                                     0x01,0x0A,0x53,0x01,0x67,0x00,0x01,0x3A,\
+                                     0x60,0x00,0x01,0x3A,0x4B,0xF8,0x00,0x00,\
+                                     0x24,0x3A,0xFF,0x1C,0x26,0x02,0x3A,0xBC,\
+                                     0xFF,0xFF,0x3A,0xBC,0xFF,0xFF,0x42,0x55,\
+                                     0x4A,0x35,0x28,0xFF,0x67,0x28,0x7A,0x19,\
+                                     0x1B,0xBC,0x00,0x40,0x28,0xFF,0x42,0x35,\
+                                     0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\
+                                     0xFF,0xFC,0x1B,0xBC,0x00,0xC0,0x28,0xFF,\
+                                     0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+                                     0x4A,0x35,0x28,0xFF,0x66,0x06,0x53,0x82,\
+                                     0x66,0xCC,0x60,0x04,0x53,0x45,0x66,0xD0,\
+                                     0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\
+                                     0x00,0xE4,0x24,0x03,0x50,0xC4,0x2A,0x3C,\
+                                     0x03,0xE8,0x03,0xE8,0x72,0x20,0x1B,0x81,\
+                                     0x28,0xFF,0x1B,0x81,0x28,0xFF,0x32,0x3C,\
+                                     0x55,0xF0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+                                     0x4E,0xBA,0xFE,0x20,0x1B,0xBC,0x00,0xA0,\
+                                     0x28,0xFF,0x72,0x0C,0x4E,0x71,0x51,0xC9,\
+                                     0xFF,0xFC,0xB8,0x35,0x28,0xFF,0x66,0x08,\
+                                     0x48,0x45,0x53,0x82,0x66,0xE6,0x60,0x04,\
+                                     0x53,0x45,0x66,0xC8,0x42,0x55,0x4A,0x55,\
+                                     0x4A,0x45,0x67,0x00,0x00,0x98,0x60,0x00,\
+                                     0x00,0x90,0x70,0x01,0x42,0x83,0x1D,0x87,\
+                                     0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\
+                                     0x00,0x80,0x08,0x00,0x1D,0x87,0x08,0x00,\
+                                     0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0x10,\
+                                     0x08,0x00,0x2A,0x00,0x4E,0xBA,0xFD,0xCC,\
+                                     0x20,0x05,0x1A,0x30,0x09,0x90,0x08,0x05,\
+                                     0x00,0x07,0x66,0x20,0x08,0x05,0x00,0x05,\
+                                     0x67,0xE8,0x1A,0x30,0x09,0x90,0x08,0x05,\
+                                     0x00,0x07,0x66,0x10,0x1D,0x87,0x08,0x00,\
+                                     0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\
+                                     0x08,0x00,0x60,0x40,0x53,0x80,0x67,0xAE,\
+                                     0x60,0x36,0x42,0x83,0x3C,0x87,0x3A,0x86,\
+                                     0x3C,0xBC,0x00,0x80,0x3C,0x87,0x3A,0x86,\
+                                     0x3C,0xBC,0x00,0x10,0x4E,0xBA,0xFD,0x84,\
+                                     0x3A,0x15,0x08,0x05,0x00,0x07,0x66,0x18,\
+                                     0x08,0x05,0x00,0x05,0x67,0xEE,0x3A,0x15,\
+                                     0x08,0x05,0x00,0x07,0x66,0x0A,0x3C,0x87,\
+                                     0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x04,\
+                                     0x42,0x80,0x60,0x02,0x70,0x01,0x4E,0x75,\
+                                     0x47,0xFB,0x01,0x70,0x00,0x00,0x04,0x4C,\
+                                     0x28,0x49,0x24,0x3C,0x00,0x00,0x01,0x00,\
+                                     0x12,0x3A,0xFD,0xD8,0x53,0x01,0x67,0x14,\
+                                     0x53,0x01,0x67,0x5A,0x53,0x01,0x67,0x00,\
+                                     0x00,0xBC,0x53,0x01,0x67,0x00,0x01,0x00,\
+                                     0x60,0x00,0x01,0x2E,0x10,0x33,0x28,0xFF,\
+                                     0x0C,0x00,0x00,0xFF,0x67,0x28,0x7A,0x19,\
+                                     0x19,0xBC,0x00,0x40,0x28,0xFF,0x19,0x80,\
+                                     0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\
+                                     0xFF,0xFC,0x19,0xBC,0x00,0xC0,0x28,0xFF,\
+                                     0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+                                     0xB0,0x34,0x28,0xFF,0x66,0x06,0x53,0x82,\
+                                     0x66,0xCA,0x60,0x04,0x53,0x05,0x66,0xD0,\
+                                     0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\
+                                     0x00,0xE8,0x60,0x00,0x00,0xE0,0x20,0x0C,\
+                                     0xD0,0x82,0xC0,0xBC,0x00,0x00,0x00,0x01,\
+                                     0x08,0x40,0x00,0x00,0x16,0x33,0x28,0xFF,\
+                                     0x0C,0x03,0x00,0xFF,0x67,0x48,0x1D,0x87,\
+                                     0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\
+                                     0x00,0xA0,0x08,0x00,0x19,0x83,0x28,0xFF,\
+                                     0xC6,0x3C,0x00,0x80,0x18,0x34,0x28,0xFF,\
+                                     0x1A,0x04,0xC8,0x3C,0x00,0x80,0xB8,0x03,\
+                                     0x67,0x24,0x08,0x05,0x00,0x05,0x67,0xEC,\
+                                     0x18,0x34,0x28,0xFF,0xC8,0x3C,0x00,0x80,\
+                                     0xB8,0x03,0x67,0x12,0x1D,0x87,0x08,0x00,\
+                                     0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\
+                                     0x08,0x00,0x60,0x00,0x00,0x84,0x53,0x82,\
+                                     0x66,0xA6,0x60,0x78,0x36,0x33,0x28,0xFE,\
+                                     0x0C,0x43,0xFF,0xFF,0x67,0x3A,0x3C,0x87,\
+                                     0x3A,0x86,0x3C,0xBC,0x00,0xA0,0x39,0x83,\
+                                     0x28,0xFE,0xC6,0x7C,0x00,0x80,0x38,0x34,\
+                                     0x28,0xFE,0x3A,0x04,0xC8,0x7C,0x00,0x80,\
+                                     0xB8,0x43,0x67,0x1C,0x08,0x05,0x00,0x05,\
+                                     0x67,0xEC,0x38,0x34,0x28,0xFE,0xC8,0x7C,\
+                                     0x00,0x80,0xB8,0x43,0x67,0x0A,0x3C,0x87,\
+                                     0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x38,\
+                                     0x55,0x82,0x66,0xB8,0x60,0x2E,0x3C,0x87,\
+                                     0x3A,0x86,0x3C,0xBC,0xA0,0xA0,0x39,0xB3,\
+                                     0x28,0xFE,0x28,0xFE,0x55,0x82,0x66,0xF6,\
+                                     0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,\
+                                     0xFF,0xFC,0x34,0x3C,0x01,0x00,0x36,0x33,\
+                                     0x28,0xFE,0xB6,0x74,0x28,0xFE,0x66,0x08,\
+                                     0x55,0x82,0x66,0xF2,0x42,0x80,0x60,0x02,\
+                                     0x70,0x01,0x4E,0x75,\
+                                     0x4F,0xFB,0x01,0x70,0x00,0x00,0x02,0xF0,\
+                                     0x4E,0xBA,0xFC,0x08,0x4E,0xBA,0xFC,0x82,\
+                                     0x4E,0xBA,0xFD,0x30,0x4A,0xFA,0x42,0x80,\
+                                     0x22,0x40,0x4E,0xBA,0xFE,0x88,0x4A,0xFA,\
+                                     0xD2,0xFC,0x01,0x00,0x60,0xF4
+                                    };
 
-    timer.reset();
-    timer.start();
+            /*
+            uint8_t flashDriver8[] = {\
+            0x60,0x00,0x05,0xC2,0x54,0x72,0x69,0x6F,\
+            0x6E,0x69,0x63,0x20,0x45,0x43,0x55,0x20,\
+            0x46,0x4C,0x41,0x53,0x48,0x20,0x73,0x63,\
+            0x72,0x69,0x70,0x74,0x0D,0x0A,0x00,0x50,\
+            0x72,0x6F,0x67,0x72,0x61,0x6D,0x6D,0x69,\
+            0x6E,0x67,0x20,0x46,0x4C,0x41,0x53,0x48,\
+            0x20,0x63,0x68,0x69,0x70,0x20,0x61,0x64,\
+            0x64,0x72,0x65,0x73,0x73,0x65,0x73,0x3A,\
+            0x0D,0x0A,0x00,0x54,0x72,0x69,0x6F,0x6E,\
+            0x69,0x63,0x20,0x45,0x43,0x55,0x20,0x46,\
+            0x4C,0x41,0x53,0x48,0x20,0x63,0x68,0x69,\
+            0x70,0x73,0x20,0x75,0x70,0x64,0x61,0x74,\
+            0x65,0x64,0x20,0x2D,0x20,0x65,0x6E,0x6A,\
+            0x6F,0x79,0x20,0x3A,0x2D,0x29,0x0D,0x0A,\
+            0x00,0x46,0x4C,0x41,0x53,0x48,0x20,0x73,\
+            0x69,0x7A,0x65,0x3A,0x20,0x30,0x78,0x30,\
+            0x46,0x61,0x64,0x65,0x30,0x20,0x42,0x79,\
+            0x74,0x65,0x73,0x0D,0x0A,0x00,0x30,0x78,\
+            0x30,0x43,0x61,0x66,0x65,0x30,0x2D,0x30,\
+            0x42,0x61,0x62,0x65,0x30,0x0D,0x00,0x72,\
+            0x62,0x00,\
+            0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,\
+            0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46,\
+            0xE1,0x9A,0x76,0x05,0x42,0x84,0xE9,0x9A,\
+            0x18,0x02,0x02,0x04,0x00,0x0F,0x10,0xFB,\
+            0x40,0xE0,0x51,0xCB,0xFF,0xF2,0x4E,0x75,\
+            0x7C,0x2F,0x2D,0x5C,0x2A,0x0D,0x00,0x00,\
+            0x02,0x03,0x00,0x03,0x41,0xFA,0xFF,0xF6,\
+            0x10,0xBB,0x30,0xEE,0x70,0x01,0x4A,0xFA,\
+            0x52,0x43,0x4E,0x75,\
+            0x20,0x7C,0x00,0xFF,0xFA,0x00,0x08,0x10,\
+            0x00,0x04,0x66,0x4E,0xD0,0xFC,0x00,0x04,\
+            0x10,0xFC,0x00,0x7F,0x08,0x10,0x00,0x03,\
+            0x67,0xFA,0xD0,0xFC,0x00,0x1C,0x42,0x10,\
+            0xD0,0xFC,0x00,0x23,0x30,0xBC,0x3F,0xFF,\
+            0xD0,0xFC,0x00,0x04,0x70,0x07,0x30,0xC0,\
+            0x30,0xBC,0x68,0x70,0xD0,0xFC,0x00,0x06,\
+            0x30,0xC0,0x30,0xFC,0x30,0x30,0x30,0xC0,\
+            0x30,0xBC,0x50,0x30,0xD0,0xFC,0x01,0xBE,\
+            0x70,0x40,0x30,0xC0,0x30,0x80,0x30,0x3C,\
+            0x55,0xF0,0x4E,0x71,0x51,0xC8,0xFF,0xFC,\
+            0x60,0x18,0xD0,0xFC,0x00,0x08,0x30,0xFC,\
+            0x69,0x08,0x08,0x10,0x00,0x09,0x67,0xFA,\
+            0x31,0x3C,0x68,0x08,0xD0,0xFC,0x00,0x48,\
+            0x42,0x50,0x4E,0x75,\
+            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+            0x00,0x00,0x2C,0x3C,0x00,0x00,0x55,0x55,\
+            0x2E,0x3C,0x00,0x00,0xAA,0xAA,0x2A,0x46,\
+            0x53,0x8D,0x2C,0x47,0x45,0xF8,0x00,0x00,\
+            0x47,0xFA,0xFF,0xDE,0x3C,0x87,0x3A,0x86,\
+            0x3C,0xBC,0x90,0x90,0x36,0xDA,0x36,0x92,\
+            0x3C,0x87,0x3A,0x86,0x3C,0xBC,0xF0,0xF0,\
+            0x20,0x3A,0xFF,0xC6,0x72,0x02,0x48,0x41,\
+            0x74,0x01,0x0C,0x00,0x00,0x25,0x67,0x50,\
+            0x0C,0x00,0x00,0xB8,0x67,0x4A,0x74,0x04,\
+            0x0C,0x00,0x00,0x5D,0x67,0x42,0x74,0x01,\
+            0xE3,0x99,0x0C,0x00,0x00,0xA7,0x67,0x38,\
+            0x0C,0x00,0x00,0xB4,0x67,0x32,0x74,0x02,\
+            0x0C,0x00,0x00,0x20,0x67,0x2A,0x0C,0x00,\
+            0x00,0xA4,0x67,0x24,0x0C,0x00,0x00,0xB5,\
+            0x67,0x1E,0x74,0x04,0x0C,0x00,0x00,0xD5,\
+            0x67,0x16,0x74,0x03,0xE3,0x99,0x0C,0x00,\
+            0x00,0x23,0x67,0x0C,0xE3,0x99,0x0C,0x00,\
+            0x00,0x81,0x67,0x04,0x72,0x00,0x74,0x00,\
+            0x47,0xFA,0xFF,0x6A,0x26,0x81,0x47,0xFA,\
+            0xFF,0x68,0x16,0x82,0x4E,0x75,\
+            0x46,0x6F,0x75,0x6E,0x64,0x20,0x61,0x20,\
+            0x54,0x20,0x20,0x20,0x0D,0x0A,0x00,0x00,\
+            0x20,0x3A,0xFF,0x4C,0x48,0x40,0x41,0xFA,\
+            0xFF,0xF1,0x72,0x38,0xE9,0x18,0x65,0x16,\
+            0x72,0x37,0xE3,0x18,0x65,0x10,0x72,0x35,\
+            0x10,0xC1,0x72,0x2E,0x10,0xC1,0x72,0x35,\
+            0xE3,0x18,0x65,0x02,0x72,0x32,0x10,0x81,\
+            0x41,0xFA,0xFF,0xC6,0x70,0x01,0x4A,0xFA,\
+            0x4E,0x75,\
+            0x46,0x49,0x4C,0x45,0x4E,0x41,0x4D,0x45,\
+            0x2E,0x42,0x49,0x4E,0x00,0x45,0x6E,0x74,\
+            0x65,0x72,0x20,0x61,0x20,0x66,0x69,0x6C,\
+            0x65,0x6E,0x61,0x6D,0x65,0x20,0x28,0x75,\
+            0x70,0x20,0x74,0x6F,0x20,0x38,0x20,0x63,\
+            0x68,0x61,0x72,0x61,0x63,0x74,0x65,0x72,\
+            0x73,0x29,0x3A,0x20,0x00,0x00,0x41,0xFA,\
+            0xFF,0xD5,0x70,0x01,0x4A,0xFA,0x41,0xFA,\
+            0xFF,0xC0,0x78,0x08,0x70,0x04,0x4A,0xFA,\
+            0x0C,0x00,0x00,0x0D,0x67,0x26,0x0C,0x00,\
+            0x00,0x2E,0x67,0x20,0x0C,0x00,0x00,0x08,\
+            0x66,0x0A,0xB8,0x00,0x67,0xE6,0x53,0x48,\
+            0x54,0x44,0x60,0x06,0x4A,0x04,0x67,0x0C,\
+            0x10,0xC0,0x12,0x00,0x70,0x02,0x4A,0xFA,\
+            0x51,0xCC,0xFF,0xD2,0x10,0xFC,0x00,0x2E,\
+            0x10,0xFC,0x00,0x42,0x10,0xFC,0x00,0x49,\
+            0x10,0xFC,0x00,0x4E,0x10,0xBC,0x00,0x00,\
+            0x59,0x88,0x70,0x01,0x4A,0xFA,0x41,0xFA,\
+            0xFD,0xB5,0x70,0x01,0x4A,0xFA,0x41,0xFA,\
+            0xFF,0x68,0x43,0xFA,0xFD,0xBD,0x70,0x06,\
+            0x4A,0xFA,0x41,0xFA,0xFF,0x58,0x20,0x80,\
+            0x4E,0x75,\
+            0x45,0x72,0x61,0x73,0x69,0x6E,0x67,0x20,\
+            0x46,0x4C,0x41,0x53,0x48,0x20,0x63,0x68,\
+            0x69,0x70,0x73,0x0D,0x0A,0x00,0x41,0xFA,\
+            0xFF,0xE8,0x70,0x01,0x4A,0xFA,0x12,0x3A,\
+            0xFE,0x52,0x53,0x01,0x67,0x16,0x53,0x01,\
+            0x67,0x00,0x00,0xB8,0x53,0x01,0x67,0x00,\
+            0x01,0x0A,0x53,0x01,0x67,0x00,0x01,0x3A,\
+            0x60,0x00,0x01,0x3A,0x4B,0xF8,0x00,0x00,\
+            0x24,0x3A,0xFE,0x2C,0x26,0x02,0x3A,0xBC,\
+            0xFF,0xFF,0x3A,0xBC,0xFF,0xFF,0x42,0x55,\
+            0x4A,0x35,0x28,0xFF,0x67,0x28,0x7A,0x19,\
+            0x1B,0xBC,0x00,0x40,0x28,0xFF,0x42,0x35,\
+            0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\
+            0xFF,0xFC,0x1B,0xBC,0x00,0xC0,0x28,0xFF,\
+            0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+            0x4A,0x35,0x28,0xFF,0x66,0x06,0x53,0x82,\
+            0x66,0xCC,0x60,0x04,0x53,0x45,0x66,0xD0,\
+            0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\
+            0x00,0xE4,0x24,0x03,0x50,0xC4,0x2A,0x3C,\
+            0x03,0xE8,0x03,0xE8,0x72,0x20,0x1B,0x81,\
+            0x28,0xFF,0x1B,0x81,0x28,0xFF,0x32,0x3C,\
+            0x55,0xF0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+            0x4E,0xBA,0xFD,0x30,0x1B,0xBC,0x00,0xA0,\
+            0x28,0xFF,0x72,0x0C,0x4E,0x71,0x51,0xC9,\
+            0xFF,0xFC,0xB8,0x35,0x28,0xFF,0x66,0x08,\
+            0x48,0x45,0x53,0x82,0x66,0xE6,0x60,0x04,\
+            0x53,0x45,0x66,0xC8,0x42,0x55,0x4A,0x55,\
+            0x4A,0x45,0x67,0x00,0x00,0x98,0x60,0x00,\
+            0x00,0x90,0x70,0x01,0x42,0x83,0x1D,0x87,\
+            0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\
+            0x00,0x80,0x08,0x00,0x1D,0x87,0x08,0x00,\
+            0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0x10,\
+            0x08,0x00,0x2A,0x00,0x4E,0xBA,0xFC,0xDC,\
+            0x20,0x05,0x1A,0x30,0x09,0x90,0x08,0x05,\
+            0x00,0x07,0x66,0x20,0x08,0x05,0x00,0x05,\
+            0x67,0xE8,0x1A,0x30,0x09,0x90,0x08,0x05,\
+            0x00,0x07,0x66,0x10,0x1D,0x87,0x08,0x00,\
+            0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\
+            0x08,0x00,0x60,0x40,0x53,0x80,0x67,0xAE,\
+            0x60,0x36,0x42,0x83,0x3C,0x87,0x3A,0x86,\
+            0x3C,0xBC,0x00,0x80,0x3C,0x87,0x3A,0x86,\
+            0x3C,0xBC,0x00,0x10,0x4E,0xBA,0xFC,0x94,\
+            0x3A,0x15,0x08,0x05,0x00,0x07,0x66,0x18,\
+            0x08,0x05,0x00,0x05,0x67,0xEE,0x3A,0x15,\
+            0x08,0x05,0x00,0x07,0x66,0x0A,0x3C,0x87,\
+            0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x04,\
+            0x42,0x80,0x60,0x02,0x70,0x01,0x4E,0x75,\
+            0x47,0xFB,0x01,0x70,0x00,0x00,0x02,0x96,\
+            0x28,0x49,0x24,0x3C,0x00,0x00,0x01,0x00,\
+            0x12,0x3A,0xFC,0xE8,0x53,0x01,0x67,0x14,\
+            0x53,0x01,0x67,0x5A,0x53,0x01,0x67,0x00,\
+            0x00,0xBC,0x53,0x01,0x67,0x00,0x01,0x00,\
+            0x60,0x00,0x01,0x2E,0x10,0x33,0x28,0xFF,\
+            0x0C,0x00,0x00,0xFF,0x67,0x28,0x7A,0x19,\
+            0x19,0xBC,0x00,0x40,0x28,0xFF,0x19,0x80,\
+            0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\
+            0xFF,0xFC,0x19,0xBC,0x00,0xC0,0x28,0xFF,\
+            0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\
+            0xB0,0x34,0x28,0xFF,0x66,0x06,0x53,0x82,\
+            0x66,0xCA,0x60,0x04,0x53,0x05,0x66,0xD0,\
+            0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\
+            0x00,0xE8,0x60,0x00,0x00,0xE0,0x20,0x0C,\
+            0xD0,0x82,0xC0,0xBC,0x00,0x00,0x00,0x01,\
+            0x08,0x40,0x00,0x00,0x16,0x33,0x28,0xFF,\
+            0x0C,0x03,0x00,0xFF,0x67,0x48,0x1D,0x87,\
+            0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\
+            0x00,0xA0,0x08,0x00,0x19,0x83,0x28,0xFF,\
+            0xC6,0x3C,0x00,0x80,0x18,0x34,0x28,0xFF,\
+            0x1A,0x04,0xC8,0x3C,0x00,0x80,0xB8,0x03,\
+            0x67,0x24,0x08,0x05,0x00,0x05,0x67,0xEC,\
+            0x18,0x34,0x28,0xFF,0xC8,0x3C,0x00,0x80,\
+            0xB8,0x03,0x67,0x12,0x1D,0x87,0x08,0x00,\
+            0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\
+            0x08,0x00,0x60,0x00,0x00,0x84,0x53,0x82,\
+            0x66,0xA6,0x60,0x78,0x36,0x33,0x28,0xFE,\
+            0x0C,0x43,0xFF,0xFF,0x67,0x3A,0x3C,0x87,\
+            0x3A,0x86,0x3C,0xBC,0x00,0xA0,0x39,0x83,\
+            0x28,0xFE,0xC6,0x7C,0x00,0x80,0x38,0x34,\
+            0x28,0xFE,0x3A,0x04,0xC8,0x7C,0x00,0x80,\
+            0xB8,0x43,0x67,0x1C,0x08,0x05,0x00,0x05,\
+            0x67,0xEC,0x38,0x34,0x28,0xFE,0xC8,0x7C,\
+            0x00,0x80,0xB8,0x43,0x67,0x0A,0x3C,0x87,\
+            0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x38,\
+            0x55,0x82,0x66,0xB8,0x60,0x2E,0x3C,0x87,\
+            0x3A,0x86,0x3C,0xBC,0xA0,0xA0,0x39,0xB3,\
+            0x28,0xFE,0x28,0xFE,0x55,0x82,0x66,0xF6,\
+            0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,\
+            0xFF,0xFC,0x34,0x3C,0x01,0x00,0x36,0x33,\
+            0x28,0xFE,0xB6,0x74,0x28,0xFE,0x66,0x08,\
+            0x55,0x82,0x66,0xF2,0x42,0x80,0x60,0x02,\
+            0x70,0x01,0x4E,0x75,\
+            0x4F,0xFB,0x01,0x70,0x00,0x00,0x01,0x3A,\
+            0x41,0xFA,0xFA,0x36,0x70,0x01,0x4A,0xFA,\
+            0x4E,0xBA,0xFB,0x10,0x4E,0xBA,0xFB,0x8A,\
+            0x4A,0x42,0x66,0x06,0x74,0x01,0x60,0x00,\
+            0x00,0x42,0x4E,0xBA,0xFC,0x28,0x41,0xFA,\
+            0xFA,0x93,0x24,0x3A,0xFB,0x6E,0x4E,0xBA,\
+            0xFA,0xBE,0x41,0xFA,0xFA,0x79,0x70,0x01,\
+            0x4A,0xFA,0x4E,0xBA,0xFD,0x06,0x4A,0x00,\
+            0x67,0x06,0x74,0x05,0x60,0x00,0x00,0x1C,\
+            0x4A,0xFA,0x41,0xFA,0xFA,0x0F,0x70,0x01,\
+            0x4A,0xFA,0x42,0x80,0x22,0x40,0x4E,0xBA,\
+            0xFE,0x4C,0x4A,0xFA,0xD2,0xFC,0x01,0x00,\
+            0x60,0xF4,0x20,0x7C,0x00,0xFF,0xFA,0x00,\
+            0x08,0x10,0x00,0x04,0x66,0x08,0x02,0x79,\
+            0xFF,0xBF,0x00,0xFF,0xFC,0x14,0x22,0x02,\
+            0x70,0x00,0x4A,0xFA
+            };
+            */
 
-    uint16_t word_value = 0;
-    uint8_t byte_value = 0;
-//    bool ret = true;
+
+            //if (prep_t5_do() != TERM_OK) return TERM_ERR;
+            // Set Program counter to start of BDM driver code
+            uint32_t driverAddress = 0x100000;
+            if (sysreg_write(0x0, &driverAddress) != TERM_OK) break;
+            for (uint32_t i = 0; i < sizeof(flashDriver); i++) {
+                if(memwrite_byte(&driverAddress, flashDriver[i]) != TERM_OK) return false;
+                driverAddress++;
+            }
+//            if (!bdmLoadMemory(flashDriver, driverAddress, sizeof(flashDriver))) break;
+
+            timer.reset();
+            timer.start();
+            printf("Erasing FLASH chips...\r\n");
+            printf("This can take up to a minute for a T8,\r\n");
+            printf("30s for a T7 or 15s for a T5 ECU.\r\n");
+            // execute the erase algorithm in the BDM driver
+            // write the buffer - should complete within 200 milliseconds
+            // Typical and Maximum Chip Programming times are 9 and 27 seconds for Am29BL802C
+            // Typical Chip erase time for Am29BL802C is 45 secinds, not including 0x00 programming prior to erasure.
+            // Allow for at least worst case 27 seconds programming to 0x00 + 3(?) * 45 typical erase time (162 seconds)
+            // Allow at least 200 seconds erase time 2,000 * (100ms + BDM memread time)
+            // NOTE: 29/39F010 and 29F400 erase times are considerably lower
+
+//            if (sysreg_write(0x0, &driverAddress) != TERM_OK) return TERM_ERR;
+//            break;
+            do {
+                if (!bdmRunDriver(0x0, 20000)) {
+                    printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n");
+                    return TERM_ERR;
+                }
+            } while (bdmProcessSyscall() == CONTINUE);
+
+//            if (!run_bdm_driver(0x0, 200000)) {
+//                printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n");
+//               return TERM_ERR;
+//            }
+            printf("Erasing took %#.1f seconds.\r\n",timer.read());
+
+            printf("Programming the FLASH chips...\r\n");
 
 // ready to receive data
-    printf("  0.00 %% complete.\r");
-    while (curr_addr < flash_size) {
-        // receive bytes from BIN file
-        //Get a byte - break if no more bytes to get
-        if (!fread(&byte_value,1,1,fp)) {
-            fclose(fp);
-            printf("Error reading the BIN file MODIFIED.HEX");
-            break;
-        }
-        word_value = (byte_value << 8);
-        if (!fread(&byte_value,1,1,fp)) {
-            fclose(fp);
-            printf("Error reading the BIN file MODIFIED.HEX");
+            printf("  0.00 %% complete.\r");
+            while (curr_addr < flash_size) {
+                // receive bytes from BIN file - break if no more bytes to get
+                if (!fread(file_buffer,1,0x100,fp)) {
+                    fclose(fp);
+                    printf("Error reading the BIN file MODIFIED.BIN");
+                    break;
+                }
+                if (!bdmLoadMemory((uint8_t*)file_buffer, 0x100700, 0x100)) break;
+                // write the buffer - should complete within 200 milliseconds
+                if (!bdmRunDriver(0x0, 200)) break;
+//                if (!run_bdm_driver(0x0, 200)) break;
+
+                printf("%6.2f\r", 100*(float)curr_addr/(float)flash_size );
+                // make the activity LED twinkle
+                ACTIVITYLEDON;
+                curr_addr += 0x100;
+            }
             break;
         }
-        word_value |= byte_value;
+        // johnc's original method
+        case AMD29F400B:        /// a sort of dummy 'placeholder' as the 'B' chip isn't ever fitted to T7 ECUS
+        default: {
+            timer.reset();
+            timer.start();
+
+            // reset the FLASH chips
+            printf("Reset the FLASH chip(s) to prepare them for Erasing\r\n");
+            if (!reset_func()) return TERM_ERR;
 
-        // write the word if it is not 0xffff
-        if (word_value != 0xffff) {
-            if (!flash_func(&curr_addr, word_value)) break;
+            switch (type) {
+                    // AM29Fxxx chips (retrofitted to Trionic 5.x; original to T7)
+                case AMD29BL802C:
+                case AMD29F400B:
+                case AMD29F400T:
+                case AMD29F010:
+                case SST39SF010:
+                case AMICA29010L:
+                    printf("Erasing 29BL802/F400/010 type FLASH chips...\r\n");
+                    if (!erase_am29()) {
+                        printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n");
+                        return TERM_ERR;
+                    }
+                    break;
+                    // AM28F010 chip (Trionic 5.x original)
+                case AMD28F010:
+                case INTEL28F010:
+                case AMD28F512:
+                case INTEL28F512:
+                    printf("Erasing 28F010/512 type FLASH chips...\r\n");
+                    if (!erase_am28(&curr_addr, &flash_size)) {
+                        printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n");
+                        return TERM_ERR;
+                    }
+                    break;
+                case ATMEL29C010:
+                case ATMEL29C512:
+                    printf("Atmel FLASH chips do not require ERASEing :-)\r\n");
+                    break;
+                default:
+                    // unknown flash type - shouldn't get here hence "Strange!"
+                    printf("Strange! I couldn't work out how to erase the FLASH chips in the TRIONIC ECU that I am connected to :-(\r\n");
+                    return TERM_ERR;
+            }
+
+            timer.stop();
+            printf("Erasing took %#.1f seconds.\r\n",timer.read());
+
+            printf("Programming the FLASH chips...\r\n");
+
+            timer.reset();
+            timer.start();
+
+            uint16_t word_value = 0;
+
+// ready to receive data
+            printf("  0.00 %% complete.\r");
+            while (curr_addr < flash_size) {
+                // receive bytes from BIN file
+                //Get a byte - break if no more bytes to get
+                if (!fread(&file_buffer[0],1,0x2,fp)) {
+                    fclose(fp);
+                    printf("Error reading the BIN file MODIFIED.BIN");
+                    break;
+                }
+                for(uint32_t i=0; i<2; i++) {
+                    (word_value <<= 8) |= file_buffer[i];
+                }
+
+                // write the word if it is not 0xffff
+                if (word_value != 0xffff) {
+                    if (!flash_func(&curr_addr, word_value)) break;
+                }
+
+                if (!(curr_addr % 0x80)) {
+                    printf("%6.2f\r", 100*(float)curr_addr/(float)flash_size );
+                    // make the activity LED twinkle
+                    ACTIVITYLEDON;
+                }
+                curr_addr += 2;
+            }
         }
-        curr_addr += 2;
-
-        // make the activity LED twinkle
-        ACTIVITYLEDON;
-        if (!(curr_addr % 0x80))
-            printf("%6.2f\r", 100*(float)curr_addr/(float)flash_size );
     }
-    printf("\n");
     timer.stop();
     fclose(fp);
 
     if (curr_addr == flash_size) {
+        printf("100.00\r\n");
         printf("Programming took %#.1f seconds.\r\n",timer.read());
 
         // "Just4pleisure;)" 'tag' in the empty space at the end of the FLASH chip
@@ -577,8 +1314,11 @@
         //            flash_func(&flash_tag[i].addr, (flash_tag[i].val & word_value));
         //        }
 
-    } else
-        printf("WARNING: Oh dear, I couldn't program the FLASH at address 0x%8x.\r\n", curr_addr);
+    } else {
+        printf("\r\n");
+        printf("Programming took %#.1f seconds.\r\n",timer.read());
+        printf("WARNING: Oh dear, I couldn't program the FLASH at address 0x%08x.\r\n", curr_addr);
+    }
 
     // reset flash
     return (reset_func() && (curr_addr == flash_size)) ? TERM_OK : TERM_ERR;
@@ -632,13 +1372,15 @@
     uint32_t addr = 0x0;
     uint16_t verify_value;
 
-    printf(" 0.0 seconds.\r");
-    uint8_t err_cnt = ERR_COUNT;
-    while (--err_cnt) {
-        // typical erase time = 1s
-        // Allow up to 25.5 seconds erase time
-        wait_ms(100);
-        wait_ms(100);
+    printf("  0.0 seconds.\r");
+    timeout.reset();
+    timeout.start();
+    while (timeout.read() < 200.0) {
+        // Typical and Maximum Chip Programming times are 9 and 27 seconds for Am29BL802C
+        // Typical Chip erase time for Am29BL802C is 45 secinds, not including 0x00 programming prior to erasure.
+        // Allow for at least worst case 27 seconds programming to 0x00 + 3(?) * 45 typical erase time (162 seconds)
+        // Allow at least 200 seconds erase time 2,000 * (100ms + BDM memread time)
+        // NOTE: 29/39F010 and 29F400 erase times are considerably lower
         if (memread_word(&verify_value, &addr) == TERM_OK && verify_value == 0xffff) {
             // erase completed normally
             reset_am29();
@@ -647,11 +1389,10 @@
         }
         // make the activity LED twinkle
         ACTIVITYLEDON;
-        printf("%4.1f\r", (float)ERR_COUNT/5 - (float)err_cnt/5 );
+        printf("%5.1f\r", timeout.read());
     }
+    // erase failed
     printf("\n");
-
-    // erase failed
     reset_am29();
     return false;
 }
@@ -682,11 +1423,12 @@
         return false;
     }
     // verify the result
-    uint8_t err_cnt = ERR_COUNT;
-    while (--err_cnt) {
-        // Allow up to approx 2.55 milliseconds program time (255 * ~10us BDM memread time)
-        //        wait_ms(10);
-        wait_us(100);
+    timeout.reset();
+    timeout.start();
+    while (timeout.read_us() < 500) {
+        // Typical and Maximum Word Programming times are 9us and 360us for Am29BL802C
+        // Allow at least 500 microseconds program time 500 * (1us + BDM memread time)
+        // NOTE: 29/39F010 and 29F400 programming times are considerably lower
         uint16_t verify_value;
         if ((memread_word(&verify_value, addr) == TERM_OK) &&
                 (verify_value == value)) {
@@ -699,6 +1441,56 @@
     return false;
 }
 
+
+//-----------------------------------------------------------------------------
+/**
+Writes a word to a FLASH memory chip and checks the result
+MCU must be in background mode.
+
+@param        addr        BDM driver address (0 to continue)
+@param        maxtime     how long to allow driver to execute (milliseconds)
+
+@return                    succ / fail
+*/
+bool run_bdm_driver(uint32_t addr, uint32_t maxtime)
+{
+    // Start BDM driver and allow it up to 200 milliseconds to update 256 Bytes
+    // Upto 25 pulses per byte, 16us per pulse, 256 Bytes
+    // 25 * 16 * 256 = 102,400us plus overhead for driver code execution time
+    // Allowing up to 200 milliseconds seems like a good allowance.
+    uint32_t driverAddress = addr;
+    if (run_chip(&driverAddress) != TERM_OK) {
+        printf("Failed to start BDM driver.\r\n");
+        return false;
+    }
+    timeout.reset();
+    timeout.start();
+    // T5 ECUs' BDM interface seem to have problems when the running the CPU and
+    // sometimes shows the CPU briefly switching between showing BDM mode or that
+    // the CPU is running.
+    // I 'debounce' the interface state to workaround this erratic bahaviour
+    for (uint32_t debounce = 0; debounce < 5; debounce++) {
+        while (IS_RUNNING) {
+            debounce = 0;
+            if (timeout.read_ms() > maxtime) {
+                printf("Driver did not return to BDM mode.\r\n");
+                timeout.stop();
+                return false;
+            }
+        }
+        wait_us(1);
+    }
+    timeout.stop();
+    // Check return code in D0 register (0 - OK, 1 - FAILED)
+    uint32_t result = 1;
+    if (adreg_read(&result, 0x0) != TERM_OK) {
+        printf("Failed to read BDM register.\r\n");
+        return false;
+    }
+    return (result == 1) ? false : true;
+}
+
+
 //-----------------------------------------------------------------------------
 /**
 Resets a AM28Fxxx flash memory chip. MCU must be in background mode.
@@ -742,10 +1534,11 @@
         addr += 2;
         //        // feedback to host computer
         //        pc.putc(TERM_OK);
-        // make the activity LED twinkle
-        ACTIVITYLEDON;
-        if (!(addr % 0x80))
+        if (!(addr % 0x80)) {
+            // make the activity LED twinkle
+            ACTIVITYLEDON;
             printf("%6.2f\r", 100*(float)addr/(float)*end_addr );
+        }
     }
     printf("\n");
 
@@ -777,8 +1570,11 @@
             addr++;
             // make the activity LED twinkle
             ACTIVITYLEDON;
-            if (!(addr % 0x80))
+            if (!(addr % 0x80)) {
+                // make the activity LED twinkle
+                ACTIVITYLEDON;
                 printf("%6.2f\r", 100*(float)addr/(float)*end_addr );
+            }
         }
     }
     printf("\n");
@@ -918,7 +1714,8 @@
 
 uint8_t prep_t5_do(void)
 {
-
+    // Make sure that BDM clock is SLOW
+    bdm_clk_mode(SLOW);
     // reset and freeze the MC68332/377 chip
     if (restart_chip() != TERM_OK) return TERM_ERR;
 
@@ -940,7 +1737,10 @@
     // MC68377 MCR = x111111x01001111 binary after a reset
     if ((verify_value & 0x7E4F) == 0x7E4F) {
         printf ("I have found a Trionic 8 ECU.\r\n");
-// Set MC68377 to double it's default speed (16 MHz?) (SYNCR)
+        // Stop system protection (MDR bit 0 STOP-SYS-PROT)
+        long_value = 0x00fffa04;
+        if (memwrite_byte(&long_value, 0x01) != TERM_OK) return TERM_ERR;
+        // Set MC68377 to double it's default speed (16 MHz?) (SYNCR)
         long_value = 0x00fffa08;
         // First set the MFD part (change 4x to 8x)
         if (memwrite_word(&long_value, 0x6908) != TERM_OK) return TERM_ERR;
@@ -951,7 +1751,11 @@
         // Disable watchdog and monitors (SYPCR)
         long_value = 0x00fffa50;
         if (memwrite_word(&long_value, 0x0000) != TERM_OK) return TERM_ERR;
-        return TERM_OK;
+        // Enable internal 6kByte RAM of 68377 at address 0x00100000 (DPTRAM)
+        long_value = 0x00fff684;
+        if (memwrite_word(&long_value, 0x1000) != TERM_OK) return TERM_ERR;
+        // can use fast or turbo or nitrous BDM clock mode once ECU has been prepped and CPU clock is ??MHz
+//        bdm_clk_mode(NITROUS);
     }
 // MC68332 SIMCR = 0000x00011001111 binary after a reset
     //if ((verify_value & 0x00CF) == 0x00CF) {
@@ -985,12 +1789,13 @@
         // wait for programming voltage to be ready
         wait_ms(10);
         // Enable internal 2kByte RAM of 68332 at address 0x00100000 (TRAMBAR)
-        //long_value = 0x00fffb04;
-        //if (memwrite_word(&long_value, 0x1000) != TERM_OK) return TERM_ERR;
-        return TERM_OK;
+        long_value = 0x00fffb04;
+        if (memwrite_word(&long_value, 0x1000) != TERM_OK) return TERM_ERR;
+        // can use fast or turbo BDM clock mode once ECU has been prepped and CPU clock is 16MHz
+//        bdm_clk_mode(TURBO);
+//        bdm_clk_mode(FAST);
     }
-// Unknown MC683xx chip if code reaches this point
-    return TERM_ERR;
+    return TERM_OK;
 }