Sophie Dexter
/
Just4Trionic
Just4Trionic - CAN and BDM FLASH programmer for Saab cars
Revision 3:92dae9083c83, committed 2011-06-07
- Comitter:
- Just4pLeisure
- Date:
- Tue Jun 07 12:23:28 2011 +0000
- Parent:
- 2:bf3a2b29259a
- Child:
- 4:682d96ff6d79
- Commit message:
- Basic T7 CAN DUMP and FLASH for P-BUS connection only
Requires MyBooty V2.x for T5 CAN FLASHing at 1 Mbps
Changed in this revision
--- a/canutils.cpp Tue Dec 14 21:50:35 2010 +0000 +++ b/canutils.cpp Tue Jun 07 12:23:28 2011 +0000 @@ -42,16 +42,42 @@ return (can.frequency(speed)) ? TERM_OK : TERM_ERR; } - -void show_can_message() { +// +// show_can_message +// +// Displays a CAN message in the RX buffer if there is one. +// +// inputs: none +// return: bool TRUE if there was a message, FALSE if no message. +// +extern void show_can_message() { CANMessage can_MsgRx; if (can.read(can_MsgRx)) { + CANRXLEDON; printf("w%03x%d", can_MsgRx.id, can_MsgRx.len); - for (char i=0; i<can_MsgRx.len; i++) { + for (char i=0; i<can_MsgRx.len; i++) printf("%02x", can_MsgRx.data[i]); - } + printf(" %c ", can_MsgRx.data[2]); printf("\r\n"); } + return; +} + +// +// silent_can_message +// +// Turns on the CAN receive LED if there is a CAN message +// but doesn't displays anything. +// +// inputs: none +// return: bool TRUE if there was a message, FALSE if no message. +// +extern void silent_can_message() { + CANMessage can_MsgRx; + if (can.read(can_MsgRx)) { + CANRXLEDON; + } + return; } //
--- a/canutils.h Tue Dec 14 21:50:35 2010 +0000 +++ b/canutils.h Tue Jun 07 12:23:28 2011 +0000 @@ -23,6 +23,7 @@ extern void can_close(); extern uint8_t can_set_speed(uint32_t speed); extern void show_can_message(); +extern void silent_can_message(); extern bool can_send_timeout (uint32_t id, char *frame, uint8_t len, uint16_t timeout); extern bool can_wait_timeout (uint32_t id, char *frame, uint8_t len, uint16_t timeout);
--- a/main.cpp Tue Dec 14 21:50:35 2010 +0000 +++ b/main.cpp Tue Jun 07 12:23:28 2011 +0000 @@ -28,6 +28,16 @@ ******************************************************************************** +Version 1.3 (06/2011) - Basic T7 CAN support and faster T5 CAN bootloader + +Changes since Verion 1.1 + New T7 CAN menu provides some very basic T7 CAN DUMP and FLASH functions + T5 CAN uses Mybooty version 2 for 1 Mbps CAN speed + Get MyBooty version 2.x from forum.ecuproject.com + Does not work with version MyBooty 1.x + +******************************************************************************** + Version 1.2 (12/2010) - Only a very small update Fixed since Version 1.1: @@ -36,7 +46,7 @@ FLASH Trionic 7 ECUs using the BDM connection See the 'get_flash_id' function in bdmtrionic.cpp -Changes since Verion 1.2 +Changes since Verion 1.1 I have removed everything to do with the BDM DS connection I have changed the mbed pin number for the BDM DSO connection Now all BDM connections are part of the same MBED 'port' @@ -105,6 +115,7 @@ #include "bdm.h" #include "can232.h" #include "t5can.h" +#include "t7can.h" // constants #define CMD_BUF_LENGTH 32 ///< command buffer size @@ -201,6 +212,9 @@ case '5': t5_can(); return TERM_OK; + case '7': + t7_can(); + return TERM_OK; case 'h': case 'H': return TERM_OK; @@ -218,6 +232,7 @@ printf("b/B - Start BDM interface\r\n"); printf("o/O - Open Lawicel CAN232 type interface\r\n"); printf("5 - Start Trionic5 ECU CAN interface\r\n"); + printf("7 - Start Trionic7 ECU CAN interface\r\n"); printf("\r\n"); printf("h/H - show this help menu\r\n"); printf("\r\n");
--- a/t5can.cpp Tue Dec 14 21:50:35 2010 +0000 +++ b/t5can.cpp Tue Jun 07 12:23:28 2011 +0000 @@ -77,7 +77,7 @@ timer.start(); ret = execute_t5_cmd(); pc.putc(ret); - printf("Completed in %.1f seconds.\r\n", timer.read()); + printf("Completed in %.3f seconds.\r\n", timer.read()); // reset command buffer *cmd_buffer = '\0'; // light up LED @@ -152,7 +152,8 @@ // Send a Bootloader file to the T5 ECU case 'b': case 'B': - return t5_can_send_boot_loader() + return (t5_can_send_boot_loader() && can_set_speed(1000000)) +// return (t5_can_send_boot_loader() && can_set_speed(615000)) ? TERM_OK : TERM_ERR; // Get Checksum from ECU (Bootloader must be uploaded first) @@ -164,7 +165,7 @@ // Exit the BootLoader and restart the T5 ECU case 'q': case 'Q': - return t5_can_bootloader_reset() + return (t5_can_bootloader_reset() && can_set_speed(615000)) ? TERM_OK : TERM_ERR; // Erase the FLASH chips @@ -189,11 +190,13 @@ return TERM_ERR; if (!t5_can_send_boot_loader()) return TERM_ERR; + can_set_speed(1000000); if (!t5_can_get_start_and_chip_types(&flash_start)) { t5_can_bootloader_reset(); + can_set_speed(615000); return TERM_ERR; } - return (t5_can_dump_flash(flash_start) && t5_can_bootloader_reset()) + return (t5_can_dump_flash(flash_start) && t5_can_bootloader_reset() && can_set_speed(615000)) ? TERM_OK : TERM_ERR; // Send a FLASH update file to the T5 ECU @@ -204,17 +207,20 @@ case 'F': if (!t5_can_send_boot_loader()) return TERM_ERR; + can_set_speed(1000000); if (!t5_can_get_start_and_chip_types(&flash_start)) { t5_can_bootloader_reset(); + can_set_speed(615000); return TERM_ERR; } if (!t5_can_get_checksum()) led4 = 1; if (!t5_can_erase_flash()) { t5_can_bootloader_reset(); + can_set_speed(615000); return TERM_ERR; } - return (t5_can_send_flash_bin_update(flash_start) && t5_can_get_checksum() && t5_can_bootloader_reset()) + return (t5_can_send_flash_bin_update(flash_start) && t5_can_get_checksum() && t5_can_bootloader_reset() && can_set_speed(615000)) ? TERM_OK : TERM_ERR; // Send the C3 message - should get last used address 0x7FFFF
--- a/t5utils.cpp Tue Dec 14 21:50:35 2010 +0000 +++ b/t5utils.cpp Tue Jun 07 12:23:28 2011 +0000 @@ -308,12 +308,14 @@ // wait for the T5 to reply char T5RxMsg[8]; // if a message is not received, has the wrong type or indicates an error then there is a problem - if ((!can_wait_timeout(RESPID, T5RxMsg, 8, T5MESSAGETIMEOUT)) || (T5RxMsg[0] != T5TxMsg[0]) || (T5RxMsg[1] != 0x00)) - return FALSE; + return ((!can_wait_timeout(RESPID, T5RxMsg, 8, T5MESSAGETIMEOUT)) || (T5RxMsg[0] != T5TxMsg[0]) || (T5RxMsg[1] != 0x00)) + ? FALSE : TRUE; +// if ((!can_wait_timeout(RESPID, T5RxMsg, 8, T5MESSAGETIMEOUT)) || (T5RxMsg[0] != T5TxMsg[0]) || (T5RxMsg[1] != 0x00)) +// return FALSE; // wait for the T5 to reset // if a message is not received, has the wrong type or indicates an error then there is a problem - return (!can_wait_timeout(RSETID, T5RxMsg, 8, T5MESSAGETIMEOUT)) - ? FALSE : TRUE; +// return (!can_wait_timeout(RSETID, T5RxMsg, 8, T5MESSAGETIMEOUT)) +// ? FALSE : TRUE; } //-----------------------------------------------------------------------------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/t7can.cpp Tue Jun 07 12:23:28 2011 +0000 @@ -0,0 +1,213 @@ +/******************************************************************************* + +trionic7.cpp - CAN Bus functions for Just4Trionic by Just4pLeisure +(c) 2011 by Sophie Dexter + +This C++ module provides functions for reading and writing the FLASH chips and +SRAM in Trionic7 ECUs. (Writing the adaption data back to SRAM not done yet). + +Some functions need an additional 'bootloader' program to be sent to the T5 ECU +before they can be used. These functions are: Identifying the T5 ECU type and +FLASH chips, dumping the FLASH chips, erasing the FLASH chips, writing to the +FLASH chips and calculating the FLASH chips' checksum. + +My version of the bootloader, BOOTY.S19, includes some features not in other +bootloaders; identifying the ECU and FLASH chip types, a 'safer' way of dumping +the FLASH chips and the ability to program AMD 29F010 type FLASH chips + +******************************************************************************** + +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 "t7can.h" + +// constants +#define CMD_BUF_LENGTH 32 ///< command buffer size + +// static variables +static char cmd_buffer[CMD_BUF_LENGTH]; ///< command string buffer + +//static uint32_t cmd_addr; ///< address (optional) +//static uint32_t cmd_value; ///< value (optional) +//static uint32_t cmd_result; ///< result + +//static uint32_t flash_start = 0; + +// private functions +uint8_t execute_t7_cmd(); +void t7_can_show_help(); +void t7_can_show_full_help(); + +void t7_can() { + // Start the CAN bus system + // Note that at the moment this is only for T5 ECUs at 615 kbits + can_open(); + can_set_speed(500000); + + t7_can_show_help(); + + if (t7_initialise()) + printf("Trionic 7 Connection OK\r\n"); + else + printf("Trionic 7 Connection Failed\r\n"); +// t7_authenticate(); + if (t7_authenticate()) + printf("Security Key Accepted\r\n"); + else + printf("Security Key Failed\r\n"); + + // main loop + *cmd_buffer = '\0'; + char ret; + char rx_char; + while (true) { + // read chars from USB + // send received messages to the pc over USB connection + // This function displays any CAN messages that are 'missed' by the other functions + // Can messages might be 'missed' because they are received after a 'timeout' period + // or because they weren't expected, e.g. if the T5 ECU resets for some reason +// t7_show_can_message(); + silent_can_message(); + if (pc.readable()) { + // turn Error LED off for next command + led4 = 0; + rx_char = pc.getc(); + switch (rx_char) { + // 'ESC' key to go back to mbed Just4Trionic 'home' menu + case '\e': + can_close(); + return; + // end-of-command reached + case TERM_OK : + // execute command and return flag via USB + timer.reset(); + timer.start(); + ret = execute_t7_cmd(); + pc.putc(ret); + printf("Completed in %.3f seconds.\r\n", timer.read()); + // reset command buffer + *cmd_buffer = '\0'; + // light up LED + // ret == TERM_OK ? led_on(LED_ACT) : led_on(LED_ERR); + ret == TERM_OK ? led3 = 1 : led4 = 1; + break; + // another command char + default: + // store in buffer if space permits + if (StrLen(cmd_buffer) < CMD_BUF_LENGTH - 1) { + StrAddc(cmd_buffer, rx_char); + } + break; + } + } + } +} + +//----------------------------------------------------------------------------- +/** + Executes a command and returns result flag (does not transmit the flag + itself). + + @return command flag (success / failure) +*/ +uint8_t execute_t7_cmd() { + + +// uint8_t cmd_length = strlen(cmd_buffer); + // command groups + switch (*cmd_buffer) { +// CHECK_ARGLENGTH(0); + // Get the Symbol Table + case 'i' : + case 'I' : + return t7_initialise() + ? TERM_OK : TERM_ERR; + case 'a' : + case 'A' : + return t7_authenticate() + ? TERM_OK : TERM_ERR; + + // Erase the FLASH chips + case 'e': + case 'E': + return t7_erase() + ? TERM_OK : TERM_ERR; + // DUMP the T5 ECU BIN file stored in the FLASH chips + case 'd': + case 'D': + return t7_dump() + ? TERM_OK : TERM_ERR; + // Send a FLASH update file to the T5 ECU + case 'f': + case 'F': + return t7_flash() + ? TERM_OK : TERM_ERR; + + case '3': + + // Print help + case 'h': + t7_can_show_help(); + return TERM_OK; + case 'H': + t7_can_show_full_help(); + return TERM_OK; + default: + t7_can_show_help(); + break; + } + // unknown command + return TERM_ERR; +} + +// +// Trionic7ShowHelp +// +// Displays a list of things that can be done with the T5 ECU. +// +// inputs: none +// return: none +// +void t7_can_show_help() { + printf("Trionic 7 Command Menu\r\n"); + printf("======================\r\n"); + printf("D - Read and DUMP T7 FLASH BIN file\r\n"); + printf("F - FLASH the update file to the T7\r\n"); + printf("\r\n"); + printf("'ESC' - Return to Just4Trionic Main Menu\r\n"); + printf("\r\n"); + printf("h - Show this help menu\r\n"); + printf("\r\n"); + return; +} +// +// t7_can_show_full_help +// +// Displays a complete list of things that can be done with the T5 ECU. +// +// inputs: none +// return: none +// +void t7_can_show_full_help() { + printf("Trionic 7 Command Menu\r\n"); + printf("======================\r\n"); + printf("D - Read and DUMP T7 FLASH BIN file\r\n"); + printf("F - FLASH the update file to the T7\r\n"); + printf("\r\n"); + printf("\r\n"); + printf("i - Send initialisation message to T7\r\n"); + printf("a - Send Authentication key to T7\r\n"); + printf("d - Dump T7 Bin file\r\n"); + printf("\r\n"); + printf("'ESC' - Return to Just4Trionic Main Menu\r\n"); + printf("\r\n"); + printf("H - Show this help menu\r\n"); + printf("\r\n"); + return; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/t7can.h Tue Jun 07 12:23:28 2011 +0000 @@ -0,0 +1,33 @@ +/******************************************************************************* + +t5can.h - information and definitions needed for doing things with the T5 ECU +(c) 2010 by Sophie Dexter + +******************************************************************************** + +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. + +*******************************************************************************/ + +#ifndef __T7CAN_H__ +#define __T7CAN_H__ + +#include "mbed.h" +#include "CAN.h" + +#include "common.h" +#include "strings.h" +#include "t7utils.h" +#include "srecutils.h" + + +extern void t7_can(); + +void t7_can_show_help(); +void t7_can_show_full_help(); +uint8_t execute_t7_cmd(); + + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/t7utils.cpp Tue Jun 07 12:23:28 2011 +0000 @@ -0,0 +1,580 @@ +/******************************************************************************* + +t7utils.cpp +(c) 2011 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(" %% 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() { + 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(" %% 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"); + 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"); + 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); + 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; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/t7utils.h Tue Jun 07 12:23:28 2011 +0000 @@ -0,0 +1,121 @@ + +// t5utils.h - information and definitions needed for communicating with the T5 ECU + +// (C) 2011, Sophie Dexter + +#ifndef __T7UTILS_H__ +#define __T7UTILS_H__ + +#include "mbed.h" + +#include "common.h" +#include "canutils.h" + +#define T7CMNDID 0x220 +#define T7RESPID 0x238 +#define T7SEC_ID 0x240 +#define T7SEC_RX 0x258 +#define T7ACK_ID 0x266 + +// initialise T7 + +#define T7INITMSG {0x3F,0x81,0x00,0x11,0x02,0x40,0x00,0x00} + +// authenticate with T7 + +#define T7SEC_MSG {0x40,0xA1,0x02,0x27,0x05,0x00,0x00,0x00} +#define T7KEY_MSG {0x40,0xA1,0x04,0x27,0x06,0x00,0x00,0x00} + +#define T7ACK_MSG {0x40,0xA1,0x3F,0x00,0x00,0x00,0x00,0x00} + +// read_trionic7 + +#define T7DMP_END {0x40,0xA1,0x01,0x82,0x00,0x00,0x00,0x00} +//#define T7DMPJP1A {0x41,0xA1,0x08,0x2C,0xF0,0x03,0x00,0xEF} // 0x000000 length=0xEF +#define T7DMPJP1A {0x41,0xA1,0x08,0x2C,0xF0,0x03,0x00,0x80} // 0x000000 length=0x80 (128 bytes) +#define T7DMPJP1B {0x00,0xA1,0x00,0x00,0x00,0x00,0x00,0x00} +#define T7DMPPOST {0x40,0xA1,0x01,0x3E,0x00,0x00,0x00,0x00} +#define T7DMPDATA {0x40,0xA1,0x02,0x21,0xF0,0x00,0x00,0x00} +#define T7DMP_ACK {0x40,0xA1,0x20,0x00,0x00,0x00,0x00,0x00} + +// flash_trionic7 + +#define T7FLAJP1A {0x41,0xA1,0x08,0x34,0x00,0x00,0x00,0x00} // Start = 0x000000 +#define T7FLAJP1B {0x00,0xA1,0x08,0x00,0x00,0x00,0x00,0x00} // Length = 0x080000 +#define T7FLA_END {0x40,0xA1,0x01,0x37,0x00,0x00,0x00,0x00} +#define T7FLAEXIT {0x40,0xA1,0x02,0x31,0x54,0x00,0x00,0x00} +#define T7FLA_ACK {0x40,0xA1,0x3F,0x00,0x00,0x00,0x00,0x00} // 266h + + +#define T7MESSAGETIMEOUT 50 // 50 milliseconds (0.05 of a second) - Seems to be plenty of time to wait for messages on the CAN bus +#define T7LONGERTIMEOUT 500 // 500 milliseconds (0.5 of a second) - Some messages seem to need longer +#define T7CHECKSUMTIMEOUT 2000 // 2 seconds (2,000 milliseconds) - Usually takes less than a second so allowing 2 is plenty +#define T7ERASETIMEOUT 40000 // 40 seconds (60,000 milliseconds) - Usually takes less than 20 seconds so allowing 40 is plenty + +extern bool t7_initialise(); +extern bool t7_authenticate(); +extern bool t7_dump(); +extern bool t7_flash(); +extern bool t7_erase(); +/* global constants */ +//#define init_msg { 0x3F, 0x81, 0x00, 0x11, 0x02, 0x40, 0x00, 0x00 } + +// ask_header_trionic7 + +//#define query { 0x40, 0xA1, 0x02, 0x1A, 0x00, 0x00, 0x00, 0x00 } +//#define ack { 0x40, 0xA1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00 } + +// ask_header2_trionic7 + +//#define query { 0x40, 0xA1, 0x02, 0x1A, 0x00, 0x00, 0x00, 0x00 } +//#define ack { 0x40, 0xA1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00 } + + +// authenticate_trionic7 + +#define security_msg { 0x40, 0xA1, 0x02, 0x27, 0x05, 0x00, 0x00, 0x00 } +#define security_msg_reply { 0x40, 0xA1, 0x04, 0x27, 0x06, 0x00, 0x00, 0x00 } +#define ack { 0x40, 0xA1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00 } + + +// erase_trionic7 + +//#define erase_msg1 { 0x40, 0xA1, 0x02, 0x31, 0x52, 0x00, 0x00, 0x00 } +//#define erase_msg2 { 0x40, 0xA1, 0x02, 0x31, 0x53, 0x00, 0x00, 0x00 } +//#define confirm_msg { 0x40, 0xA1, 0x01, 0x3E, 0x00, 0x00, 0x00, 0x00 } + + +// program_trionic7 + +//#define jump_msg1a { 0x41, 0xA1, 0x08, 0x34, 0x00, 0x00, 0x00, 0x00 } // 0x000000 length=0x07B000 +#define jump_msg1b { 0x00, 0xA1, 0x07, 0xB0, 0x00, 0x00, 0x00, 0x00 } +#define jump_msg2a { 0x41, 0xA1, 0x08, 0x34, 0x07, 0xFF, 0x00, 0x00 } // 0x07FF00 length=0x000100 +#define jump_msg2b { 0x00, 0xA1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } +#define end_data_msg { 0x40, 0xA1, 0x01, 0x37, 0x00, 0x00, 0x00, 0x00 } +#define exit_diag_msg { 0x40, 0xA1, 0x02, 0x31, 0x54, 0x00, 0x00, 0x00 } +#define req_diag_result_msg { 0x3F, 0x81, 0x01, 0x33, 0x02, 0x40, 0x00, 0x00 } // 220h +#define ack { 0x40, 0xA1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00 } // 266h + +// program_trionic7_tis + +//#define jump_msg1a { 0x41, 0xA1, 0x08, 0x34, 0x00, 0x00, 0x00, 0x00 } // 0x000000 length=0x070000 +//#define jump_msg1b { 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 } +//#define jump_msg2a { 0x41, 0xA1, 0x08, 0x34, 0x07, 0xFF, 0x00, 0x00 } // 0x07FF00 length=0x000100 +//#define jump_msg2b { 0x00, 0xA1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } +//#define end_data_msg { 0x40, 0xA1, 0x01, 0x37, 0x00, 0x00, 0x00, 0x00 } +//#define exit_diag_msg { 0x40, 0xA1, 0x02, 0x31, 0x54, 0x00, 0x00, 0x00 } +//#define req_diag_result_msg { 0x3F, 0x81, 0x01, 0x33, 0x02, 0x40, 0x00, 0x00 } // 220h +//#define ack { 0x40, 0xA1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00 } // 266h + + +// verify_trionic7 +//#define init_msg { 0x20, 0x81, 0x00, 0x11, 0x02, 0x42, 0x00, 0x00 } +//#define end_data_msg { 0x40, 0xA1, 0x01, 0x82, 0x00, 0x00, 0x00, 0x00 } +//#define jump_msg1a { 0x41, 0xA1, 0x08, 0x2C, 0xF0, 0x03, 0x00, 0xEF } // 0x000000 length=0xEF +//#define jump_msg1b { 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +//#define post_jump_msg { 0x40, 0xA1, 0x01, 0x3E, 0x00, 0x00, 0x00, 0x00 } +//#define data_msg { 0x40, 0xA1, 0x02, 0x21, 0xF0, 0x00, 0x00, 0x00 } +//#define ack { 0x40, 0xA1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00 } + + +#endif \ No newline at end of file