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:
- 4:682d96ff6d79
- Child:
- 5:1775b4b13232
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/t8utils.cpp Wed Sep 11 11:55:51 2013 +0000
@@ -0,0 +1,513 @@
+/*******************************************************************************
+
+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 "t8utils.h"
+
+Timer TesterPresent;
+
+
+//
+// t8_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 t8_initialise()
+{
+ return TRUE;
+}
+
+bool t8_show_VIN()
+{
+ uint16_t i;
+ char T8TxFlo[] = T8FLOCTL;
+ char T8TxMsg[] = T8REQVIN;
+ char T8RxMsg[8];
+ printf("Requesting VIN from T8...\r\n");
+ // Send "Request VIN" to Trionic8
+ if (!can_send_timeout (T8TSTRID, T8TxMsg, 8, T8MESSAGETIMEOUT))
+ return FALSE;
+ // wait for the T8 to reply
+ // Read "Seed"
+ // if a message is not received id return false
+ if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
+ return FALSE;
+ //* DEBUG info...
+ for (i = 0; i < 8; i++ ) printf("0x%02X ", T8RxMsg[i] );
+ printf("\r\n");
+ for (i = 5; i < 8; i++ ) printf("%c", T8RxMsg[i] );
+ printf("\r\n");
+ // Send Trionic8 a "Flow Control Message to get the rest of the VIN
+ if (!can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT))
+ return FALSE;
+ if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
+ return FALSE;
+ //* DEBUG info...
+ for (i = 0; i < 8; i++ ) printf("0x%02X ", T8RxMsg[i] );
+ printf("\r\n");
+ for (i = 1; i < 8; i++ ) printf("%c", T8RxMsg[i] );
+ printf("\r\n");
+ if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
+ return FALSE;
+ //* DEBUG info...
+ for (i = 0; i < 8; i++ ) printf("0x%02X ", T8RxMsg[i] );
+ printf("\r\n");
+ for (i = 1; i < 8; i++ ) printf("%c", T8RxMsg[i] );
+ printf("\r\n");
+ //*/
+ return TRUE;
+}
+
+bool t8_write_VIN()
+{
+
+ char SetVin10[] = {0x10,0x13,0x3B,0x90,0x59,0x53,0x33,0x46};
+ char SetVin21[] = {0x21,0x46,0x34,0x35,0x53,0x38,0x33,0x31};
+// char SetVin22[] = {0x22,0x30,0x30,0x32,0x33,0x34,0x30,0xaa}; // Original
+ char SetVin22[] = {0x22,0x30,0x30,0x34,0x33,0x32,0x31,0x00};
+ char T8RxMsg[8];
+ char k = 0;
+
+// GMLANTesterPresentT8();
+// wait_ms(2000);
+//
+// printf("Requesting Security Access\r\n");
+// if (!t8_authenticate(0x01)) {
+// printf("Unable to get Security Access\r\n");
+// return FALSE;
+// }
+// printf("Security Access Granted\r\n");
+//
+// GMLANTesterPresentT8();
+// wait_ms(2000);
+//
+// GMLANTesterPresentT8();
+// wait_ms(2000);
+//
+ if (!can_send_timeout (T8TSTRID, SetVin10, 8, T8MESSAGETIMEOUT)) {
+ printf("Unable to write VIN\r\n");
+ return FALSE;
+ }
+ for (k = 0; k < 8; k++ ) printf("0x%02X ", SetVin10[k] );
+ printf("\r\n");
+ if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
+ return FALSE;
+ for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] );
+ printf("\r\n");
+// wait_ms(100);
+ if (!can_send_timeout (T8TSTRID, SetVin21, 8, T8MESSAGETIMEOUT)) {
+ printf("Unable to write VIN\r\n");
+ return FALSE;
+ }
+ for (k = 0; k < 8; k++ ) printf("0x%02X ", SetVin21[k] );
+ printf("\r\n");
+// wait_ms(100);
+ if (!can_send_timeout (T8TSTRID, SetVin22, 8, T8MESSAGETIMEOUT)) {
+ printf("Unable to write VIN\r\n");
+ return FALSE;
+ }
+ for (k = 0; k < 8; k++ ) printf("0x%02X ", SetVin22[k] );
+ printf("\r\n");
+ if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
+ return FALSE;
+ for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] );
+ printf("\r\n");
+ return TRUE;
+// GMLANTesterPresentT8();
+// wait_ms(2000);
+//
+}
+
+//
+// t8_authenticate
+//
+// sends an authentication message to the T7 ECU
+// but doesn't display anything.
+//
+// inputs: none
+// return: bool TRUE if there was a message, FALSE if no message.
+//
+
+bool t8_authenticate(char level)
+{
+ uint16_t seed, key;
+ if (!GMLANSecurityAccessRequest(level, seed)) {
+ 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;
+ }
+ key = (seed >> 5) | (seed << 11);
+ key += 0xB988;
+ if (level == 0xFD) {
+ key /= 3;
+ key ^= 0x8749;
+ key += 0x0ACF;
+ key ^= 0x81BF;
+ } else if (level == 0xFB) {
+ key ^= 0x8749;
+ key += 0x06D3;
+ key ^= 0xCFDF;
+ }
+ /* CIM KEY CALCULATION
+ uint16_t key = (seed + 0x9130);
+ key = (key >> 8) | (key << 8);
+ key -= 0x3FC7;
+ */
+ if (!GMLANSecurityAccessSendKey(level, key)) {
+ printf("Unable to send KEY value for security access\r\n");
+ return FALSE;
+ }
+ printf("Key Accepted\r\n");
+ return TRUE;
+}
+
+
+
+//
+// t8_dump
+//
+// dumps the T8 BIN File
+// but doesn't displays anything.
+//
+// inputs: none
+// return: bool TRUE if there was a message, FALSE if no message.
+//
+
+bool t8_dump()
+{
+ uint16_t i = 0, k = 0;
+ char T8TxMsg[8];
+ char T8RxMsg[8];
+
+ timer.reset();
+ timer.start();
+ printf("Creating FLASH dump file...\r\n");
+
+//
+ GMLANTesterPresentT8();
+//
+ if (!GMLANprogrammingSetupProcess())
+ return FALSE;
+//
+ wait_ms(500);
+ printf("Requesting Security Access\r\n");
+ if (!t8_authenticate(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))
+ 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");
+ 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;
+ }
+ printf(" 0.00 %% complete.\r");
+ TesterPresent.start();
+ while (StartAddress < 0x100000) { // 0x100000
+ T8TxMsg[0] = 0x06;
+ T8TxMsg[1] = 0x21;
+ T8TxMsg[2] = 0x80; // Blocksize
+ T8TxMsg[3] = (char) (StartAddress >> 24);
+ T8TxMsg[4] = (char) (StartAddress >> 16);
+ T8TxMsg[5] = (char) (StartAddress >> 8);
+ T8TxMsg[6] = (char) (StartAddress);
+ T8TxMsg[7] = 0xaa;
+#ifdef DEBUG
+ printf("block %#.3f\r\n",timer.read());
+#endif
+ 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;
+#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;
+ for (k = 4; k < 8; k++ ) file_buffer[txpnt++] = T8RxMsg[k];
+
+ uint8_t DataFrames = 0x12;
+ iFrameNumber = 0x21;
+ char T8TxFlo[] = T8FLOCTL;
+#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];
+ }
+ fwrite((file_buffer), 1, 0x80, fp);
+ if (ferror (fp)) {
+ fclose (fp);
+ 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) );
+ if (TesterPresent.read_ms() > 2000) {
+ GMLANTesterPresentT8();
+ TesterPresent.reset();
+ ACTIVITYLEDON;
+ }
+ }
+
+ printf("%6.2f\r\n", (float)100 );
+ timer.stop();
+ printf("SUCCESS! Getting the FLASH dump took %#.1f seconds.\r\n",timer.read());
+ fclose(fp);
+ 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;
+
+ timer.reset();
+ timer.start();
+ printf("FLASHing T8 BIN file...\r\n");
+
+//
+ GMLANTesterPresentT8();
+//
+ if (!GMLANprogrammingSetupProcess())
+ return FALSE;
+//
+ wait_ms(500);
+ printf("Requesting Security Access\r\n");
+ if (!t8_authenticate(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))
+ 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;
+ 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
+ // 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
+ uint32_t stack_long = 0;
+ if (!fread(&stack_long,4,1,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)) 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(GMLANRequestDownloadModeEncrypted)) {
+ printf("Unable to erase the FLASH chip!\r\n");
+ return FALSE;
+ }
+// Now send the BIN file
+ 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;
+ }
+ }
+ // Send the block of data
+ if (!GMLANDataTransferFirstFrame(0xE6, GMLANDOWNLOAD, StartAddress)) {
+ fclose(fp);
+ printf("Unable 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++];
+#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)) {
+ fclose(fp);
+ printf("Unable 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;
+ }
+ 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");
+ fclose(fp);
+ return FALSE;
+ }
+ if (TesterPresent.read_ms() > 2000) {
+ GMLANTesterPresentT8();
+ TesterPresent.reset();
+ ACTIVITYLEDON;
+ }
+ 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()) {
+ 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;
+}