Sophie Dexter
/
Just4Trionic
Just4Trionic - CAN and BDM FLASH programmer for Saab cars
t7utils.cpp
- Committer:
- Just4pLeisure
- Date:
- 2013-09-11
- Revision:
- 4:682d96ff6d79
- Parent:
- 3:92dae9083c83
- Child:
- 5:1775b4b13232
File content as of revision 4:682d96ff6d79:
/******************************************************************************* t7utils.cpp (c) 2011, 2012 by Sophie Dexter portions (c) Tomi Liljemark (firstname.surname@gmail.com) This C++ module provides functions for communicating simple messages to and from the T7 ECU ******************************************************************************** WARNING: Use at your own risk, sadly this software comes with no guarantees. This software is provided 'free' and in good faith, but the author does not accept liability for any damage arising from its use. *******************************************************************************/ #include "t7utils.h" // // t7_initialise // // sends an initialisation message to the T7 ECU // but doesn't displays anything. // // inputs: none // return: bool TRUE if there was a message, FALSE if no message. // 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)) return FALSE; // wait for the T7 to reply char T7RxMsg[8]; // if a message is not received, has the wrong id if (!can_wait_timeout(T7RESPID, T7RxMsg, 8, T7MESSAGETIMEOUT)) return FALSE; /* DEBUG info... for (int i = 0; i < 8; i++ ) printf("0x%02X ", T7RxMsg[i] ); printf(" init\r\n"); */ return TRUE; } // // t7_authenticate // // sends an authentication message to the T7 ECU // but doesn't displays anything. // // inputs: none // return: bool TRUE if there was a message, FALSE if no message. // bool t7_authenticate() { uint16_t seed, key; // uint16_t i; char T7TxAck[] = T7ACK_MSG; char T7TxMsg[] = T7SEC_MSG; char T7TxKey[] = T7KEY_MSG; char T7RxMsg[8]; // Send "Request Seed" to Trionic7 if (!can_send_timeout (T7SEC_ID, T7TxMsg, 8, T7MESSAGETIMEOUT)) return FALSE; // wait for the T7 to reply // Read "Seed" // if a message is not received id return false if (!can_wait_timeout(T7SEC_RX, T7RxMsg, 8, T7MESSAGETIMEOUT)) return FALSE; /* DEBUG info... for (i = 0; i < 8; i++ ) printf("0x%02X ", T7RxMsg[i] ); printf(" seed\r\n"); */ // Send Ack T7TxAck[3] = T7RxMsg[0] & 0xBF; if (!can_send_timeout (T7ACK_ID, T7TxAck, 8, T7MESSAGETIMEOUT)) return FALSE; // Send "Key", try two different methods of calculating the key seed = T7RxMsg[5] << 8 | T7RxMsg[6]; for (int method = 0; method < 2; method++ ) { key = seed << 2; key &= 0xFFFF; key ^= ( method ? 0x4081 : 0x8142 ); key -= ( method ? 0x1F6F : 0x2356 ); key &= 0xFFFF; T7TxKey[5] = ( key >> 8 ) & 0xFF; T7TxKey[6] = key & 0xFF; if (!can_send_timeout (T7SEC_ID, T7TxKey, 8, T7MESSAGETIMEOUT)) return FALSE; // Wait for response // if a message is not received id return false if (!can_wait_timeout(T7SEC_RX, T7RxMsg, 8, T7MESSAGETIMEOUT)) return FALSE; /* DEBUG info... for (i = 0; i < 8; i++ ) printf("0x%02X ", T7RxMsg[i] ); printf(" key %d 0x%02X 0x%02X\r\n", method, T7RxMsg[3], T7RxMsg[5]); */ // Send Ack T7TxAck[3] = T7RxMsg[0] & 0xBF; if (!can_send_timeout (T7ACK_ID, T7TxAck, 8, T7MESSAGETIMEOUT)) { /* DEBUG info... printf("Key ACK message timeout\r\n"); */ return FALSE; } if ( T7RxMsg[3] == 0x67 && T7RxMsg[5] == 0x34 ) { /* DEBUG info... printf("Key %d Accepted\r\n", method); */ return TRUE; } else { /* DEBUG info... printf("Key %d Failed\r\n", method); */ } } return FALSE; } // // t7_dump // // dumps the T7 BIN File // but doesn't displays anything. // // inputs: none // return: bool TRUE if there was a message, FALSE if no message. // bool t7_dump() { uint32_t received; uint8_t byte_count, retries, i; char T7_dump_jumpa[] = T7DMPJP1A; char T7_dump_jumpb[] = T7DMPJP1B; char T7_dump_ack[] = T7DMP_ACK; char T7_dump_data[] = T7DMPDATA; char T7_dump_end[] = T7DMP_END; char T7RxMsg[8]; printf("Creating FLASH dump file...\r\n"); FILE *fp = fopen("/local/original.bin", "w"); // Open "original.bin" on the local file system for writing if (!fp) { perror ("The following error occured"); return TERM_ERR; } timer.reset(); timer.start(); received = 0; printf(" 0.00 %% complete.\r"); while (received < T7FLASHSIZE) { // T7_dump_jumpa[7] = ((T7FLASHSIZE - received) < 0xEF) ? (T7FLASHSIZE - received) : 0xEF; T7_dump_jumpb[2] = (received >> 16) & 0xFF; T7_dump_jumpb[3] = (received >> 8) & 0xFF; T7_dump_jumpb[4] = received & 0xFF; // Send read address and length to Trionic if (!can_send_timeout (T7SEC_ID, T7_dump_jumpa, 8, T7MESSAGETIMEOUT)) { printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); return FALSE; } if (!can_send_timeout (T7SEC_ID, T7_dump_jumpb, 8, T7MESSAGETIMEOUT)) { printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); return FALSE; } // Wait for a response if (!can_wait_timeout(T7SEC_RX, T7RxMsg, 8, T7MESSAGETIMEOUT)) { printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); return FALSE; } /* DEBUG info... for (i = 0; i < 8; i++ ) printf("0x%02X ", T7RxMsg[i] ); printf(" seed\r\n"); */ // Send Ack T7_dump_ack[3] = T7RxMsg[0] & 0xBF; if (!can_send_timeout (T7ACK_ID, T7_dump_ack, 8, T7MESSAGETIMEOUT)) { printf("ERROR Asking1: %5.1f %% done\r\n", 100*(float)received/(float)T7FLASHSIZE); printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); return FALSE; } if ((T7RxMsg[3] != 0x6C) ||(T7RxMsg[4] != 0xF0)) { printf("ERROR Asking2: %5.1f %% done\r\n", 100*(float)received/(float)T7FLASHSIZE); printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); return FALSE; } // Ask T7 ECU to start sending data for (retries = 0 ; retries <10 ; retries++ ) { if (!can_send_timeout (T7SEC_ID, T7_dump_data, 8, T7MESSAGETIMEOUT)) { printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); return FALSE; } // Read mesages from the T7 ECU byte_count = 0; T7RxMsg[0] = 0x00; while (T7RxMsg[0] != 0x80 && T7RxMsg[0] != 0xC0) { if (!can_wait_timeout(T7SEC_RX, T7RxMsg, 8, T7MESSAGETIMEOUT)) break; // Need to process the received data here! // Send Ack T7_dump_ack[3] = T7RxMsg[0] & 0xBF; if (!can_send_timeout (T7ACK_ID, T7_dump_ack, 8, T7MESSAGETIMEOUT)) { printf("ERROR processing: %5.1f %% done\r\n", 100*(float)received/(float)T7FLASHSIZE); printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); return FALSE; } // /* DEBUG info... // for (i = 0; i < 8; i++ ) printf("0x%02X ", T7RxMsg[i] ); // for (i = 2; i < 8; i++ ) printf("%c ", T7RxMsg[i] ); // printf(" data\r\n"); for (i = 2; i < 8; i++ ) file_buffer[byte_count++] = (T7RxMsg[i]); // */ } // Success if these conditions met if (T7RxMsg[0] == 0x80 || T7RxMsg[0] == 0xC0) break; // printf("retries: %d\r\n", retries); } if (retries > 9) { printf("err t7utils line: %d\r\n", __LINE__ ); printf("Retries: %d, Done: %5.2f %%\r\n", retries, 100*(float)received/(float)T7FLASHSIZE ); fclose(fp); return FALSE; } // received += 0xEF; received += 0x80; // printf("Retries: %d, Done: %5.2f %%\r\n", retries, 100*(float)received/(float)T7FLASHSIZE ); printf("%6.2f\r", 100*(float)received/(float)T7FLASHSIZE ); fwrite((file_buffer + 3), 1, 0x80, fp); if (ferror (fp)) { fclose (fp); printf ("Error writing to the FLASH BIN file.\r\n"); return TERM_ERR; } } printf("\n"); // Send Message to T7 ECU to say that we have finished if (!can_send_timeout (T7SEC_ID, T7_dump_end, 8, T7MESSAGETIMEOUT)) { fclose(fp); return FALSE; } // Wait for response if (!can_wait_timeout(T7SEC_RX, T7RxMsg, 8, T7MESSAGETIMEOUT)) { fclose(fp); return FALSE; } // Send Ack T7_dump_ack[3] = T7RxMsg[0] & 0xBF; if (!can_send_timeout (T7ACK_ID, T7_dump_ack, 8, T7MESSAGETIMEOUT)) { printf("ERROR closing1: %5.1f %% done\r\n", 100*(float)received/(float)T7FLASHSIZE); printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); return FALSE; } if (T7RxMsg[3] != 0xC2) { printf("ERROR closing2: %5.1f %% done\r\n", 100*(float)received/(float)T7FLASHSIZE); printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); return FALSE; } timer.stop(); printf("SUCCESS! Getting the FLASH dump took %#.1f seconds.\r\n",timer.read()); fclose(fp); 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 }; char T7_erase_ack[] = { 0x40, 0xA1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00 }; char data[8]; int i; printf("Erasing T7 ECU FLASH...\r\n"); data[3] = 0; i = 0; 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__ ); return FALSE; } if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) { printf("err t7utils line: %d\r\n", __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__ ); return FALSE; } wait_ms(100); i++; printf("."); } printf("\r\n"); // Check to see if erase operation lasted longer than 1 sec... if (i >=10) { printf("Second Message took too long'\r\n"); return FALSE; } data[3] = 0; i = 0; 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__ ); return FALSE; } if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) { printf("err t7utils line: %d\r\n", __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__ ); return FALSE; } wait_ms(100); i++; printf("."); } printf("\r\n"); // Check to see if erase operation lasted longer than 20 sec... if (i >=200) { printf("Second Message took too long'\r\n"); return FALSE; } // 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__ ); return FALSE; } if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) { printf("err t7utils line: %d\r\n", __LINE__ ); return FALSE; } if ( data[3] != 0x7E ) { printf("err t7utils line: %d\r\n", __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__ ); return FALSE; } if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) { printf("err t7utils line: %d\r\n", __LINE__ ); return FALSE; } if ( data[3] != 0x7E ) { printf("err t7utils line: %d\r\n", __LINE__ ); 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.hex here? // 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 if (!fp) { printf("Error: I could not find the BIN file MODIFIED.HEX\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); 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] != 0x74 ) { printf("Cannot Update FLASH, message refused.\r\n"); printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); return FALSE; } uint32_t address = 0; printf(" 0.00 %% complete.\r"); while (address < T7FLASHSIZE) { // 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[1] = 0xA1; // data[2] = 0x41; // length+1 (64 Bytes) // data[2] = 0x11; // length+1 (16 Bytes) data[2] = 0x05; // length+1 (4 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.HEX\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); 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.HEX\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; } } */ // address += 0x40; // address += 0x10; 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 ); } 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); 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; } 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; char T7_flash_exit[] = T7FLAEXIT; char T7_flash_ack[] = T7FLA_ACK; char data[8]; int i, k; // fopen modified.hex here? // 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 if (!fp) { printf("Error: I could not find the BIN file MODIFIED.HEX\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); 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] != 0x74 ) { printf("Cannot Update FLASH, message refused.\r\n"); printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); 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.HEX\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); return FALSE; } if (!can_send_timeout (T7SEC_ID, T7_flash_jumpd, 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] != 0x74 ) { printf("Cannot Update FLASH, message refused.\r\n"); printf("err t7utils line: %d\r\n", __LINE__ ); fclose(fp); 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.HEX\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 ); } 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; }