Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Committer:
Just4pLeisure
Date:
Wed Sep 11 11:55:51 2013 +0000
Revision:
4:682d96ff6d79
Child:
5:1775b4b13232
This update adds T8 CAN DUMP and FLASH capability (recovery still to do)

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 4:682d96ff6d79 41 uint16_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 4:682d96ff6d79 90 // GMLANTesterPresentT8();
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 4:682d96ff6d79 100 // GMLANTesterPresentT8();
Just4pLeisure 4:682d96ff6d79 101 // wait_ms(2000);
Just4pLeisure 4:682d96ff6d79 102 //
Just4pLeisure 4:682d96ff6d79 103 // GMLANTesterPresentT8();
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 4:682d96ff6d79 135 // GMLANTesterPresentT8();
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 4:682d96ff6d79 150 bool t8_authenticate(char level)
Just4pLeisure 4:682d96ff6d79 151 {
Just4pLeisure 4:682d96ff6d79 152 uint16_t seed, key;
Just4pLeisure 4:682d96ff6d79 153 if (!GMLANSecurityAccessRequest(level, seed)) {
Just4pLeisure 4:682d96ff6d79 154 printf("Unable to request SEED value for security access\r\n");
Just4pLeisure 4:682d96ff6d79 155 return FALSE;
Just4pLeisure 4:682d96ff6d79 156 }
Just4pLeisure 4:682d96ff6d79 157 if ( seed == 0x0000 ) {
Just4pLeisure 4:682d96ff6d79 158 printf("T8 ECU is already unlocked\r\n");
Just4pLeisure 4:682d96ff6d79 159 return TRUE;
Just4pLeisure 4:682d96ff6d79 160 }
Just4pLeisure 4:682d96ff6d79 161 key = (seed >> 5) | (seed << 11);
Just4pLeisure 4:682d96ff6d79 162 key += 0xB988;
Just4pLeisure 4:682d96ff6d79 163 if (level == 0xFD) {
Just4pLeisure 4:682d96ff6d79 164 key /= 3;
Just4pLeisure 4:682d96ff6d79 165 key ^= 0x8749;
Just4pLeisure 4:682d96ff6d79 166 key += 0x0ACF;
Just4pLeisure 4:682d96ff6d79 167 key ^= 0x81BF;
Just4pLeisure 4:682d96ff6d79 168 } else if (level == 0xFB) {
Just4pLeisure 4:682d96ff6d79 169 key ^= 0x8749;
Just4pLeisure 4:682d96ff6d79 170 key += 0x06D3;
Just4pLeisure 4:682d96ff6d79 171 key ^= 0xCFDF;
Just4pLeisure 4:682d96ff6d79 172 }
Just4pLeisure 4:682d96ff6d79 173 /* CIM KEY CALCULATION
Just4pLeisure 4:682d96ff6d79 174 uint16_t key = (seed + 0x9130);
Just4pLeisure 4:682d96ff6d79 175 key = (key >> 8) | (key << 8);
Just4pLeisure 4:682d96ff6d79 176 key -= 0x3FC7;
Just4pLeisure 4:682d96ff6d79 177 */
Just4pLeisure 4:682d96ff6d79 178 if (!GMLANSecurityAccessSendKey(level, key)) {
Just4pLeisure 4:682d96ff6d79 179 printf("Unable to send KEY value for security access\r\n");
Just4pLeisure 4:682d96ff6d79 180 return FALSE;
Just4pLeisure 4:682d96ff6d79 181 }
Just4pLeisure 4:682d96ff6d79 182 printf("Key Accepted\r\n");
Just4pLeisure 4:682d96ff6d79 183 return TRUE;
Just4pLeisure 4:682d96ff6d79 184 }
Just4pLeisure 4:682d96ff6d79 185
Just4pLeisure 4:682d96ff6d79 186
Just4pLeisure 4:682d96ff6d79 187
Just4pLeisure 4:682d96ff6d79 188 //
Just4pLeisure 4:682d96ff6d79 189 // t8_dump
Just4pLeisure 4:682d96ff6d79 190 //
Just4pLeisure 4:682d96ff6d79 191 // dumps the T8 BIN File
Just4pLeisure 4:682d96ff6d79 192 // but doesn't displays anything.
Just4pLeisure 4:682d96ff6d79 193 //
Just4pLeisure 4:682d96ff6d79 194 // inputs: none
Just4pLeisure 4:682d96ff6d79 195 // return: bool TRUE if there was a message, FALSE if no message.
Just4pLeisure 4:682d96ff6d79 196 //
Just4pLeisure 4:682d96ff6d79 197
Just4pLeisure 4:682d96ff6d79 198 bool t8_dump()
Just4pLeisure 4:682d96ff6d79 199 {
Just4pLeisure 4:682d96ff6d79 200 uint16_t i = 0, k = 0;
Just4pLeisure 4:682d96ff6d79 201 char T8TxMsg[8];
Just4pLeisure 4:682d96ff6d79 202 char T8RxMsg[8];
Just4pLeisure 4:682d96ff6d79 203
Just4pLeisure 4:682d96ff6d79 204 timer.reset();
Just4pLeisure 4:682d96ff6d79 205 timer.start();
Just4pLeisure 4:682d96ff6d79 206 printf("Creating FLASH dump file...\r\n");
Just4pLeisure 4:682d96ff6d79 207
Just4pLeisure 4:682d96ff6d79 208 //
Just4pLeisure 4:682d96ff6d79 209 GMLANTesterPresentT8();
Just4pLeisure 4:682d96ff6d79 210 //
Just4pLeisure 4:682d96ff6d79 211 if (!GMLANprogrammingSetupProcess())
Just4pLeisure 4:682d96ff6d79 212 return FALSE;
Just4pLeisure 4:682d96ff6d79 213 //
Just4pLeisure 4:682d96ff6d79 214 wait_ms(500);
Just4pLeisure 4:682d96ff6d79 215 printf("Requesting Security Access\r\n");
Just4pLeisure 4:682d96ff6d79 216 if (!t8_authenticate(0x01)) {
Just4pLeisure 4:682d96ff6d79 217 printf("Unable to get Security Access\r\n");
Just4pLeisure 4:682d96ff6d79 218 return FALSE;
Just4pLeisure 4:682d96ff6d79 219 }
Just4pLeisure 4:682d96ff6d79 220 printf("Security Access Granted\r\n");
Just4pLeisure 4:682d96ff6d79 221 wait_ms(500);
Just4pLeisure 4:682d96ff6d79 222 GMLANTesterPresentT8();
Just4pLeisure 4:682d96ff6d79 223 //
Just4pLeisure 4:682d96ff6d79 224 char BootLoader[] = T8Bootloader;
Just4pLeisure 4:682d96ff6d79 225 if(!GMLANprogrammingUtilityFileProcess(BootLoader))
Just4pLeisure 4:682d96ff6d79 226 return FALSE;
Just4pLeisure 4:682d96ff6d79 227 //
Just4pLeisure 4:682d96ff6d79 228 uint32_t StartAddress = 0x0;
Just4pLeisure 4:682d96ff6d79 229 uint16_t txpnt = 0;
Just4pLeisure 4:682d96ff6d79 230 char iFrameNumber = 0x21;
Just4pLeisure 4:682d96ff6d79 231 //
Just4pLeisure 4:682d96ff6d79 232 printf("Downloading FLASH BIN file...\r\n");
Just4pLeisure 4:682d96ff6d79 233 printf("Creating FLASH dump file...\r\n");
Just4pLeisure 4:682d96ff6d79 234 FILE *fp = fopen("/local/original.bin", "w"); // Open "original.bin" on the local file system for writing
Just4pLeisure 4:682d96ff6d79 235 if (!fp) {
Just4pLeisure 4:682d96ff6d79 236 perror ("The following error occured");
Just4pLeisure 4:682d96ff6d79 237 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 238 }
Just4pLeisure 4:682d96ff6d79 239 printf(" 0.00 %% complete.\r");
Just4pLeisure 4:682d96ff6d79 240 TesterPresent.start();
Just4pLeisure 4:682d96ff6d79 241 while (StartAddress < 0x100000) { // 0x100000
Just4pLeisure 4:682d96ff6d79 242 T8TxMsg[0] = 0x06;
Just4pLeisure 4:682d96ff6d79 243 T8TxMsg[1] = 0x21;
Just4pLeisure 4:682d96ff6d79 244 T8TxMsg[2] = 0x80; // Blocksize
Just4pLeisure 4:682d96ff6d79 245 T8TxMsg[3] = (char) (StartAddress >> 24);
Just4pLeisure 4:682d96ff6d79 246 T8TxMsg[4] = (char) (StartAddress >> 16);
Just4pLeisure 4:682d96ff6d79 247 T8TxMsg[5] = (char) (StartAddress >> 8);
Just4pLeisure 4:682d96ff6d79 248 T8TxMsg[6] = (char) (StartAddress);
Just4pLeisure 4:682d96ff6d79 249 T8TxMsg[7] = 0xaa;
Just4pLeisure 4:682d96ff6d79 250 #ifdef DEBUG
Just4pLeisure 4:682d96ff6d79 251 printf("block %#.3f\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 252 #endif
Just4pLeisure 4:682d96ff6d79 253 if (!can_send_timeout (T8TSTRID, T8TxMsg, 7, T8MESSAGETIMEOUT)) {
Just4pLeisure 4:682d96ff6d79 254 printf("Unable to download FLASH\r\n");
Just4pLeisure 4:682d96ff6d79 255 return FALSE;
Just4pLeisure 4:682d96ff6d79 256 }
Just4pLeisure 4:682d96ff6d79 257 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 258 return FALSE;
Just4pLeisure 4:682d96ff6d79 259 #ifdef DEBUG
Just4pLeisure 4:682d96ff6d79 260 printf("first %#.3f\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 261 for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] );
Just4pLeisure 4:682d96ff6d79 262 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 263 #endif
Just4pLeisure 4:682d96ff6d79 264 txpnt = 0;
Just4pLeisure 4:682d96ff6d79 265 for (k = 4; k < 8; k++ ) file_buffer[txpnt++] = T8RxMsg[k];
Just4pLeisure 4:682d96ff6d79 266
Just4pLeisure 4:682d96ff6d79 267 uint8_t DataFrames = 0x12;
Just4pLeisure 4:682d96ff6d79 268 iFrameNumber = 0x21;
Just4pLeisure 4:682d96ff6d79 269 char T8TxFlo[] = T8FLOCTL;
Just4pLeisure 4:682d96ff6d79 270 #ifdef DEBUG
Just4pLeisure 4:682d96ff6d79 271 printf("flowCtrl %#.3f\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 272 #endif
Just4pLeisure 4:682d96ff6d79 273 can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT);
Just4pLeisure 4:682d96ff6d79 274 for (i = 0; i < DataFrames; i++) {
Just4pLeisure 4:682d96ff6d79 275 if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT))
Just4pLeisure 4:682d96ff6d79 276 return FALSE;
Just4pLeisure 4:682d96ff6d79 277 #ifdef DEBUG
Just4pLeisure 4:682d96ff6d79 278 printf("Consec %#.3f\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 279 for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] );
Just4pLeisure 4:682d96ff6d79 280 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 281 #endif
Just4pLeisure 4:682d96ff6d79 282 iFrameNumber++;
Just4pLeisure 4:682d96ff6d79 283 for (k = 1; k < 8; k++ ) file_buffer[txpnt++] = T8RxMsg[k];
Just4pLeisure 4:682d96ff6d79 284 }
Just4pLeisure 4:682d96ff6d79 285 fwrite((file_buffer), 1, 0x80, fp);
Just4pLeisure 4:682d96ff6d79 286 if (ferror (fp)) {
Just4pLeisure 4:682d96ff6d79 287 fclose (fp);
Just4pLeisure 4:682d96ff6d79 288 printf ("Error writing to the FLASH BIN file.\r\n");
Just4pLeisure 4:682d96ff6d79 289 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 290 }
Just4pLeisure 4:682d96ff6d79 291 StartAddress +=0x80;
Just4pLeisure 4:682d96ff6d79 292 printf("%6.2f\r", (100.0*(float)StartAddress)/(float)(0x100000) );
Just4pLeisure 4:682d96ff6d79 293 if (TesterPresent.read_ms() > 2000) {
Just4pLeisure 4:682d96ff6d79 294 GMLANTesterPresentT8();
Just4pLeisure 4:682d96ff6d79 295 TesterPresent.reset();
Just4pLeisure 4:682d96ff6d79 296 ACTIVITYLEDON;
Just4pLeisure 4:682d96ff6d79 297 }
Just4pLeisure 4:682d96ff6d79 298 }
Just4pLeisure 4:682d96ff6d79 299
Just4pLeisure 4:682d96ff6d79 300 printf("%6.2f\r\n", (float)100 );
Just4pLeisure 4:682d96ff6d79 301 timer.stop();
Just4pLeisure 4:682d96ff6d79 302 printf("SUCCESS! Getting the FLASH dump took %#.1f seconds.\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 303 fclose(fp);
Just4pLeisure 4:682d96ff6d79 304 return TRUE;
Just4pLeisure 4:682d96ff6d79 305 }
Just4pLeisure 4:682d96ff6d79 306
Just4pLeisure 4:682d96ff6d79 307 bool t8_erase()
Just4pLeisure 4:682d96ff6d79 308 {
Just4pLeisure 4:682d96ff6d79 309 printf("Erasing T8 ECU FLASH...\r\n");
Just4pLeisure 4:682d96ff6d79 310 printf("SUCCESS: The FLASH has been erased.\r\n");
Just4pLeisure 4:682d96ff6d79 311 return TRUE;
Just4pLeisure 4:682d96ff6d79 312 }
Just4pLeisure 4:682d96ff6d79 313
Just4pLeisure 4:682d96ff6d79 314 bool t8_flash_raw()
Just4pLeisure 4:682d96ff6d79 315 {
Just4pLeisure 4:682d96ff6d79 316 timer.reset();
Just4pLeisure 4:682d96ff6d79 317 timer.start();
Just4pLeisure 4:682d96ff6d79 318 printf("Checking the FLASH BIN file...\r\n");
Just4pLeisure 4:682d96ff6d79 319 timer.stop();
Just4pLeisure 4:682d96ff6d79 320 printf("SUCCESS! Programming the FLASH took %#.1f seconds.\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 321 return TRUE;
Just4pLeisure 4:682d96ff6d79 322 }
Just4pLeisure 4:682d96ff6d79 323
Just4pLeisure 4:682d96ff6d79 324
Just4pLeisure 4:682d96ff6d79 325 bool t8_flash()
Just4pLeisure 4:682d96ff6d79 326 {
Just4pLeisure 4:682d96ff6d79 327 uint16_t i = 0, j = 0, k = 0;
Just4pLeisure 4:682d96ff6d79 328
Just4pLeisure 4:682d96ff6d79 329 timer.reset();
Just4pLeisure 4:682d96ff6d79 330 timer.start();
Just4pLeisure 4:682d96ff6d79 331 printf("FLASHing T8 BIN file...\r\n");
Just4pLeisure 4:682d96ff6d79 332
Just4pLeisure 4:682d96ff6d79 333 //
Just4pLeisure 4:682d96ff6d79 334 GMLANTesterPresentT8();
Just4pLeisure 4:682d96ff6d79 335 //
Just4pLeisure 4:682d96ff6d79 336 if (!GMLANprogrammingSetupProcess())
Just4pLeisure 4:682d96ff6d79 337 return FALSE;
Just4pLeisure 4:682d96ff6d79 338 //
Just4pLeisure 4:682d96ff6d79 339 wait_ms(500);
Just4pLeisure 4:682d96ff6d79 340 printf("Requesting Security Access\r\n");
Just4pLeisure 4:682d96ff6d79 341 if (!t8_authenticate(0x01)) {
Just4pLeisure 4:682d96ff6d79 342 printf("Unable to get Security Access\r\n");
Just4pLeisure 4:682d96ff6d79 343 return FALSE;
Just4pLeisure 4:682d96ff6d79 344 }
Just4pLeisure 4:682d96ff6d79 345 printf("Security Access Granted\r\n");
Just4pLeisure 4:682d96ff6d79 346 wait_ms(500);
Just4pLeisure 4:682d96ff6d79 347 GMLANTesterPresentT8();
Just4pLeisure 4:682d96ff6d79 348 //
Just4pLeisure 4:682d96ff6d79 349 char BootLoader[] = T8BootloaderProg;
Just4pLeisure 4:682d96ff6d79 350 if(!GMLANprogrammingUtilityFileProcess(BootLoader))
Just4pLeisure 4:682d96ff6d79 351 return FALSE;
Just4pLeisure 4:682d96ff6d79 352 //
Just4pLeisure 4:682d96ff6d79 353
Just4pLeisure 4:682d96ff6d79 354
Just4pLeisure 4:682d96ff6d79 355 // All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance)
Just4pLeisure 4:682d96ff6d79 356 // bool GMLANprogrammingUtilityFileProcess(char UtilityFile[]) {
Just4pLeisure 4:682d96ff6d79 357 // uint16_t i = 0, j = 0, k = 0;
Just4pLeisure 4:682d96ff6d79 358 uint32_t StartAddress = 0x020000;
Just4pLeisure 4:682d96ff6d79 359 uint16_t txpnt = 0;
Just4pLeisure 4:682d96ff6d79 360 char iFrameNumber = 0x21;
Just4pLeisure 4:682d96ff6d79 361 char GMLANMsg[8];
Just4pLeisure 4:682d96ff6d79 362 char data2Send[0xE0];
Just4pLeisure 4:682d96ff6d79 363 //
Just4pLeisure 4:682d96ff6d79 364 // fopen modified.hex here, check it is OK and work out how much data I need to send
Just4pLeisure 4:682d96ff6d79 365 // need lots of fcloses though
Just4pLeisure 4:682d96ff6d79 366 printf("Checking the FLASH BIN file...\r\n");
Just4pLeisure 4:682d96ff6d79 367 FILE *fp = fopen("/local/modified.hex", "r"); // Open "modified.hex" on the local file system for reading
Just4pLeisure 4:682d96ff6d79 368 if (!fp) {
Just4pLeisure 4:682d96ff6d79 369 printf("Error: I could not find the BIN file MODIFIED.HEX\r\n");;
Just4pLeisure 4:682d96ff6d79 370 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 371 }
Just4pLeisure 4:682d96ff6d79 372 // obtain file size - it should match the size of the FLASH chips:
Just4pLeisure 4:682d96ff6d79 373 fseek (fp , 0 , SEEK_END);
Just4pLeisure 4:682d96ff6d79 374 uint32_t file_size = ftell (fp);
Just4pLeisure 4:682d96ff6d79 375 rewind (fp);
Just4pLeisure 4:682d96ff6d79 376
Just4pLeisure 4:682d96ff6d79 377 // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU
Just4pLeisure 4:682d96ff6d79 378 uint32_t stack_long = 0;
Just4pLeisure 4:682d96ff6d79 379 if (!fread(&stack_long,4,1,fp)) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 380 stack_long = (stack_long >> 24) | ((stack_long << 8) & 0x00FF0000) | ((stack_long >> 8) & 0x0000FF00) | (stack_long << 24);
Just4pLeisure 4:682d96ff6d79 381 //
Just4pLeisure 4:682d96ff6d79 382 if (file_size != T8FLASHSIZE || stack_long != T8POINTER) {
Just4pLeisure 4:682d96ff6d79 383 fclose(fp);
Just4pLeisure 4:682d96ff6d79 384 printf("The BIN file does not appear to be for a T8 ECU :-(\r\n");
Just4pLeisure 4:682d96ff6d79 385 printf("BIN file size: %#010x, FLASH chip size: %#010x, Pointer: %#010x.\r\n", file_size, T7FLASHSIZE, stack_long);
Just4pLeisure 4:682d96ff6d79 386 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 387 }
Just4pLeisure 4:682d96ff6d79 388 // It is possible to save some time by only sending the program code and CAL data
Just4pLeisure 4:682d96ff6d79 389 // 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 390 uint32_t blocks2Send;
Just4pLeisure 4:682d96ff6d79 391 fseek(fp,0x020140,SEEK_SET);
Just4pLeisure 4:682d96ff6d79 392 if (!fread(&blocks2Send,4,1,fp)) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 393 blocks2Send = (blocks2Send >> 24) | ((blocks2Send << 8) & 0x00FF0000) | ((blocks2Send >> 8) & 0x0000FF00) | (blocks2Send << 24);
Just4pLeisure 4:682d96ff6d79 394 printf("Start address of BIN file's Footer area = 0x%06X\r\n", blocks2Send );
Just4pLeisure 4:682d96ff6d79 395 blocks2Send += 0x200; // Add some bytes for the Footer itself and to account for division rounded down later
Just4pLeisure 4:682d96ff6d79 396 blocks2Send -= 0x020000; // Remove 0x020000 because we don't send the bootblock and adaptation blocks
Just4pLeisure 4:682d96ff6d79 397 printf("Amount of data to send BIN file adjusted for footer = 0x%06X Bytes\r\n", blocks2Send );
Just4pLeisure 4:682d96ff6d79 398 blocks2Send /= 0xE0;
Just4pLeisure 4:682d96ff6d79 399 printf("Number of Blocks of 0xE0 Bytes needed to send BIN file = 0x%04X\r\n", blocks2Send );
Just4pLeisure 4:682d96ff6d79 400 // Move BIN file pointer to start of data
Just4pLeisure 4:682d96ff6d79 401 fseek (fp , 0x020000 , SEEK_SET);
Just4pLeisure 4:682d96ff6d79 402 // Erase the FLASH
Just4pLeisure 4:682d96ff6d79 403 printf("Waiting for FLASH to be Erased\r\n");
Just4pLeisure 4:682d96ff6d79 404 if (!GMLANRequestDownload(GMLANRequestDownloadModeEncrypted)) {
Just4pLeisure 4:682d96ff6d79 405 printf("Unable to erase the FLASH chip!\r\n");
Just4pLeisure 4:682d96ff6d79 406 return FALSE;
Just4pLeisure 4:682d96ff6d79 407 }
Just4pLeisure 4:682d96ff6d79 408 // Now send the BIN file
Just4pLeisure 4:682d96ff6d79 409 TesterPresent.start();
Just4pLeisure 4:682d96ff6d79 410 printf("Sending FLASH BIN file\r\n");
Just4pLeisure 4:682d96ff6d79 411 printf(" 0.00 %% complete.\r");
Just4pLeisure 4:682d96ff6d79 412 for (i=0; i<blocks2Send; i++) {
Just4pLeisure 4:682d96ff6d79 413 // get a block of 0xE0 bytes in an array called data2Send
Just4pLeisure 4:682d96ff6d79 414 for ( j = 0; j < 0xE0; j++ ) {
Just4pLeisure 4:682d96ff6d79 415 //data[k] = *(bin + bin_count++);
Just4pLeisure 4:682d96ff6d79 416 if (!fread(&data2Send[j],1,1,fp)) {
Just4pLeisure 4:682d96ff6d79 417 fclose(fp);
Just4pLeisure 4:682d96ff6d79 418 printf("Error reading the BIN file MODIFIED.HEX\r\n");
Just4pLeisure 4:682d96ff6d79 419 return FALSE;
Just4pLeisure 4:682d96ff6d79 420 }
Just4pLeisure 4:682d96ff6d79 421 // encrypt data2Send array by XORing with 6 different in a ring (modulo function)
Just4pLeisure 4:682d96ff6d79 422 switch ( ((0xE0*i)+j) %6) {
Just4pLeisure 4:682d96ff6d79 423 case 1:
Just4pLeisure 4:682d96ff6d79 424 data2Send[j] ^= 0x68;
Just4pLeisure 4:682d96ff6d79 425 break;
Just4pLeisure 4:682d96ff6d79 426 case 2:
Just4pLeisure 4:682d96ff6d79 427 data2Send[j] ^= 0x77;
Just4pLeisure 4:682d96ff6d79 428 break;
Just4pLeisure 4:682d96ff6d79 429 case 3:
Just4pLeisure 4:682d96ff6d79 430 data2Send[j] ^= 0x6D;
Just4pLeisure 4:682d96ff6d79 431 break;
Just4pLeisure 4:682d96ff6d79 432 case 4:
Just4pLeisure 4:682d96ff6d79 433 data2Send[j] ^= 0x47;
Just4pLeisure 4:682d96ff6d79 434 break;
Just4pLeisure 4:682d96ff6d79 435 default: // remainder 0 and 5 both XOR with 0x39
Just4pLeisure 4:682d96ff6d79 436 data2Send[j] ^= 0x39;
Just4pLeisure 4:682d96ff6d79 437 }
Just4pLeisure 4:682d96ff6d79 438 }
Just4pLeisure 4:682d96ff6d79 439 // Send the block of data
Just4pLeisure 4:682d96ff6d79 440 if (!GMLANDataTransferFirstFrame(0xE6, GMLANDOWNLOAD, StartAddress)) {
Just4pLeisure 4:682d96ff6d79 441 fclose(fp);
Just4pLeisure 4:682d96ff6d79 442 printf("Unable to start BIN File Upload\r\n");
Just4pLeisure 4:682d96ff6d79 443 return FALSE;
Just4pLeisure 4:682d96ff6d79 444 }
Just4pLeisure 4:682d96ff6d79 445 // Send 0x20 messages of 0x07 bytes each (0x20 * 0x07 = 0xE0)
Just4pLeisure 4:682d96ff6d79 446 txpnt = 0;
Just4pLeisure 4:682d96ff6d79 447 iFrameNumber = 0x21;
Just4pLeisure 4:682d96ff6d79 448 for (j=0; j < 0x20; j++) {
Just4pLeisure 4:682d96ff6d79 449 GMLANMsg[0] = iFrameNumber;
Just4pLeisure 4:682d96ff6d79 450 for (k=1; k<8; k++)
Just4pLeisure 4:682d96ff6d79 451 GMLANMsg[k] = data2Send[txpnt++];
Just4pLeisure 4:682d96ff6d79 452 #ifdef DEBUG
Just4pLeisure 4:682d96ff6d79 453 for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
Just4pLeisure 4:682d96ff6d79 454 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 455 #endif
Just4pLeisure 4:682d96ff6d79 456 if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) {
Just4pLeisure 4:682d96ff6d79 457 fclose(fp);
Just4pLeisure 4:682d96ff6d79 458 printf("Unable to send BIN File\r\n");
Just4pLeisure 4:682d96ff6d79 459 return FALSE;
Just4pLeisure 4:682d96ff6d79 460 }
Just4pLeisure 4:682d96ff6d79 461 ++iFrameNumber &= 0x2F;
Just4pLeisure 4:682d96ff6d79 462 // wait_ms(1);
Just4pLeisure 4:682d96ff6d79 463 wait_us(250);
Just4pLeisure 4:682d96ff6d79 464 }
Just4pLeisure 4:682d96ff6d79 465 if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) {
Just4pLeisure 4:682d96ff6d79 466 fclose(fp);
Just4pLeisure 4:682d96ff6d79 467 printf("I did not receive a block acknowledge message\r\n");
Just4pLeisure 4:682d96ff6d79 468 return FALSE;
Just4pLeisure 4:682d96ff6d79 469 }
Just4pLeisure 4:682d96ff6d79 470 while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) {
Just4pLeisure 4:682d96ff6d79 471 printf("I'm waiting for a Block to be programmed into FLASH\r\n");
Just4pLeisure 4:682d96ff6d79 472 if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) {
Just4pLeisure 4:682d96ff6d79 473 printf("I did not receive a block acknowledge message after enhanced timeout\r\n");
Just4pLeisure 4:682d96ff6d79 474 fclose(fp);
Just4pLeisure 4:682d96ff6d79 475 return FALSE;
Just4pLeisure 4:682d96ff6d79 476 }
Just4pLeisure 4:682d96ff6d79 477 }
Just4pLeisure 4:682d96ff6d79 478 #ifdef DEBUG
Just4pLeisure 4:682d96ff6d79 479 for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] );
Just4pLeisure 4:682d96ff6d79 480 printf("\r\n");
Just4pLeisure 4:682d96ff6d79 481 #endif
Just4pLeisure 4:682d96ff6d79 482 if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) {
Just4pLeisure 4:682d96ff6d79 483 GMLANShowReturnCode(GMLANMsg[3]);
Just4pLeisure 4:682d96ff6d79 484 fclose(fp);
Just4pLeisure 4:682d96ff6d79 485 return FALSE;
Just4pLeisure 4:682d96ff6d79 486 }
Just4pLeisure 4:682d96ff6d79 487 if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) {
Just4pLeisure 4:682d96ff6d79 488 printf("EXITING due to an unexpected CAN message");
Just4pLeisure 4:682d96ff6d79 489 fclose(fp);
Just4pLeisure 4:682d96ff6d79 490 return FALSE;
Just4pLeisure 4:682d96ff6d79 491 }
Just4pLeisure 4:682d96ff6d79 492 if (TesterPresent.read_ms() > 2000) {
Just4pLeisure 4:682d96ff6d79 493 GMLANTesterPresentT8();
Just4pLeisure 4:682d96ff6d79 494 TesterPresent.reset();
Just4pLeisure 4:682d96ff6d79 495 ACTIVITYLEDON;
Just4pLeisure 4:682d96ff6d79 496 }
Just4pLeisure 4:682d96ff6d79 497 StartAddress += 0xE0;
Just4pLeisure 4:682d96ff6d79 498 printf("%6.2f\r", (100.0*(float)i)/(float)(blocks2Send) );
Just4pLeisure 4:682d96ff6d79 499 }
Just4pLeisure 4:682d96ff6d79 500 // FLASHing complete
Just4pLeisure 4:682d96ff6d79 501 printf("%6.2f\r\n", (float)100 );
Just4pLeisure 4:682d96ff6d79 502 // End programming session and return to normal mode
Just4pLeisure 4:682d96ff6d79 503 if (!GMLANReturnToNormalMode()) {
Just4pLeisure 4:682d96ff6d79 504 fclose(fp);
Just4pLeisure 4:682d96ff6d79 505 printf("UH-OH! T8 ECU did not Return To Normal Mode!!\r\n");
Just4pLeisure 4:682d96ff6d79 506 return FALSE;
Just4pLeisure 4:682d96ff6d79 507 }
Just4pLeisure 4:682d96ff6d79 508 wait_ms(1000);
Just4pLeisure 4:682d96ff6d79 509 timer.stop();
Just4pLeisure 4:682d96ff6d79 510 printf("SUCCESS! FLASHing the BIN file took %#.1f seconds.\r\n",timer.read());
Just4pLeisure 4:682d96ff6d79 511 fclose(fp);
Just4pLeisure 4:682d96ff6d79 512 return TRUE;
Just4pLeisure 4:682d96ff6d79 513 }