Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: t8utils.cpp
- Revision:
- 5:1775b4b13232
- Parent:
- 4:682d96ff6d79
- Child:
- 6:2fbcbebed28c
diff -r 682d96ff6d79 -r 1775b4b13232 t8utils.cpp
--- a/t8utils.cpp Wed Sep 11 11:55:51 2013 +0000
+++ b/t8utils.cpp Sat Apr 25 17:07:08 2015 +0000
@@ -38,7 +38,7 @@
bool t8_show_VIN()
{
- uint16_t i;
+ uint32_t i;
char T8TxFlo[] = T8FLOCTL;
char T8TxMsg[] = T8REQVIN;
char T8RxMsg[8];
@@ -87,7 +87,7 @@
char T8RxMsg[8];
char k = 0;
-// GMLANTesterPresentT8();
+// GMLANTesterPresent(T8REQID, T8RESPID);
// wait_ms(2000);
//
// printf("Requesting Security Access\r\n");
@@ -97,10 +97,10 @@
// }
// printf("Security Access Granted\r\n");
//
-// GMLANTesterPresentT8();
+// GMLANTesterPresent(T8REQID, T8RESPID);
// wait_ms(2000);
//
-// GMLANTesterPresentT8();
+// GMLANTesterPresent(T8REQID, T8RESPID);
// wait_ms(2000);
//
if (!can_send_timeout (T8TSTRID, SetVin10, 8, T8MESSAGETIMEOUT)) {
@@ -132,7 +132,7 @@
for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] );
printf("\r\n");
return TRUE;
-// GMLANTesterPresentT8();
+// GMLANTesterPresent(T8REQID, T8RESPID);
// wait_ms(2000);
//
}
@@ -147,13 +147,25 @@
// return: bool TRUE if there was a message, FALSE if no message.
//
-bool t8_authenticate(char level)
+bool t8_authenticate(uint32_t ReqID, uint32_t RespID, char level)
{
- uint16_t seed, key;
- if (!GMLANSecurityAccessRequest(level, seed)) {
+ uint16_t i, seed, key;
+// if (!GMLANSecurityAccessRequest(ReqID, RespID, level, seed)) {
+// printf("Unable to request SEED value for security access\r\n");
+// return FALSE;
+// }
+
+ for (i=0; i < 20; i++) {
+ if (GMLANSecurityAccessRequest(ReqID, RespID, level, seed))
+ break;
+ wait(1);
+ GMLANTesterPresent(ReqID, RespID);
+ }
+ if (i == 20) {
printf("Unable to request SEED value for security access\r\n");
return FALSE;
}
+
if ( seed == 0x0000 ) {
printf("T8 ECU is already unlocked\r\n");
return TRUE;
@@ -175,16 +187,17 @@
key = (key >> 8) | (key << 8);
key -= 0x3FC7;
*/
- if (!GMLANSecurityAccessSendKey(level, key)) {
+ wait_ms(1);
+ if (!GMLANSecurityAccessSendKey(ReqID, RespID, level, key)) {
printf("Unable to send KEY value for security access\r\n");
return FALSE;
}
printf("Key Accepted\r\n");
+ wait_ms(500); // was 5
return TRUE;
}
-
//
// t8_dump
//
@@ -197,7 +210,7 @@
bool t8_dump()
{
- uint16_t i = 0, k = 0;
+ uint32_t i = 0, k = 0;
char T8TxMsg[8];
char T8RxMsg[8];
@@ -206,28 +219,19 @@
printf("Creating FLASH dump file...\r\n");
//
- GMLANTesterPresentT8();
-//
- if (!GMLANprogrammingSetupProcess())
+ if (!GMLANprogrammingSetupProcess(T8REQID, T8RESPID))
return FALSE;
//
- wait_ms(500);
printf("Requesting Security Access\r\n");
- if (!t8_authenticate(0x01)) {
+ if (!t8_authenticate(T8REQID, T8RESPID, 0x01)) {
printf("Unable to get Security Access\r\n");
return FALSE;
}
printf("Security Access Granted\r\n");
- wait_ms(500);
- GMLANTesterPresentT8();
//
- char BootLoader[] = T8Bootloader;
- if(!GMLANprogrammingUtilityFileProcess(BootLoader))
+ if(!GMLANprogrammingUtilityFileProcess(T8REQID, T8RESPID, T8BootloaderRead))
return FALSE;
//
- uint32_t StartAddress = 0x0;
- uint16_t txpnt = 0;
- char iFrameNumber = 0x21;
//
printf("Downloading FLASH BIN file...\r\n");
printf("Creating FLASH dump file...\r\n");
@@ -238,7 +242,34 @@
}
printf(" 0.00 %% complete.\r");
TesterPresent.start();
- while (StartAddress < 0x100000) { // 0x100000
+
+// It is possible to save some time by only reading the program code and CAL data
+// This is just a rough calculation, and slight overestimate of the number of blocks of data needed to send the BIN file
+ T8TxMsg[0] = 0x06;
+ T8TxMsg[1] = 0x21;
+ T8TxMsg[2] = 0x80; // Blocksize
+ T8TxMsg[3] = 0x00; // This address (0x020140) points to the Header at the end of the BIN
+ T8TxMsg[4] = 0x02;
+ T8TxMsg[5] = 0x01;
+ T8TxMsg[6] = 0x40;
+ T8TxMsg[7] = 0xaa;
+ if (!can_send_timeout (T8TSTRID, T8TxMsg, 7, T8MESSAGETIMEOUT)) {
+ printf("Unable to download FLASH\r\n");
+ return FALSE;
+ }
+ if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
+ return FALSE;
+ uint32_t EndAddress = (T8RxMsg[5] << 16) | (T8RxMsg[6] << 8) | T8RxMsg[7];
+ EndAddress += 0x200; // Add some bytes for the Footer itself and to account for division rounded down later
+ char T8TxFlo[] = T8FLOCTL;
+ can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT);
+ for (i = 0; i < 0x12; i++) {
+ if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
+ return FALSE;
+ }
+ printf("Reading your BIN file adjusted for footer = 0x%06X Bytes\r\n", EndAddress );
+
+ for ( uint32_t StartAddress = 0x0; StartAddress < EndAddress; StartAddress +=0x80 ) { // 0x100000
T8TxMsg[0] = 0x06;
T8TxMsg[1] = 0x21;
T8TxMsg[2] = 0x80; // Blocksize
@@ -258,26 +289,22 @@
return FALSE;
#ifdef DEBUG
printf("first %#.3f\r\n",timer.read());
- for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] );
- printf("\r\n");
#endif
- txpnt = 0;
+ uint32_t txpnt = 0;
for (k = 4; k < 8; k++ ) file_buffer[txpnt++] = T8RxMsg[k];
uint8_t DataFrames = 0x12;
- iFrameNumber = 0x21;
+ char iFrameNumber = 0x21;
char T8TxFlo[] = T8FLOCTL;
+ can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT);
#ifdef DEBUG
printf("flowCtrl %#.3f\r\n",timer.read());
#endif
- can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT);
for (i = 0; i < DataFrames; i++) {
if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
return FALSE;
#ifdef DEBUG
printf("Consec %#.3f\r\n",timer.read());
- for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] );
- printf("\r\n");
#endif
iFrameNumber++;
for (k = 1; k < 8; k++ ) file_buffer[txpnt++] = T8RxMsg[k];
@@ -288,12 +315,22 @@
printf ("Error writing to the FLASH BIN file.\r\n");
return TERM_ERR;
}
- StartAddress +=0x80;
- printf("%6.2f\r", (100.0*(float)StartAddress)/(float)(0x100000) );
+ printf("%6.2f\r", (100.0*(float)StartAddress)/(float)(EndAddress) );
if (TesterPresent.read_ms() > 2000) {
- GMLANTesterPresentT8();
+ GMLANTesterPresent(T8REQID, T8RESPID);
TesterPresent.reset();
- ACTIVITYLEDON;
+ }
+ }
+
+ for (uint32_t i = 0; i < 0x80; i++)
+ file_buffer[i] = 0xFF;
+ while ( ftell(fp) < 0x100000 ) {
+// for ( uint32_t StartAddress = EndAddress; StartAddress < 0x100000; StartAddress +=0x80 ) {
+ fwrite((file_buffer), 1, 0x80, fp);
+ if (ferror (fp)) {
+ fclose (fp);
+ printf ("Error writing to the FLASH BIN file.\r\n");
+ return TERM_ERR;
}
}
@@ -304,69 +341,44 @@
return TRUE;
}
-bool t8_erase()
-{
- printf("Erasing T8 ECU FLASH...\r\n");
- printf("SUCCESS: The FLASH has been erased.\r\n");
- return TRUE;
-}
-
-bool t8_flash_raw()
-{
- timer.reset();
- timer.start();
- printf("Checking the FLASH BIN file...\r\n");
- timer.stop();
- printf("SUCCESS! Programming the FLASH took %#.1f seconds.\r\n",timer.read());
- return TRUE;
-}
-
bool t8_flash()
{
- uint16_t i = 0, j = 0, k = 0;
+ uint32_t i = 0, j = 0, k = 0;
timer.reset();
timer.start();
printf("FLASHing T8 BIN file...\r\n");
//
- GMLANTesterPresentT8();
-//
- if (!GMLANprogrammingSetupProcess())
+ if (!GMLANprogrammingSetupProcess(T8REQID, T8RESPID))
return FALSE;
//
- wait_ms(500);
printf("Requesting Security Access\r\n");
- if (!t8_authenticate(0x01)) {
+ if (!t8_authenticate(T8REQID, T8RESPID, 0x01)) {
printf("Unable to get Security Access\r\n");
return FALSE;
}
printf("Security Access Granted\r\n");
- wait_ms(500);
- GMLANTesterPresentT8();
//
- char BootLoader[] = T8BootloaderProg;
- if(!GMLANprogrammingUtilityFileProcess(BootLoader))
+// const uint8_t BootLoader[] = T8BootloaderProg;
+// if(!GMLANprogrammingUtilityFileProcess(T8REQID, T8RESPID, BootLoader))
+ if(!GMLANprogrammingUtilityFileProcess(T8REQID, T8RESPID, T8BootLoaderWrite))
return FALSE;
//
-
-
// All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance)
-// bool GMLANprogrammingUtilityFileProcess(char UtilityFile[]) {
-// uint16_t i = 0, j = 0, k = 0;
uint32_t StartAddress = 0x020000;
- uint16_t txpnt = 0;
+ uint32_t txpnt = 0;
char iFrameNumber = 0x21;
char GMLANMsg[8];
char data2Send[0xE0];
//
- // fopen modified.hex here, check it is OK and work out how much data I need to send
+ // fopen modified.bin here, check it is OK and work out how much data I need to send
// need lots of fcloses though
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
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:
@@ -376,7 +388,10 @@
// read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU
uint32_t stack_long = 0;
- if (!fread(&stack_long,4,1,fp)) return TERM_ERR;
+ if (!fread(&stack_long,4,1,fp)) {
+ fclose(fp);
+ return TERM_ERR;
+ }
stack_long = (stack_long >> 24) | ((stack_long << 8) & 0x00FF0000) | ((stack_long >> 8) & 0x0000FF00) | (stack_long << 24);
//
if (file_size != T8FLASHSIZE || stack_long != T8POINTER) {
@@ -389,7 +404,10 @@
// This is just a rough calculation, and slight overestimate of the number of blocks of data needed to send the BIN file
uint32_t blocks2Send;
fseek(fp,0x020140,SEEK_SET);
- if (!fread(&blocks2Send,4,1,fp)) return TERM_ERR;
+ if (!fread(&blocks2Send,4,1,fp)) {
+ fclose(fp);
+ return TERM_ERR;
+ }
blocks2Send = (blocks2Send >> 24) | ((blocks2Send << 8) & 0x00FF0000) | ((blocks2Send >> 8) & 0x0000FF00) | (blocks2Send << 24);
printf("Start address of BIN file's Footer area = 0x%06X\r\n", blocks2Send );
blocks2Send += 0x200; // Add some bytes for the Footer itself and to account for division rounded down later
@@ -401,45 +419,31 @@
fseek (fp , 0x020000 , SEEK_SET);
// Erase the FLASH
printf("Waiting for FLASH to be Erased\r\n");
- if (!GMLANRequestDownload(GMLANRequestDownloadModeEncrypted)) {
+ if (!GMLANRequestDownload(T8REQID, T8RESPID, GMLANRequestDownloadModeEncrypted)) {
+ fclose(fp);
printf("Unable to erase the FLASH chip!\r\n");
return FALSE;
}
// Now send the BIN file
+ GMLANTesterPresent(T8REQID, T8RESPID);
TesterPresent.start();
printf("Sending FLASH BIN file\r\n");
printf(" 0.00 %% complete.\r");
for (i=0; i<blocks2Send; i++) {
// get a block of 0xE0 bytes in an array called data2Send
- for ( j = 0; j < 0xE0; j++ ) {
- //data[k] = *(bin + bin_count++);
- if (!fread(&data2Send[j],1,1,fp)) {
- fclose(fp);
- printf("Error reading the BIN file MODIFIED.HEX\r\n");
- return FALSE;
- }
- // encrypt data2Send array by XORing with 6 different in a ring (modulo function)
- switch ( ((0xE0*i)+j) %6) {
- case 1:
- data2Send[j] ^= 0x68;
- break;
- case 2:
- data2Send[j] ^= 0x77;
- break;
- case 3:
- data2Send[j] ^= 0x6D;
- break;
- case 4:
- data2Send[j] ^= 0x47;
- break;
- default: // remainder 0 and 5 both XOR with 0x39
- data2Send[j] ^= 0x39;
- }
+ if (!fread(data2Send,0xE0,1,fp)) {
+ fclose(fp);
+ printf("\r\nError reading the BIN file MODIFIED.BIN\r\n");
+ return FALSE;
}
+ // encrypt data2Send array by XORing with 6 different values in a ring (modulo function)
+ char key[6] = { 0x39, 0x68, 0x77, 0x6D, 0x47, 0x39 };
+ for ( j = 0; j < 0xE0; j++ )
+ data2Send[j] ^= key[(((0xE0*i)+j) % 6)];
// Send the block of data
- if (!GMLANDataTransferFirstFrame(0xE6, GMLANDOWNLOAD, StartAddress)) {
+ if (!GMLANDataTransferFirstFrame(T8REQID, T8RESPID, 0xE6, GMLANDOWNLOAD, StartAddress)) {
fclose(fp);
- printf("Unable to start BIN File Upload\r\n");
+ printf("\r\nUnable to start BIN File Upload\r\n");
return FALSE;
}
// Send 0x20 messages of 0x07 bytes each (0x20 * 0x07 = 0xE0)
@@ -449,50 +453,21 @@
GMLANMsg[0] = iFrameNumber;
for (k=1; k<8; k++)
GMLANMsg[k] = data2Send[txpnt++];
-#ifdef DEBUG
- for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
- printf("\r\n");
-#endif
- if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) {
+ if (!can_send_timeout(T8REQID, GMLANMsg, 8, GMLANPTCT)) {
fclose(fp);
- printf("Unable to send BIN File\r\n");
+ printf("\r\nUnable to send BIN File\r\n");
return FALSE;
}
++iFrameNumber &= 0x2F;
-// wait_ms(1);
- wait_us(250);
- }
- if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) {
- fclose(fp);
- printf("I did not receive a block acknowledge message\r\n");
- return FALSE;
+ wait_us(1000); // can be as low as 250 for an ECU on its own, but need 1000 (1ms) to work in a car (use a longer delay to be ultrasafe??? )
}
- while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) {
- printf("I'm waiting for a Block to be programmed into FLASH\r\n");
- if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) {
- printf("I did not receive a block acknowledge message after enhanced timeout\r\n");
- fclose(fp);
- return FALSE;
- }
- }
-#ifdef DEBUG
- for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
- printf("\r\n");
-#endif
- if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) {
- GMLANShowReturnCode(GMLANMsg[3]);
- fclose(fp);
- return FALSE;
- }
- if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) {
- printf("EXITING due to an unexpected CAN message");
+ if (!GMLANDataTransferBlockAcknowledge(T8RESPID)) {
fclose(fp);
return FALSE;
}
if (TesterPresent.read_ms() > 2000) {
- GMLANTesterPresentT8();
+ GMLANTesterPresent(T8REQID, T8RESPID);
TesterPresent.reset();
- ACTIVITYLEDON;
}
StartAddress += 0xE0;
printf("%6.2f\r", (100.0*(float)i)/(float)(blocks2Send) );
@@ -500,14 +475,158 @@
// FLASHing complete
printf("%6.2f\r\n", (float)100 );
// End programming session and return to normal mode
- if (!GMLANReturnToNormalMode()) {
+ if (!GMLANReturnToNormalMode(T8REQID, T8RESPID)) {
fclose(fp);
printf("UH-OH! T8 ECU did not Return To Normal Mode!!\r\n");
return FALSE;
}
- wait_ms(1000);
timer.stop();
printf("SUCCESS! FLASHing the BIN file took %#.1f seconds.\r\n",timer.read());
fclose(fp);
return TRUE;
}
+
+bool t8_recover()
+{
+ uint32_t i = 0, j = 0, k = 0;
+
+ timer.reset();
+ timer.start();
+ printf("Recovering your T8 ECU ...\r\n");
+//
+ if (!GMLANprogrammingSetupProcess(T8USDTREQID, T8UUDTRESPID))
+ return FALSE;
+//
+ printf("Requesting Security Access\r\n");
+ if (!t8_authenticate(T8USDTREQID, T8UUDTRESPID, 0x01)) {
+ printf("Unable to get Security Access\r\n");
+ return FALSE;
+ }
+ printf("Security Access Granted\r\n");
+//
+// const uint8_t BootLoader[] = T8BootloaderProg;
+// if(!GMLANprogrammingUtilityFileProcess(T8USDTREQID, T8UUDTRESPID, BootLoader))
+ if(!GMLANprogrammingUtilityFileProcess(T8USDTREQID, T8UUDTRESPID, T8BootLoaderWrite))
+ return FALSE;
+//
+
+
+// All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance)
+ uint32_t StartAddress = 0x020000;
+ uint32_t txpnt = 0;
+ char iFrameNumber = 0x21;
+ char GMLANMsg[8];
+ char data2Send[0xE0];
+//
+ // fopen modified.bin here, check it is OK and work out how much data I need to send
+ // 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
+ uint32_t stack_long = 0;
+ if (!fread(&stack_long,4,1,fp)) {
+ fclose(fp);
+ return TERM_ERR;
+ }
+ stack_long = (stack_long >> 24) | ((stack_long << 8) & 0x00FF0000) | ((stack_long >> 8) & 0x0000FF00) | (stack_long << 24);
+//
+ if (file_size != T8FLASHSIZE || stack_long != T8POINTER) {
+ fclose(fp);
+ printf("The BIN file does not appear to be for a T8 ECU :-(\r\n");
+ printf("BIN file size: %#010x, FLASH chip size: %#010x, Pointer: %#010x.\r\n", file_size, T7FLASHSIZE, stack_long);
+ return TERM_ERR;
+ }
+// It is possible to save some time by only sending the program code and CAL data
+// This is just a rough calculation, and slight overestimate of the number of blocks of data needed to send the BIN file
+ uint32_t blocks2Send;
+ fseek(fp,0x020140,SEEK_SET);
+ if (!fread(&blocks2Send,4,1,fp)) {
+ fclose(fp);
+ return TERM_ERR;
+ }
+ blocks2Send = (blocks2Send >> 24) | ((blocks2Send << 8) & 0x00FF0000) | ((blocks2Send >> 8) & 0x0000FF00) | (blocks2Send << 24);
+ printf("Start address of BIN file's Footer area = 0x%06X\r\n", blocks2Send );
+ blocks2Send += 0x200; // Add some bytes for the Footer itself and to account for division rounded down later
+ blocks2Send -= 0x020000; // Remove 0x020000 because we don't send the bootblock and adaptation blocks
+ printf("Amount of data to send BIN file adjusted for footer = 0x%06X Bytes\r\n", blocks2Send );
+ blocks2Send /= 0xE0;
+ printf("Number of Blocks of 0xE0 Bytes needed to send BIN file = 0x%04X\r\n", blocks2Send );
+// Move BIN file pointer to start of data
+ fseek (fp , 0x020000 , SEEK_SET);
+// Erase the FLASH
+ printf("Waiting for FLASH to be Erased\r\n");
+ if (!GMLANRequestDownload(T8REQID, T8RESPID, GMLANRequestDownloadModeEncrypted)) {
+ fclose(fp);
+ printf("Unable to erase the FLASH chip!\r\n");
+ return FALSE;
+ }
+// Now send the BIN file
+ GMLANTesterPresent(T8REQID, T8RESPID);
+ TesterPresent.start();
+ printf("Sending FLASH BIN file\r\n");
+ printf(" 0.00 %% complete.\r");
+ for (i=0; i<blocks2Send; i++) {
+ // get a block of 0xE0 bytes in an array called data2Send
+ if (!fread(data2Send,0xE0,1,fp)) {
+ fclose(fp);
+ printf("\r\nError reading the BIN file MODIFIED.BIN\r\n");
+ return FALSE;
+ }
+ // encrypt data2Send array by XORing with 6 different values in a ring (modulo function)
+ char key[6] = { 0x39, 0x68, 0x77, 0x6D, 0x47, 0x39 };
+ for ( j = 0; j < 0xE0; j++ )
+ data2Send[j] ^= key[(((0xE0*i)+j) % 6)];
+ // Send the block of data
+ if (!GMLANDataTransferFirstFrame(T8REQID, T8RESPID, 0xE6, GMLANDOWNLOAD, StartAddress)) {
+ fclose(fp);
+ printf("\r\nUnable to start BIN File Upload\r\n");
+ return FALSE;
+ }
+ // Send 0x20 messages of 0x07 bytes each (0x20 * 0x07 = 0xE0)
+ txpnt = 0;
+ iFrameNumber = 0x21;
+ for (j=0; j < 0x20; j++) {
+ GMLANMsg[0] = iFrameNumber;
+ for (k=1; k<8; k++)
+ GMLANMsg[k] = data2Send[txpnt++];
+ if (!can_send_timeout(T8REQID, GMLANMsg, 8, GMLANPTCT)) {
+ fclose(fp);
+ printf("\r\nUnable to send BIN File\r\n");
+ return FALSE;
+ }
+ ++iFrameNumber &= 0x2F;
+ wait_us(1000); // was 250 use 1000 or wait_ms(1) to be ultrasafe
+ }
+ if (!GMLANDataTransferBlockAcknowledge(T8RESPID)) {
+ fclose(fp);
+ return FALSE;
+ }
+ if (TesterPresent.read_ms() > 2000) {
+ GMLANTesterPresent(T8REQID, T8RESPID);
+ TesterPresent.reset();
+ }
+ StartAddress += 0xE0;
+ printf("%6.2f\r", (100.0*(float)i)/(float)(blocks2Send) );
+ }
+// FLASHing complete
+ printf("%6.2f\r\n", (float)100 );
+// End programming session and return to normal mode
+ if (!GMLANReturnToNormalMode(T8REQID, T8RESPID)) {
+ fclose(fp);
+ printf("UH-OH! T8 ECU did not Return To Normal Mode!!\r\n");
+ return FALSE;
+ }
+ timer.stop();
+ fclose(fp);
+ printf("SUCCESS: Your T8 ECU has been recovered.\r\n");
+ return TRUE;
+}