Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Committer:
Just4pLeisure
Date:
Sat Apr 25 17:07:08 2015 +0000
Revision:
5:1775b4b13232
Parent:
4:682d96ff6d79
Child:
6:2fbcbebed28c
Version 1.5 Is a significant milestone.; ; Supports BDM and CAN read and write of T5.x, T7 and T8 ECU's plus T8 recovery.; A Target Resident Driver for BDM gives a big speed boost.; Supports many alternative replacement FLASH chips for T5.x ECU's;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Just4pLeisure 4:682d96ff6d79 1 /*******************************************************************************
Just4pLeisure 4:682d96ff6d79 2
Just4pLeisure 4:682d96ff6d79 3 t7utils.cpp
Just4pLeisure 4:682d96ff6d79 4 (c) 2011, 2012 by Sophie Dexter
Just4pLeisure 4:682d96ff6d79 5 portions (c) Tomi Liljemark (firstname.surname@gmail.com)
Just4pLeisure 4:682d96ff6d79 6
Just4pLeisure 4:682d96ff6d79 7 This C++ module provides functions for communicating simple messages to and from
Just4pLeisure 4:682d96ff6d79 8 the T7 ECU
Just4pLeisure 4:682d96ff6d79 9
Just4pLeisure 4:682d96ff6d79 10 ********************************************************************************
Just4pLeisure 4:682d96ff6d79 11
Just4pLeisure 4:682d96ff6d79 12 WARNING: Use at your own risk, sadly this software comes with no guarantees.
Just4pLeisure 4:682d96ff6d79 13 This software is provided 'free' and in good faith, but the author does not
Just4pLeisure 4:682d96ff6d79 14 accept liability for any damage arising from its use.
Just4pLeisure 4:682d96ff6d79 15
Just4pLeisure 4:682d96ff6d79 16 *******************************************************************************/
Just4pLeisure 4:682d96ff6d79 17
Just4pLeisure 4:682d96ff6d79 18 #include "t8utils.h"
Just4pLeisure 4:682d96ff6d79 19
Just4pLeisure 4:682d96ff6d79 20 Timer TesterPresent;
Just4pLeisure 4:682d96ff6d79 21
Just4pLeisure 4:682d96ff6d79 22
Just4pLeisure 4:682d96ff6d79 23 //
Just4pLeisure 4:682d96ff6d79 24 // t8_initialise
Just4pLeisure 4:682d96ff6d79 25 //
Just4pLeisure 4:682d96ff6d79 26 // sends an initialisation message to the T7 ECU
Just4pLeisure 4:682d96ff6d79 27 // but doesn't displays anything.
Just4pLeisure 4:682d96ff6d79 28 //
Just4pLeisure 4:682d96ff6d79 29 // inputs: none
Just4pLeisure 4:682d96ff6d79 30 // return: bool TRUE if there was a message, FALSE if no message.
Just4pLeisure 4:682d96ff6d79 31 //
Just4pLeisure 4:682d96ff6d79 32
Just4pLeisure 4:682d96ff6d79 33
Just4pLeisure 4:682d96ff6d79 34 bool t8_initialise()
Just4pLeisure 4:682d96ff6d79 35 {
Just4pLeisure 4:682d96ff6d79 36 return TRUE;
Just4pLeisure 4:682d96ff6d79 37 }
Just4pLeisure 4:682d96ff6d79 38
Just4pLeisure 4:682d96ff6d79 39 bool t8_show_VIN()
Just4pLeisure 4:682d96ff6d79 40 {
Just4pLeisure 5:1775b4b13232 41 uint32_t i;
Just4pLeisure 4:682d96ff6d79 42 char T8TxFlo[] = T8FLOCTL;
Just4pLeisure 4:682d96ff6d79 43 char T8TxMsg[] = T8REQVIN;
Just4pLeisure 4:682d96ff6d79 44 char T8RxMsg[8];
Just4pLeisure 4:682d96ff6d79 45 printf("Requesting VIN from T8...\r\n");
Just4pLeisure 4:682d96ff6d79 46 // Send "Request VIN" to Trionic8
Just4pLeisure 4:682d96ff6d79 47 if (!can_send_timeout (T8TSTRID, T8TxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 48 return FALSE;
Just4pLeisure 4:682d96ff6d79 49 // wait for the T8 to reply
Just4pLeisure 4:682d96ff6d79 50 // Read "Seed"
Just4pLeisure 4:682d96ff6d79 51 // if a message is not received id return false
Just4pLeisure 4:682d96ff6d79 52 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 53 return FALSE;
Just4pLeisure 4:682d96ff6d79 54 //* DEBUG info...
Just4pLeisure 4:682d96ff6d79 55 for (i = 0; i < 8; i++ ) printf("0x%02X ", T8RxMsg[i] );
Just4pLeisure 4:682d96ff6d79 56 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 57 for (i = 5; i < 8; i++ ) printf("%c", T8RxMsg[i] );
Just4pLeisure 4:682d96ff6d79 58 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 59 // Send Trionic8 a "Flow Control Message to get the rest of the VIN
Just4pLeisure 4:682d96ff6d79 60 if (!can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 61 return FALSE;
Just4pLeisure 4:682d96ff6d79 62 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 63 return FALSE;
Just4pLeisure 4:682d96ff6d79 64 //* DEBUG info...
Just4pLeisure 4:682d96ff6d79 65 for (i = 0; i < 8; i++ ) printf("0x%02X ", T8RxMsg[i] );
Just4pLeisure 4:682d96ff6d79 66 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 67 for (i = 1; i < 8; i++ ) printf("%c", T8RxMsg[i] );
Just4pLeisure 4:682d96ff6d79 68 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 69 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 70 return FALSE;
Just4pLeisure 4:682d96ff6d79 71 //* DEBUG info...
Just4pLeisure 4:682d96ff6d79 72 for (i = 0; i < 8; i++ ) printf("0x%02X ", T8RxMsg[i] );
Just4pLeisure 4:682d96ff6d79 73 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 74 for (i = 1; i < 8; i++ ) printf("%c", T8RxMsg[i] );
Just4pLeisure 4:682d96ff6d79 75 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 76 //*/
Just4pLeisure 4:682d96ff6d79 77 return TRUE;
Just4pLeisure 4:682d96ff6d79 78 }
Just4pLeisure 4:682d96ff6d79 79
Just4pLeisure 4:682d96ff6d79 80 bool t8_write_VIN()
Just4pLeisure 4:682d96ff6d79 81 {
Just4pLeisure 4:682d96ff6d79 82
Just4pLeisure 4:682d96ff6d79 83 char SetVin10[] = {0x10,0x13,0x3B,0x90,0x59,0x53,0x33,0x46};
Just4pLeisure 4:682d96ff6d79 84 char SetVin21[] = {0x21,0x46,0x34,0x35,0x53,0x38,0x33,0x31};
Just4pLeisure 4:682d96ff6d79 85 // char SetVin22[] = {0x22,0x30,0x30,0x32,0x33,0x34,0x30,0xaa}; // Original
Just4pLeisure 4:682d96ff6d79 86 char SetVin22[] = {0x22,0x30,0x30,0x34,0x33,0x32,0x31,0x00};
Just4pLeisure 4:682d96ff6d79 87 char T8RxMsg[8];
Just4pLeisure 4:682d96ff6d79 88 char k = 0;
Just4pLeisure 4:682d96ff6d79 89
Just4pLeisure 5:1775b4b13232 90 // GMLANTesterPresent(T8REQID, T8RESPID);
Just4pLeisure 4:682d96ff6d79 91 // wait_ms(2000);
Just4pLeisure 4:682d96ff6d79 92 //
Just4pLeisure 4:682d96ff6d79 93 // printf("Requesting Security Access\r\n");
Just4pLeisure 4:682d96ff6d79 94 // if (!t8_authenticate(0x01)) {
Just4pLeisure 4:682d96ff6d79 95 // printf("Unable to get Security Access\r\n");
Just4pLeisure 4:682d96ff6d79 96 // return FALSE;
Just4pLeisure 4:682d96ff6d79 97 // }
Just4pLeisure 4:682d96ff6d79 98 // printf("Security Access Granted\r\n");
Just4pLeisure 4:682d96ff6d79 99 //
Just4pLeisure 5:1775b4b13232 100 // GMLANTesterPresent(T8REQID, T8RESPID);
Just4pLeisure 4:682d96ff6d79 101 // wait_ms(2000);
Just4pLeisure 4:682d96ff6d79 102 //
Just4pLeisure 5:1775b4b13232 103 // GMLANTesterPresent(T8REQID, T8RESPID);
Just4pLeisure 4:682d96ff6d79 104 // wait_ms(2000);
Just4pLeisure 4:682d96ff6d79 105 //
Just4pLeisure 4:682d96ff6d79 106 if (!can_send_timeout (T8TSTRID, SetVin10, 8, T8MESSAGETIMEOUT)) {
Just4pLeisure 4:682d96ff6d79 107 printf("Unable to write VIN\r\n");
Just4pLeisure 4:682d96ff6d79 108 return FALSE;
Just4pLeisure 4:682d96ff6d79 109 }
Just4pLeisure 4:682d96ff6d79 110 for (k = 0; k < 8; k++ ) printf("0x%02X ", SetVin10[k] );
Just4pLeisure 4:682d96ff6d79 111 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 112 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 113 return FALSE;
Just4pLeisure 4:682d96ff6d79 114 for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] );
Just4pLeisure 4:682d96ff6d79 115 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 116 // wait_ms(100);
Just4pLeisure 4:682d96ff6d79 117 if (!can_send_timeout (T8TSTRID, SetVin21, 8, T8MESSAGETIMEOUT)) {
Just4pLeisure 4:682d96ff6d79 118 printf("Unable to write VIN\r\n");
Just4pLeisure 4:682d96ff6d79 119 return FALSE;
Just4pLeisure 4:682d96ff6d79 120 }
Just4pLeisure 4:682d96ff6d79 121 for (k = 0; k < 8; k++ ) printf("0x%02X ", SetVin21[k] );
Just4pLeisure 4:682d96ff6d79 122 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 123 // wait_ms(100);
Just4pLeisure 4:682d96ff6d79 124 if (!can_send_timeout (T8TSTRID, SetVin22, 8, T8MESSAGETIMEOUT)) {
Just4pLeisure 4:682d96ff6d79 125 printf("Unable to write VIN\r\n");
Just4pLeisure 4:682d96ff6d79 126 return FALSE;
Just4pLeisure 4:682d96ff6d79 127 }
Just4pLeisure 4:682d96ff6d79 128 for (k = 0; k < 8; k++ ) printf("0x%02X ", SetVin22[k] );
Just4pLeisure 4:682d96ff6d79 129 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 130 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 131 return FALSE;
Just4pLeisure 4:682d96ff6d79 132 for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] );
Just4pLeisure 4:682d96ff6d79 133 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 134 return TRUE;
Just4pLeisure 5:1775b4b13232 135 // GMLANTesterPresent(T8REQID, T8RESPID);
Just4pLeisure 4:682d96ff6d79 136 // wait_ms(2000);
Just4pLeisure 4:682d96ff6d79 137 //
Just4pLeisure 4:682d96ff6d79 138 }
Just4pLeisure 4:682d96ff6d79 139
Just4pLeisure 4:682d96ff6d79 140 //
Just4pLeisure 4:682d96ff6d79 141 // t8_authenticate
Just4pLeisure 4:682d96ff6d79 142 //
Just4pLeisure 4:682d96ff6d79 143 // sends an authentication message to the T7 ECU
Just4pLeisure 4:682d96ff6d79 144 // but doesn't display anything.
Just4pLeisure 4:682d96ff6d79 145 //
Just4pLeisure 4:682d96ff6d79 146 // inputs: none
Just4pLeisure 4:682d96ff6d79 147 // return: bool TRUE if there was a message, FALSE if no message.
Just4pLeisure 4:682d96ff6d79 148 //
Just4pLeisure 4:682d96ff6d79 149
Just4pLeisure 5:1775b4b13232 150 bool t8_authenticate(uint32_t ReqID, uint32_t RespID, char level)
Just4pLeisure 4:682d96ff6d79 151 {
Just4pLeisure 5:1775b4b13232 152 uint16_t i, seed, key;
Just4pLeisure 5:1775b4b13232 153 // if (!GMLANSecurityAccessRequest(ReqID, RespID, level, seed)) {
Just4pLeisure 5:1775b4b13232 154 // printf("Unable to request SEED value for security access\r\n");
Just4pLeisure 5:1775b4b13232 155 // return FALSE;
Just4pLeisure 5:1775b4b13232 156 // }
Just4pLeisure 5:1775b4b13232 157
Just4pLeisure 5:1775b4b13232 158 for (i=0; i < 20; i++) {
Just4pLeisure 5:1775b4b13232 159 if (GMLANSecurityAccessRequest(ReqID, RespID, level, seed))
Just4pLeisure 5:1775b4b13232 160 break;
Just4pLeisure 5:1775b4b13232 161 wait(1);
Just4pLeisure 5:1775b4b13232 162 GMLANTesterPresent(ReqID, RespID);
Just4pLeisure 5:1775b4b13232 163 }
Just4pLeisure 5:1775b4b13232 164 if (i == 20) {
Just4pLeisure 4:682d96ff6d79 165 printf("Unable to request SEED value for security access\r\n");
Just4pLeisure 4:682d96ff6d79 166 return FALSE;
Just4pLeisure 4:682d96ff6d79 167 }
Just4pLeisure 5:1775b4b13232 168
Just4pLeisure 4:682d96ff6d79 169 if ( seed == 0x0000 ) {
Just4pLeisure 4:682d96ff6d79 170 printf("T8 ECU is already unlocked\r\n");
Just4pLeisure 4:682d96ff6d79 171 return TRUE;
Just4pLeisure 4:682d96ff6d79 172 }
Just4pLeisure 4:682d96ff6d79 173 key = (seed >> 5) | (seed << 11);
Just4pLeisure 4:682d96ff6d79 174 key += 0xB988;
Just4pLeisure 4:682d96ff6d79 175 if (level == 0xFD) {
Just4pLeisure 4:682d96ff6d79 176 key /= 3;
Just4pLeisure 4:682d96ff6d79 177 key ^= 0x8749;
Just4pLeisure 4:682d96ff6d79 178 key += 0x0ACF;
Just4pLeisure 4:682d96ff6d79 179 key ^= 0x81BF;
Just4pLeisure 4:682d96ff6d79 180 } else if (level == 0xFB) {
Just4pLeisure 4:682d96ff6d79 181 key ^= 0x8749;
Just4pLeisure 4:682d96ff6d79 182 key += 0x06D3;
Just4pLeisure 4:682d96ff6d79 183 key ^= 0xCFDF;
Just4pLeisure 4:682d96ff6d79 184 }
Just4pLeisure 4:682d96ff6d79 185 /* CIM KEY CALCULATION
Just4pLeisure 4:682d96ff6d79 186 uint16_t key = (seed + 0x9130);
Just4pLeisure 4:682d96ff6d79 187 key = (key >> 8) | (key << 8);
Just4pLeisure 4:682d96ff6d79 188 key -= 0x3FC7;
Just4pLeisure 4:682d96ff6d79 189 */
Just4pLeisure 5:1775b4b13232 190 wait_ms(1);
Just4pLeisure 5:1775b4b13232 191 if (!GMLANSecurityAccessSendKey(ReqID, RespID, level, key)) {
Just4pLeisure 4:682d96ff6d79 192 printf("Unable to send KEY value for security access\r\n");
Just4pLeisure 4:682d96ff6d79 193 return FALSE;
Just4pLeisure 4:682d96ff6d79 194 }
Just4pLeisure 4:682d96ff6d79 195 printf("Key Accepted\r\n");
Just4pLeisure 5:1775b4b13232 196 wait_ms(500); // was 5
Just4pLeisure 4:682d96ff6d79 197 return TRUE;
Just4pLeisure 4:682d96ff6d79 198 }
Just4pLeisure 4:682d96ff6d79 199
Just4pLeisure 4:682d96ff6d79 200
Just4pLeisure 4:682d96ff6d79 201 //
Just4pLeisure 4:682d96ff6d79 202 // t8_dump
Just4pLeisure 4:682d96ff6d79 203 //
Just4pLeisure 4:682d96ff6d79 204 // dumps the T8 BIN File
Just4pLeisure 4:682d96ff6d79 205 // but doesn't displays anything.
Just4pLeisure 4:682d96ff6d79 206 //
Just4pLeisure 4:682d96ff6d79 207 // inputs: none
Just4pLeisure 4:682d96ff6d79 208 // return: bool TRUE if there was a message, FALSE if no message.
Just4pLeisure 4:682d96ff6d79 209 //
Just4pLeisure 4:682d96ff6d79 210
Just4pLeisure 4:682d96ff6d79 211 bool t8_dump()
Just4pLeisure 4:682d96ff6d79 212 {
Just4pLeisure 5:1775b4b13232 213 uint32_t i = 0, k = 0;
Just4pLeisure 4:682d96ff6d79 214 char T8TxMsg[8];
Just4pLeisure 4:682d96ff6d79 215 char T8RxMsg[8];
Just4pLeisure 4:682d96ff6d79 216
Just4pLeisure 4:682d96ff6d79 217 timer.reset();
Just4pLeisure 4:682d96ff6d79 218 timer.start();
Just4pLeisure 4:682d96ff6d79 219 printf("Creating FLASH dump file...\r\n");
Just4pLeisure 4:682d96ff6d79 220
Just4pLeisure 4:682d96ff6d79 221 //
Just4pLeisure 5:1775b4b13232 222 if (!GMLANprogrammingSetupProcess(T8REQID, T8RESPID))
Just4pLeisure 4:682d96ff6d79 223 return FALSE;
Just4pLeisure 4:682d96ff6d79 224 //
Just4pLeisure 4:682d96ff6d79 225 printf("Requesting Security Access\r\n");
Just4pLeisure 5:1775b4b13232 226 if (!t8_authenticate(T8REQID, T8RESPID, 0x01)) {
Just4pLeisure 4:682d96ff6d79 227 printf("Unable to get Security Access\r\n");
Just4pLeisure 4:682d96ff6d79 228 return FALSE;
Just4pLeisure 4:682d96ff6d79 229 }
Just4pLeisure 4:682d96ff6d79 230 printf("Security Access Granted\r\n");
Just4pLeisure 4:682d96ff6d79 231 //
Just4pLeisure 5:1775b4b13232 232 if(!GMLANprogrammingUtilityFileProcess(T8REQID, T8RESPID, T8BootloaderRead))
Just4pLeisure 4:682d96ff6d79 233 return FALSE;
Just4pLeisure 4:682d96ff6d79 234 //
Just4pLeisure 4:682d96ff6d79 235 //
Just4pLeisure 4:682d96ff6d79 236 printf("Downloading FLASH BIN file...\r\n");
Just4pLeisure 4:682d96ff6d79 237 printf("Creating FLASH dump file...\r\n");
Just4pLeisure 4:682d96ff6d79 238 FILE *fp = fopen("/local/original.bin", "w"); // Open "original.bin" on the local file system for writing
Just4pLeisure 4:682d96ff6d79 239 if (!fp) {
Just4pLeisure 4:682d96ff6d79 240 perror ("The following error occured");
Just4pLeisure 4:682d96ff6d79 241 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 242 }
Just4pLeisure 4:682d96ff6d79 243 printf(" 0.00 %% complete.\r");
Just4pLeisure 4:682d96ff6d79 244 TesterPresent.start();
Just4pLeisure 5:1775b4b13232 245
Just4pLeisure 5:1775b4b13232 246 // It is possible to save some time by only reading the program code and CAL data
Just4pLeisure 5:1775b4b13232 247 // This is just a rough calculation, and slight overestimate of the number of blocks of data needed to send the BIN file
Just4pLeisure 5:1775b4b13232 248 T8TxMsg[0] = 0x06;
Just4pLeisure 5:1775b4b13232 249 T8TxMsg[1] = 0x21;
Just4pLeisure 5:1775b4b13232 250 T8TxMsg[2] = 0x80; // Blocksize
Just4pLeisure 5:1775b4b13232 251 T8TxMsg[3] = 0x00; // This address (0x020140) points to the Header at the end of the BIN
Just4pLeisure 5:1775b4b13232 252 T8TxMsg[4] = 0x02;
Just4pLeisure 5:1775b4b13232 253 T8TxMsg[5] = 0x01;
Just4pLeisure 5:1775b4b13232 254 T8TxMsg[6] = 0x40;
Just4pLeisure 5:1775b4b13232 255 T8TxMsg[7] = 0xaa;
Just4pLeisure 5:1775b4b13232 256 if (!can_send_timeout (T8TSTRID, T8TxMsg, 7, T8MESSAGETIMEOUT)) {
Just4pLeisure 5:1775b4b13232 257 printf("Unable to download FLASH\r\n");
Just4pLeisure 5:1775b4b13232 258 return FALSE;
Just4pLeisure 5:1775b4b13232 259 }
Just4pLeisure 5:1775b4b13232 260 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 5:1775b4b13232 261 return FALSE;
Just4pLeisure 5:1775b4b13232 262 uint32_t EndAddress = (T8RxMsg[5] << 16) | (T8RxMsg[6] << 8) | T8RxMsg[7];
Just4pLeisure 5:1775b4b13232 263 EndAddress += 0x200; // Add some bytes for the Footer itself and to account for division rounded down later
Just4pLeisure 5:1775b4b13232 264 char T8TxFlo[] = T8FLOCTL;
Just4pLeisure 5:1775b4b13232 265 can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT);
Just4pLeisure 5:1775b4b13232 266 for (i = 0; i < 0x12; i++) {
Just4pLeisure 5:1775b4b13232 267 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 5:1775b4b13232 268 return FALSE;
Just4pLeisure 5:1775b4b13232 269 }
Just4pLeisure 5:1775b4b13232 270 printf("Reading your BIN file adjusted for footer = 0x%06X Bytes\r\n", EndAddress );
Just4pLeisure 5:1775b4b13232 271
Just4pLeisure 5:1775b4b13232 272 for ( uint32_t StartAddress = 0x0; StartAddress < EndAddress; StartAddress +=0x80 ) { // 0x100000
Just4pLeisure 4:682d96ff6d79 273 T8TxMsg[0] = 0x06;
Just4pLeisure 4:682d96ff6d79 274 T8TxMsg[1] = 0x21;
Just4pLeisure 4:682d96ff6d79 275 T8TxMsg[2] = 0x80; // Blocksize
Just4pLeisure 4:682d96ff6d79 276 T8TxMsg[3] = (char) (StartAddress >> 24);
Just4pLeisure 4:682d96ff6d79 277 T8TxMsg[4] = (char) (StartAddress >> 16);
Just4pLeisure 4:682d96ff6d79 278 T8TxMsg[5] = (char) (StartAddress >> 8);
Just4pLeisure 4:682d96ff6d79 279 T8TxMsg[6] = (char) (StartAddress);
Just4pLeisure 4:682d96ff6d79 280 T8TxMsg[7] = 0xaa;
Just4pLeisure 4:682d96ff6d79 281 #ifdef DEBUG
Just4pLeisure 4:682d96ff6d79 282 printf("block %#.3f\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 283 #endif
Just4pLeisure 4:682d96ff6d79 284 if (!can_send_timeout (T8TSTRID, T8TxMsg, 7, T8MESSAGETIMEOUT)) {
Just4pLeisure 4:682d96ff6d79 285 printf("Unable to download FLASH\r\n");
Just4pLeisure 4:682d96ff6d79 286 return FALSE;
Just4pLeisure 4:682d96ff6d79 287 }
Just4pLeisure 4:682d96ff6d79 288 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 289 return FALSE;
Just4pLeisure 4:682d96ff6d79 290 #ifdef DEBUG
Just4pLeisure 4:682d96ff6d79 291 printf("first %#.3f\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 292 #endif
Just4pLeisure 5:1775b4b13232 293 uint32_t txpnt = 0;
Just4pLeisure 4:682d96ff6d79 294 for (k = 4; k < 8; k++ ) file_buffer[txpnt++] = T8RxMsg[k];
Just4pLeisure 4:682d96ff6d79 295
Just4pLeisure 4:682d96ff6d79 296 uint8_t DataFrames = 0x12;
Just4pLeisure 5:1775b4b13232 297 char iFrameNumber = 0x21;
Just4pLeisure 4:682d96ff6d79 298 char T8TxFlo[] = T8FLOCTL;
Just4pLeisure 5:1775b4b13232 299 can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT);
Just4pLeisure 4:682d96ff6d79 300 #ifdef DEBUG
Just4pLeisure 4:682d96ff6d79 301 printf("flowCtrl %#.3f\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 302 #endif
Just4pLeisure 4:682d96ff6d79 303 for (i = 0; i < DataFrames; i++) {
Just4pLeisure 4:682d96ff6d79 304 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 305 return FALSE;
Just4pLeisure 4:682d96ff6d79 306 #ifdef DEBUG
Just4pLeisure 4:682d96ff6d79 307 printf("Consec %#.3f\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 308 #endif
Just4pLeisure 4:682d96ff6d79 309 iFrameNumber++;
Just4pLeisure 4:682d96ff6d79 310 for (k = 1; k < 8; k++ ) file_buffer[txpnt++] = T8RxMsg[k];
Just4pLeisure 4:682d96ff6d79 311 }
Just4pLeisure 4:682d96ff6d79 312 fwrite((file_buffer), 1, 0x80, fp);
Just4pLeisure 4:682d96ff6d79 313 if (ferror (fp)) {
Just4pLeisure 4:682d96ff6d79 314 fclose (fp);
Just4pLeisure 4:682d96ff6d79 315 printf ("Error writing to the FLASH BIN file.\r\n");
Just4pLeisure 4:682d96ff6d79 316 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 317 }
Just4pLeisure 5:1775b4b13232 318 printf("%6.2f\r", (100.0*(float)StartAddress)/(float)(EndAddress) );
Just4pLeisure 4:682d96ff6d79 319 if (TesterPresent.read_ms() > 2000) {
Just4pLeisure 5:1775b4b13232 320 GMLANTesterPresent(T8REQID, T8RESPID);
Just4pLeisure 4:682d96ff6d79 321 TesterPresent.reset();
Just4pLeisure 5:1775b4b13232 322 }
Just4pLeisure 5:1775b4b13232 323 }
Just4pLeisure 5:1775b4b13232 324
Just4pLeisure 5:1775b4b13232 325 for (uint32_t i = 0; i < 0x80; i++)
Just4pLeisure 5:1775b4b13232 326 file_buffer[i] = 0xFF;
Just4pLeisure 5:1775b4b13232 327 while ( ftell(fp) < 0x100000 ) {
Just4pLeisure 5:1775b4b13232 328 // for ( uint32_t StartAddress = EndAddress; StartAddress < 0x100000; StartAddress +=0x80 ) {
Just4pLeisure 5:1775b4b13232 329 fwrite((file_buffer), 1, 0x80, fp);
Just4pLeisure 5:1775b4b13232 330 if (ferror (fp)) {
Just4pLeisure 5:1775b4b13232 331 fclose (fp);
Just4pLeisure 5:1775b4b13232 332 printf ("Error writing to the FLASH BIN file.\r\n");
Just4pLeisure 5:1775b4b13232 333 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 334 }
Just4pLeisure 4:682d96ff6d79 335 }
Just4pLeisure 4:682d96ff6d79 336
Just4pLeisure 4:682d96ff6d79 337 printf("%6.2f\r\n", (float)100 );
Just4pLeisure 4:682d96ff6d79 338 timer.stop();
Just4pLeisure 4:682d96ff6d79 339 printf("SUCCESS! Getting the FLASH dump took %#.1f seconds.\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 340 fclose(fp);
Just4pLeisure 4:682d96ff6d79 341 return TRUE;
Just4pLeisure 4:682d96ff6d79 342 }
Just4pLeisure 4:682d96ff6d79 343
Just4pLeisure 4:682d96ff6d79 344
Just4pLeisure 4:682d96ff6d79 345 bool t8_flash()
Just4pLeisure 4:682d96ff6d79 346 {
Just4pLeisure 5:1775b4b13232 347 uint32_t i = 0, j = 0, k = 0;
Just4pLeisure 4:682d96ff6d79 348
Just4pLeisure 4:682d96ff6d79 349 timer.reset();
Just4pLeisure 4:682d96ff6d79 350 timer.start();
Just4pLeisure 4:682d96ff6d79 351 printf("FLASHing T8 BIN file...\r\n");
Just4pLeisure 4:682d96ff6d79 352
Just4pLeisure 4:682d96ff6d79 353 //
Just4pLeisure 5:1775b4b13232 354 if (!GMLANprogrammingSetupProcess(T8REQID, T8RESPID))
Just4pLeisure 4:682d96ff6d79 355 return FALSE;
Just4pLeisure 4:682d96ff6d79 356 //
Just4pLeisure 4:682d96ff6d79 357 printf("Requesting Security Access\r\n");
Just4pLeisure 5:1775b4b13232 358 if (!t8_authenticate(T8REQID, T8RESPID, 0x01)) {
Just4pLeisure 4:682d96ff6d79 359 printf("Unable to get Security Access\r\n");
Just4pLeisure 4:682d96ff6d79 360 return FALSE;
Just4pLeisure 4:682d96ff6d79 361 }
Just4pLeisure 4:682d96ff6d79 362 printf("Security Access Granted\r\n");
Just4pLeisure 4:682d96ff6d79 363 //
Just4pLeisure 5:1775b4b13232 364 // const uint8_t BootLoader[] = T8BootloaderProg;
Just4pLeisure 5:1775b4b13232 365 // if(!GMLANprogrammingUtilityFileProcess(T8REQID, T8RESPID, BootLoader))
Just4pLeisure 5:1775b4b13232 366 if(!GMLANprogrammingUtilityFileProcess(T8REQID, T8RESPID, T8BootLoaderWrite))
Just4pLeisure 4:682d96ff6d79 367 return FALSE;
Just4pLeisure 4:682d96ff6d79 368 //
Just4pLeisure 4:682d96ff6d79 369 // All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance)
Just4pLeisure 4:682d96ff6d79 370 uint32_t StartAddress = 0x020000;
Just4pLeisure 5:1775b4b13232 371 uint32_t txpnt = 0;
Just4pLeisure 4:682d96ff6d79 372 char iFrameNumber = 0x21;
Just4pLeisure 4:682d96ff6d79 373 char GMLANMsg[8];
Just4pLeisure 4:682d96ff6d79 374 char data2Send[0xE0];
Just4pLeisure 4:682d96ff6d79 375 //
Just4pLeisure 5:1775b4b13232 376 // fopen modified.bin here, check it is OK and work out how much data I need to send
Just4pLeisure 4:682d96ff6d79 377 // need lots of fcloses though
Just4pLeisure 4:682d96ff6d79 378 printf("Checking the FLASH BIN file...\r\n");
Just4pLeisure 5:1775b4b13232 379 FILE *fp = fopen("/local/modified.bin", "r"); // Open "modified.bin" on the local file system for reading
Just4pLeisure 4:682d96ff6d79 380 if (!fp) {
Just4pLeisure 5:1775b4b13232 381 printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");;
Just4pLeisure 4:682d96ff6d79 382 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 383 }
Just4pLeisure 4:682d96ff6d79 384 // obtain file size - it should match the size of the FLASH chips:
Just4pLeisure 4:682d96ff6d79 385 fseek (fp , 0 , SEEK_END);
Just4pLeisure 4:682d96ff6d79 386 uint32_t file_size = ftell (fp);
Just4pLeisure 4:682d96ff6d79 387 rewind (fp);
Just4pLeisure 4:682d96ff6d79 388
Just4pLeisure 4:682d96ff6d79 389 // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU
Just4pLeisure 4:682d96ff6d79 390 uint32_t stack_long = 0;
Just4pLeisure 5:1775b4b13232 391 if (!fread(&stack_long,4,1,fp)) {
Just4pLeisure 5:1775b4b13232 392 fclose(fp);
Just4pLeisure 5:1775b4b13232 393 return TERM_ERR;
Just4pLeisure 5:1775b4b13232 394 }
Just4pLeisure 4:682d96ff6d79 395 stack_long = (stack_long >> 24) | ((stack_long << 8) & 0x00FF0000) | ((stack_long >> 8) & 0x0000FF00) | (stack_long << 24);
Just4pLeisure 4:682d96ff6d79 396 //
Just4pLeisure 4:682d96ff6d79 397 if (file_size != T8FLASHSIZE || stack_long != T8POINTER) {
Just4pLeisure 4:682d96ff6d79 398 fclose(fp);
Just4pLeisure 4:682d96ff6d79 399 printf("The BIN file does not appear to be for a T8 ECU :-(\r\n");
Just4pLeisure 4:682d96ff6d79 400 printf("BIN file size: %#010x, FLASH chip size: %#010x, Pointer: %#010x.\r\n", file_size, T7FLASHSIZE, stack_long);
Just4pLeisure 4:682d96ff6d79 401 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 402 }
Just4pLeisure 4:682d96ff6d79 403 // It is possible to save some time by only sending the program code and CAL data
Just4pLeisure 4:682d96ff6d79 404 // This is just a rough calculation, and slight overestimate of the number of blocks of data needed to send the BIN file
Just4pLeisure 4:682d96ff6d79 405 uint32_t blocks2Send;
Just4pLeisure 4:682d96ff6d79 406 fseek(fp,0x020140,SEEK_SET);
Just4pLeisure 5:1775b4b13232 407 if (!fread(&blocks2Send,4,1,fp)) {
Just4pLeisure 5:1775b4b13232 408 fclose(fp);
Just4pLeisure 5:1775b4b13232 409 return TERM_ERR;
Just4pLeisure 5:1775b4b13232 410 }
Just4pLeisure 4:682d96ff6d79 411 blocks2Send = (blocks2Send >> 24) | ((blocks2Send << 8) & 0x00FF0000) | ((blocks2Send >> 8) & 0x0000FF00) | (blocks2Send << 24);
Just4pLeisure 4:682d96ff6d79 412 printf("Start address of BIN file's Footer area = 0x%06X\r\n", blocks2Send );
Just4pLeisure 4:682d96ff6d79 413 blocks2Send += 0x200; // Add some bytes for the Footer itself and to account for division rounded down later
Just4pLeisure 4:682d96ff6d79 414 blocks2Send -= 0x020000; // Remove 0x020000 because we don't send the bootblock and adaptation blocks
Just4pLeisure 4:682d96ff6d79 415 printf("Amount of data to send BIN file adjusted for footer = 0x%06X Bytes\r\n", blocks2Send );
Just4pLeisure 4:682d96ff6d79 416 blocks2Send /= 0xE0;
Just4pLeisure 4:682d96ff6d79 417 printf("Number of Blocks of 0xE0 Bytes needed to send BIN file = 0x%04X\r\n", blocks2Send );
Just4pLeisure 4:682d96ff6d79 418 // Move BIN file pointer to start of data
Just4pLeisure 4:682d96ff6d79 419 fseek (fp , 0x020000 , SEEK_SET);
Just4pLeisure 4:682d96ff6d79 420 // Erase the FLASH
Just4pLeisure 4:682d96ff6d79 421 printf("Waiting for FLASH to be Erased\r\n");
Just4pLeisure 5:1775b4b13232 422 if (!GMLANRequestDownload(T8REQID, T8RESPID, GMLANRequestDownloadModeEncrypted)) {
Just4pLeisure 5:1775b4b13232 423 fclose(fp);
Just4pLeisure 4:682d96ff6d79 424 printf("Unable to erase the FLASH chip!\r\n");
Just4pLeisure 4:682d96ff6d79 425 return FALSE;
Just4pLeisure 4:682d96ff6d79 426 }
Just4pLeisure 4:682d96ff6d79 427 // Now send the BIN file
Just4pLeisure 5:1775b4b13232 428 GMLANTesterPresent(T8REQID, T8RESPID);
Just4pLeisure 4:682d96ff6d79 429 TesterPresent.start();
Just4pLeisure 4:682d96ff6d79 430 printf("Sending FLASH BIN file\r\n");
Just4pLeisure 4:682d96ff6d79 431 printf(" 0.00 %% complete.\r");
Just4pLeisure 4:682d96ff6d79 432 for (i=0; i<blocks2Send; i++) {
Just4pLeisure 4:682d96ff6d79 433 // get a block of 0xE0 bytes in an array called data2Send
Just4pLeisure 5:1775b4b13232 434 if (!fread(data2Send,0xE0,1,fp)) {
Just4pLeisure 5:1775b4b13232 435 fclose(fp);
Just4pLeisure 5:1775b4b13232 436 printf("\r\nError reading the BIN file MODIFIED.BIN\r\n");
Just4pLeisure 5:1775b4b13232 437 return FALSE;
Just4pLeisure 4:682d96ff6d79 438 }
Just4pLeisure 5:1775b4b13232 439 // encrypt data2Send array by XORing with 6 different values in a ring (modulo function)
Just4pLeisure 5:1775b4b13232 440 char key[6] = { 0x39, 0x68, 0x77, 0x6D, 0x47, 0x39 };
Just4pLeisure 5:1775b4b13232 441 for ( j = 0; j < 0xE0; j++ )
Just4pLeisure 5:1775b4b13232 442 data2Send[j] ^= key[(((0xE0*i)+j) % 6)];
Just4pLeisure 4:682d96ff6d79 443 // Send the block of data
Just4pLeisure 5:1775b4b13232 444 if (!GMLANDataTransferFirstFrame(T8REQID, T8RESPID, 0xE6, GMLANDOWNLOAD, StartAddress)) {
Just4pLeisure 4:682d96ff6d79 445 fclose(fp);
Just4pLeisure 5:1775b4b13232 446 printf("\r\nUnable to start BIN File Upload\r\n");
Just4pLeisure 4:682d96ff6d79 447 return FALSE;
Just4pLeisure 4:682d96ff6d79 448 }
Just4pLeisure 4:682d96ff6d79 449 // Send 0x20 messages of 0x07 bytes each (0x20 * 0x07 = 0xE0)
Just4pLeisure 4:682d96ff6d79 450 txpnt = 0;
Just4pLeisure 4:682d96ff6d79 451 iFrameNumber = 0x21;
Just4pLeisure 4:682d96ff6d79 452 for (j=0; j < 0x20; j++) {
Just4pLeisure 4:682d96ff6d79 453 GMLANMsg[0] = iFrameNumber;
Just4pLeisure 4:682d96ff6d79 454 for (k=1; k<8; k++)
Just4pLeisure 4:682d96ff6d79 455 GMLANMsg[k] = data2Send[txpnt++];
Just4pLeisure 5:1775b4b13232 456 if (!can_send_timeout(T8REQID, GMLANMsg, 8, GMLANPTCT)) {
Just4pLeisure 4:682d96ff6d79 457 fclose(fp);
Just4pLeisure 5:1775b4b13232 458 printf("\r\nUnable to send BIN File\r\n");
Just4pLeisure 4:682d96ff6d79 459 return FALSE;
Just4pLeisure 4:682d96ff6d79 460 }
Just4pLeisure 4:682d96ff6d79 461 ++iFrameNumber &= 0x2F;
Just4pLeisure 5:1775b4b13232 462 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??? )
Just4pLeisure 4:682d96ff6d79 463 }
Just4pLeisure 5:1775b4b13232 464 if (!GMLANDataTransferBlockAcknowledge(T8RESPID)) {
Just4pLeisure 4:682d96ff6d79 465 fclose(fp);
Just4pLeisure 4:682d96ff6d79 466 return FALSE;
Just4pLeisure 4:682d96ff6d79 467 }
Just4pLeisure 4:682d96ff6d79 468 if (TesterPresent.read_ms() > 2000) {
Just4pLeisure 5:1775b4b13232 469 GMLANTesterPresent(T8REQID, T8RESPID);
Just4pLeisure 4:682d96ff6d79 470 TesterPresent.reset();
Just4pLeisure 4:682d96ff6d79 471 }
Just4pLeisure 4:682d96ff6d79 472 StartAddress += 0xE0;
Just4pLeisure 4:682d96ff6d79 473 printf("%6.2f\r", (100.0*(float)i)/(float)(blocks2Send) );
Just4pLeisure 4:682d96ff6d79 474 }
Just4pLeisure 4:682d96ff6d79 475 // FLASHing complete
Just4pLeisure 4:682d96ff6d79 476 printf("%6.2f\r\n", (float)100 );
Just4pLeisure 4:682d96ff6d79 477 // End programming session and return to normal mode
Just4pLeisure 5:1775b4b13232 478 if (!GMLANReturnToNormalMode(T8REQID, T8RESPID)) {
Just4pLeisure 4:682d96ff6d79 479 fclose(fp);
Just4pLeisure 4:682d96ff6d79 480 printf("UH-OH! T8 ECU did not Return To Normal Mode!!\r\n");
Just4pLeisure 4:682d96ff6d79 481 return FALSE;
Just4pLeisure 4:682d96ff6d79 482 }
Just4pLeisure 4:682d96ff6d79 483 timer.stop();
Just4pLeisure 4:682d96ff6d79 484 printf("SUCCESS! FLASHing the BIN file took %#.1f seconds.\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 485 fclose(fp);
Just4pLeisure 4:682d96ff6d79 486 return TRUE;
Just4pLeisure 4:682d96ff6d79 487 }
Just4pLeisure 5:1775b4b13232 488
Just4pLeisure 5:1775b4b13232 489 bool t8_recover()
Just4pLeisure 5:1775b4b13232 490 {
Just4pLeisure 5:1775b4b13232 491 uint32_t i = 0, j = 0, k = 0;
Just4pLeisure 5:1775b4b13232 492
Just4pLeisure 5:1775b4b13232 493 timer.reset();
Just4pLeisure 5:1775b4b13232 494 timer.start();
Just4pLeisure 5:1775b4b13232 495 printf("Recovering your T8 ECU ...\r\n");
Just4pLeisure 5:1775b4b13232 496 //
Just4pLeisure 5:1775b4b13232 497 if (!GMLANprogrammingSetupProcess(T8USDTREQID, T8UUDTRESPID))
Just4pLeisure 5:1775b4b13232 498 return FALSE;
Just4pLeisure 5:1775b4b13232 499 //
Just4pLeisure 5:1775b4b13232 500 printf("Requesting Security Access\r\n");
Just4pLeisure 5:1775b4b13232 501 if (!t8_authenticate(T8USDTREQID, T8UUDTRESPID, 0x01)) {
Just4pLeisure 5:1775b4b13232 502 printf("Unable to get Security Access\r\n");
Just4pLeisure 5:1775b4b13232 503 return FALSE;
Just4pLeisure 5:1775b4b13232 504 }
Just4pLeisure 5:1775b4b13232 505 printf("Security Access Granted\r\n");
Just4pLeisure 5:1775b4b13232 506 //
Just4pLeisure 5:1775b4b13232 507 // const uint8_t BootLoader[] = T8BootloaderProg;
Just4pLeisure 5:1775b4b13232 508 // if(!GMLANprogrammingUtilityFileProcess(T8USDTREQID, T8UUDTRESPID, BootLoader))
Just4pLeisure 5:1775b4b13232 509 if(!GMLANprogrammingUtilityFileProcess(T8USDTREQID, T8UUDTRESPID, T8BootLoaderWrite))
Just4pLeisure 5:1775b4b13232 510 return FALSE;
Just4pLeisure 5:1775b4b13232 511 //
Just4pLeisure 5:1775b4b13232 512
Just4pLeisure 5:1775b4b13232 513
Just4pLeisure 5:1775b4b13232 514 // All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance)
Just4pLeisure 5:1775b4b13232 515 uint32_t StartAddress = 0x020000;
Just4pLeisure 5:1775b4b13232 516 uint32_t txpnt = 0;
Just4pLeisure 5:1775b4b13232 517 char iFrameNumber = 0x21;
Just4pLeisure 5:1775b4b13232 518 char GMLANMsg[8];
Just4pLeisure 5:1775b4b13232 519 char data2Send[0xE0];
Just4pLeisure 5:1775b4b13232 520 //
Just4pLeisure 5:1775b4b13232 521 // fopen modified.bin here, check it is OK and work out how much data I need to send
Just4pLeisure 5:1775b4b13232 522 // need lots of fcloses though
Just4pLeisure 5:1775b4b13232 523 printf("Checking the FLASH BIN file...\r\n");
Just4pLeisure 5:1775b4b13232 524 FILE *fp = fopen("/local/modified.bin", "r"); // Open "modified.bin" on the local file system for reading
Just4pLeisure 5:1775b4b13232 525 if (!fp) {
Just4pLeisure 5:1775b4b13232 526 printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");;
Just4pLeisure 5:1775b4b13232 527 return TERM_ERR;
Just4pLeisure 5:1775b4b13232 528 }
Just4pLeisure 5:1775b4b13232 529 // obtain file size - it should match the size of the FLASH chips:
Just4pLeisure 5:1775b4b13232 530 fseek (fp , 0 , SEEK_END);
Just4pLeisure 5:1775b4b13232 531 uint32_t file_size = ftell (fp);
Just4pLeisure 5:1775b4b13232 532 rewind (fp);
Just4pLeisure 5:1775b4b13232 533
Just4pLeisure 5:1775b4b13232 534 // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU
Just4pLeisure 5:1775b4b13232 535 uint32_t stack_long = 0;
Just4pLeisure 5:1775b4b13232 536 if (!fread(&stack_long,4,1,fp)) {
Just4pLeisure 5:1775b4b13232 537 fclose(fp);
Just4pLeisure 5:1775b4b13232 538 return TERM_ERR;
Just4pLeisure 5:1775b4b13232 539 }
Just4pLeisure 5:1775b4b13232 540 stack_long = (stack_long >> 24) | ((stack_long << 8) & 0x00FF0000) | ((stack_long >> 8) & 0x0000FF00) | (stack_long << 24);
Just4pLeisure 5:1775b4b13232 541 //
Just4pLeisure 5:1775b4b13232 542 if (file_size != T8FLASHSIZE || stack_long != T8POINTER) {
Just4pLeisure 5:1775b4b13232 543 fclose(fp);
Just4pLeisure 5:1775b4b13232 544 printf("The BIN file does not appear to be for a T8 ECU :-(\r\n");
Just4pLeisure 5:1775b4b13232 545 printf("BIN file size: %#010x, FLASH chip size: %#010x, Pointer: %#010x.\r\n", file_size, T7FLASHSIZE, stack_long);
Just4pLeisure 5:1775b4b13232 546 return TERM_ERR;
Just4pLeisure 5:1775b4b13232 547 }
Just4pLeisure 5:1775b4b13232 548 // It is possible to save some time by only sending the program code and CAL data
Just4pLeisure 5:1775b4b13232 549 // This is just a rough calculation, and slight overestimate of the number of blocks of data needed to send the BIN file
Just4pLeisure 5:1775b4b13232 550 uint32_t blocks2Send;
Just4pLeisure 5:1775b4b13232 551 fseek(fp,0x020140,SEEK_SET);
Just4pLeisure 5:1775b4b13232 552 if (!fread(&blocks2Send,4,1,fp)) {
Just4pLeisure 5:1775b4b13232 553 fclose(fp);
Just4pLeisure 5:1775b4b13232 554 return TERM_ERR;
Just4pLeisure 5:1775b4b13232 555 }
Just4pLeisure 5:1775b4b13232 556 blocks2Send = (blocks2Send >> 24) | ((blocks2Send << 8) & 0x00FF0000) | ((blocks2Send >> 8) & 0x0000FF00) | (blocks2Send << 24);
Just4pLeisure 5:1775b4b13232 557 printf("Start address of BIN file's Footer area = 0x%06X\r\n", blocks2Send );
Just4pLeisure 5:1775b4b13232 558 blocks2Send += 0x200; // Add some bytes for the Footer itself and to account for division rounded down later
Just4pLeisure 5:1775b4b13232 559 blocks2Send -= 0x020000; // Remove 0x020000 because we don't send the bootblock and adaptation blocks
Just4pLeisure 5:1775b4b13232 560 printf("Amount of data to send BIN file adjusted for footer = 0x%06X Bytes\r\n", blocks2Send );
Just4pLeisure 5:1775b4b13232 561 blocks2Send /= 0xE0;
Just4pLeisure 5:1775b4b13232 562 printf("Number of Blocks of 0xE0 Bytes needed to send BIN file = 0x%04X\r\n", blocks2Send );
Just4pLeisure 5:1775b4b13232 563 // Move BIN file pointer to start of data
Just4pLeisure 5:1775b4b13232 564 fseek (fp , 0x020000 , SEEK_SET);
Just4pLeisure 5:1775b4b13232 565 // Erase the FLASH
Just4pLeisure 5:1775b4b13232 566 printf("Waiting for FLASH to be Erased\r\n");
Just4pLeisure 5:1775b4b13232 567 if (!GMLANRequestDownload(T8REQID, T8RESPID, GMLANRequestDownloadModeEncrypted)) {
Just4pLeisure 5:1775b4b13232 568 fclose(fp);
Just4pLeisure 5:1775b4b13232 569 printf("Unable to erase the FLASH chip!\r\n");
Just4pLeisure 5:1775b4b13232 570 return FALSE;
Just4pLeisure 5:1775b4b13232 571 }
Just4pLeisure 5:1775b4b13232 572 // Now send the BIN file
Just4pLeisure 5:1775b4b13232 573 GMLANTesterPresent(T8REQID, T8RESPID);
Just4pLeisure 5:1775b4b13232 574 TesterPresent.start();
Just4pLeisure 5:1775b4b13232 575 printf("Sending FLASH BIN file\r\n");
Just4pLeisure 5:1775b4b13232 576 printf(" 0.00 %% complete.\r");
Just4pLeisure 5:1775b4b13232 577 for (i=0; i<blocks2Send; i++) {
Just4pLeisure 5:1775b4b13232 578 // get a block of 0xE0 bytes in an array called data2Send
Just4pLeisure 5:1775b4b13232 579 if (!fread(data2Send,0xE0,1,fp)) {
Just4pLeisure 5:1775b4b13232 580 fclose(fp);
Just4pLeisure 5:1775b4b13232 581 printf("\r\nError reading the BIN file MODIFIED.BIN\r\n");
Just4pLeisure 5:1775b4b13232 582 return FALSE;
Just4pLeisure 5:1775b4b13232 583 }
Just4pLeisure 5:1775b4b13232 584 // encrypt data2Send array by XORing with 6 different values in a ring (modulo function)
Just4pLeisure 5:1775b4b13232 585 char key[6] = { 0x39, 0x68, 0x77, 0x6D, 0x47, 0x39 };
Just4pLeisure 5:1775b4b13232 586 for ( j = 0; j < 0xE0; j++ )
Just4pLeisure 5:1775b4b13232 587 data2Send[j] ^= key[(((0xE0*i)+j) % 6)];
Just4pLeisure 5:1775b4b13232 588 // Send the block of data
Just4pLeisure 5:1775b4b13232 589 if (!GMLANDataTransferFirstFrame(T8REQID, T8RESPID, 0xE6, GMLANDOWNLOAD, StartAddress)) {
Just4pLeisure 5:1775b4b13232 590 fclose(fp);
Just4pLeisure 5:1775b4b13232 591 printf("\r\nUnable to start BIN File Upload\r\n");
Just4pLeisure 5:1775b4b13232 592 return FALSE;
Just4pLeisure 5:1775b4b13232 593 }
Just4pLeisure 5:1775b4b13232 594 // Send 0x20 messages of 0x07 bytes each (0x20 * 0x07 = 0xE0)
Just4pLeisure 5:1775b4b13232 595 txpnt = 0;
Just4pLeisure 5:1775b4b13232 596 iFrameNumber = 0x21;
Just4pLeisure 5:1775b4b13232 597 for (j=0; j < 0x20; j++) {
Just4pLeisure 5:1775b4b13232 598 GMLANMsg[0] = iFrameNumber;
Just4pLeisure 5:1775b4b13232 599 for (k=1; k<8; k++)
Just4pLeisure 5:1775b4b13232 600 GMLANMsg[k] = data2Send[txpnt++];
Just4pLeisure 5:1775b4b13232 601 if (!can_send_timeout(T8REQID, GMLANMsg, 8, GMLANPTCT)) {
Just4pLeisure 5:1775b4b13232 602 fclose(fp);
Just4pLeisure 5:1775b4b13232 603 printf("\r\nUnable to send BIN File\r\n");
Just4pLeisure 5:1775b4b13232 604 return FALSE;
Just4pLeisure 5:1775b4b13232 605 }
Just4pLeisure 5:1775b4b13232 606 ++iFrameNumber &= 0x2F;
Just4pLeisure 5:1775b4b13232 607 wait_us(1000); // was 250 use 1000 or wait_ms(1) to be ultrasafe
Just4pLeisure 5:1775b4b13232 608 }
Just4pLeisure 5:1775b4b13232 609 if (!GMLANDataTransferBlockAcknowledge(T8RESPID)) {
Just4pLeisure 5:1775b4b13232 610 fclose(fp);
Just4pLeisure 5:1775b4b13232 611 return FALSE;
Just4pLeisure 5:1775b4b13232 612 }
Just4pLeisure 5:1775b4b13232 613 if (TesterPresent.read_ms() > 2000) {
Just4pLeisure 5:1775b4b13232 614 GMLANTesterPresent(T8REQID, T8RESPID);
Just4pLeisure 5:1775b4b13232 615 TesterPresent.reset();
Just4pLeisure 5:1775b4b13232 616 }
Just4pLeisure 5:1775b4b13232 617 StartAddress += 0xE0;
Just4pLeisure 5:1775b4b13232 618 printf("%6.2f\r", (100.0*(float)i)/(float)(blocks2Send) );
Just4pLeisure 5:1775b4b13232 619 }
Just4pLeisure 5:1775b4b13232 620 // FLASHing complete
Just4pLeisure 5:1775b4b13232 621 printf("%6.2f\r\n", (float)100 );
Just4pLeisure 5:1775b4b13232 622 // End programming session and return to normal mode
Just4pLeisure 5:1775b4b13232 623 if (!GMLANReturnToNormalMode(T8REQID, T8RESPID)) {
Just4pLeisure 5:1775b4b13232 624 fclose(fp);
Just4pLeisure 5:1775b4b13232 625 printf("UH-OH! T8 ECU did not Return To Normal Mode!!\r\n");
Just4pLeisure 5:1775b4b13232 626 return FALSE;
Just4pLeisure 5:1775b4b13232 627 }
Just4pLeisure 5:1775b4b13232 628 timer.stop();
Just4pLeisure 5:1775b4b13232 629 fclose(fp);
Just4pLeisure 5:1775b4b13232 630 printf("SUCCESS: Your T8 ECU has been recovered.\r\n");
Just4pLeisure 5:1775b4b13232 631 return TRUE;
Just4pLeisure 5:1775b4b13232 632 }