Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Fork of Just4Trionic by Sophie Dexter

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers t7utils.cpp Source File

t7utils.cpp

00001 /*******************************************************************************
00002 
00003 t7utils.cpp
00004 (c) 2011, 2012 by Sophie Dexter
00005 portions (c) Tomi Liljemark (firstname.surname@gmail.com)
00006 
00007 This C++ module provides functions for communicating simple messages to and from
00008 the T7 ECU
00009 
00010 ********************************************************************************
00011 
00012 WARNING: Use at your own risk, sadly this software comes with no guarantees.
00013 This software is provided 'free' and in good faith, but the author does not
00014 accept liability for any damage arising from its use.
00015 
00016 *******************************************************************************/
00017 
00018 #include "t7utils.h"
00019 
00020 
00021 //
00022 // t7_initialise
00023 //
00024 // sends an initialisation message to the T7 ECU
00025 // but doesn't displays anything.
00026 //
00027 // inputs:    none
00028 // return:    bool TRUE if there was a message, FALSE if no message.
00029 //
00030 
00031 
00032 bool t7_initialise() {
00033     // send a can message to the T7 requesting that it initialises CAN communication with Just4Trionic
00034     char T7TxMsg[] = T7INITMSG;
00035     if (!can_send_timeout (T7CMNDID, T7TxMsg, 8, T7MESSAGETIMEOUT))
00036         return FALSE;
00037     // wait for the T7 to reply
00038     char T7RxMsg[8];
00039     // if a message is not received, has the wrong id
00040     if (!can_wait_timeout(T7RESPID, T7RxMsg, 8, T7MESSAGETIMEOUT))
00041         return FALSE;
00042     /* DEBUG info...
00043         for (int i = 0; i < 8; i++ ) printf("0x%02X ", T7RxMsg[i] );
00044         printf(" init\r\n");
00045     */
00046     return TRUE;
00047 }
00048 
00049 //
00050 // t7_authenticate
00051 //
00052 // sends an authentication message to the T7 ECU
00053 // but doesn't displays anything.
00054 //
00055 // inputs:    none
00056 // return:    bool TRUE if there was a message, FALSE if no message.
00057 //
00058 
00059 bool t7_authenticate() {
00060     uint16_t seed, key;
00061 //    uint16_t i;
00062     char T7TxAck[] = T7ACK_MSG;
00063     char T7TxMsg[] = T7SEC_MSG;
00064     char T7TxKey[] = T7KEY_MSG;
00065     char T7RxMsg[8];
00066     // Send "Request Seed" to Trionic7
00067     if (!can_send_timeout (T7SEC_ID, T7TxMsg, 8, T7MESSAGETIMEOUT))
00068         return FALSE;
00069     // wait for the T7 to reply
00070     // Read "Seed"
00071     // if a message is not received id return false
00072     if (!can_wait_timeout(T7SEC_RX, T7RxMsg, 8, T7MESSAGETIMEOUT))
00073         return FALSE;
00074     /* DEBUG info...
00075         for (i = 0; i < 8; i++ ) printf("0x%02X ", T7RxMsg[i] );
00076         printf(" seed\r\n");
00077     */
00078     // Send Ack
00079     T7TxAck[3] = T7RxMsg[0] & 0xBF;
00080     if (!can_send_timeout (T7ACK_ID, T7TxAck, 8, T7MESSAGETIMEOUT))
00081         return FALSE;
00082     // Send "Key", try two different methods of calculating the key
00083     seed = T7RxMsg[5] << 8 | T7RxMsg[6];
00084     for (int method = 0; method < 2; method++ ) {
00085         key = seed << 2;
00086         key &= 0xFFFF;
00087         key ^= ( method ? 0x4081 : 0x8142 );
00088         key -= ( method ? 0x1F6F : 0x2356 );
00089         key &= 0xFFFF;
00090         T7TxKey[5] = ( key >> 8 ) & 0xFF;
00091         T7TxKey[6] = key & 0xFF;
00092         if (!can_send_timeout (T7SEC_ID, T7TxKey, 8, T7MESSAGETIMEOUT))
00093             return FALSE;
00094         // Wait for response
00095         // if a message is not received id return false
00096         if (!can_wait_timeout(T7SEC_RX, T7RxMsg, 8, T7MESSAGETIMEOUT))
00097             return FALSE;
00098         /* DEBUG info...
00099                 for (i = 0; i < 8; i++ ) printf("0x%02X ", T7RxMsg[i] );
00100                 printf(" key %d 0x%02X 0x%02X\r\n", method, T7RxMsg[3], T7RxMsg[5]);
00101         */
00102         // Send Ack
00103         T7TxAck[3] = T7RxMsg[0] & 0xBF;
00104         if (!can_send_timeout (T7ACK_ID, T7TxAck, 8, T7MESSAGETIMEOUT)) {
00105             /* DEBUG info...
00106                         printf("Key ACK message timeout\r\n");
00107             */
00108             return FALSE;
00109         }
00110         if ( T7RxMsg[3] == 0x67 && T7RxMsg[5] == 0x34 ) {
00111             /* DEBUG info...
00112                         printf("Key %d Accepted\r\n", method);
00113             */
00114             return TRUE;
00115         } else {
00116             /* DEBUG info...
00117                         printf("Key %d Failed\r\n", method);
00118             */
00119         }
00120     }
00121     return FALSE;
00122 }
00123 //
00124 // t7_dump
00125 //
00126 // dumps the T7 BIN File
00127 // but doesn't displays anything.
00128 //
00129 // inputs:    none
00130 // return:    bool TRUE if there was a message, FALSE if no message.
00131 //
00132 
00133 bool t7_dump() {
00134     uint32_t received;
00135     uint8_t byte_count, retries, i;
00136     char T7_dump_jumpa[] = T7DMPJP1A;
00137     char T7_dump_jumpb[] = T7DMPJP1B;
00138     char T7_dump_ack[] = T7DMP_ACK;
00139     char T7_dump_data[] = T7DMPDATA;
00140     char T7_dump_end[] = T7DMP_END;
00141     char T7RxMsg[8];
00142 
00143     printf("Creating FLASH dump file...\r\n");
00144     FILE *fp = fopen("/local/original.bin", "w");    // Open "original.bin" on the local file system for writing
00145     if (!fp) {
00146         perror ("The following error occured");
00147         return TERM_ERR;
00148     }
00149 
00150     timer.reset();
00151     timer.start();
00152 
00153     received = 0;
00154     printf("  0.00 %% complete.\r");
00155     while (received < T7FLASHSIZE) {
00156 //        T7_dump_jumpa[7] = ((T7FLASHSIZE - received) < 0xEF) ? (T7FLASHSIZE - received) : 0xEF;
00157         T7_dump_jumpb[2] = (received >> 16) & 0xFF;
00158         T7_dump_jumpb[3] = (received >> 8) & 0xFF;
00159         T7_dump_jumpb[4] = received & 0xFF;
00160         // Send read address and length to Trionic
00161         if (!can_send_timeout (T7SEC_ID, T7_dump_jumpa, 8, T7MESSAGETIMEOUT)) {
00162             printf("err t7utils line: %d\r\n", __LINE__ );
00163             fclose(fp);
00164             return FALSE;
00165         }
00166         if (!can_send_timeout (T7SEC_ID, T7_dump_jumpb, 8, T7MESSAGETIMEOUT)) {
00167             printf("err t7utils line: %d\r\n", __LINE__ );
00168             fclose(fp);
00169             return FALSE;
00170         }
00171         // Wait for a response
00172         if (!can_wait_timeout(T7SEC_RX, T7RxMsg, 8, T7MESSAGETIMEOUT)) {
00173             printf("err t7utils line: %d\r\n", __LINE__ );
00174             fclose(fp);
00175             return FALSE;
00176         }
00177         /* DEBUG info...
00178             for (i = 0; i < 8; i++ ) printf("0x%02X ", T7RxMsg[i] );
00179             printf(" seed\r\n");
00180         */
00181         // Send Ack
00182         T7_dump_ack[3] = T7RxMsg[0] & 0xBF;
00183         if (!can_send_timeout (T7ACK_ID, T7_dump_ack, 8, T7MESSAGETIMEOUT)) {
00184             printf("ERROR Asking1: %5.1f %% done\r\n", 100*(float)received/(float)T7FLASHSIZE);
00185             printf("err t7utils line: %d\r\n", __LINE__ );
00186             fclose(fp);
00187             return FALSE;
00188         }
00189         if ((T7RxMsg[3] != 0x6C) ||(T7RxMsg[4] != 0xF0)) {
00190             printf("ERROR Asking2: %5.1f %% done\r\n", 100*(float)received/(float)T7FLASHSIZE);
00191             printf("err t7utils line: %d\r\n", __LINE__ );
00192             fclose(fp);
00193             return FALSE;
00194         }
00195         // Ask T7 ECU to start sending data
00196         for (retries = 0 ; retries <10 ; retries++ ) {
00197             if (!can_send_timeout (T7SEC_ID, T7_dump_data, 8, T7MESSAGETIMEOUT)) {
00198                 printf("err t7utils line: %d\r\n", __LINE__ );
00199                 fclose(fp);
00200                 return FALSE;
00201             }
00202             // Read mesages from the T7 ECU
00203             byte_count = 0;
00204             T7RxMsg[0] = 0x00;
00205             while (T7RxMsg[0] != 0x80 && T7RxMsg[0] != 0xC0) {
00206                 if (!can_wait_timeout(T7SEC_RX, T7RxMsg, 8, T7MESSAGETIMEOUT))
00207                     break;
00208                 // Need to process the received data here!
00209                 // Send Ack
00210                 T7_dump_ack[3] = T7RxMsg[0] & 0xBF;
00211                 if (!can_send_timeout (T7ACK_ID, T7_dump_ack, 8, T7MESSAGETIMEOUT)) {
00212                     printf("ERROR processing: %5.1f %% done\r\n", 100*(float)received/(float)T7FLASHSIZE);
00213                     printf("err t7utils line: %d\r\n", __LINE__ );
00214                     fclose(fp);
00215                     return FALSE;
00216                 }
00217 //                /* DEBUG info...
00218 //                for (i = 0; i < 8; i++ ) printf("0x%02X ", T7RxMsg[i] );
00219 //                for (i = 2; i < 8; i++ ) printf("%c ", T7RxMsg[i] );
00220 //                printf(" data\r\n");
00221                 for (i = 2; i < 8; i++ )
00222                     file_buffer[byte_count++] = (T7RxMsg[i]);
00223 //                */
00224             }
00225             // Success if these conditions met
00226             if (T7RxMsg[0] == 0x80 || T7RxMsg[0] == 0xC0)
00227                 break;
00228 //            printf("retries: %d\r\n", retries);
00229         }
00230         if (retries > 9) {
00231             printf("err t7utils line: %d\r\n", __LINE__ );
00232             printf("Retries: %d, Done: %5.2f %%\r\n", retries, 100*(float)received/(float)T7FLASHSIZE );
00233             fclose(fp);
00234             return FALSE;
00235         }
00236 //        received += 0xEF;
00237         received += 0x80;
00238 //        printf("Retries: %d, Done: %5.2f %%\r\n", retries, 100*(float)received/(float)T7FLASHSIZE );
00239         printf("%6.2f\r", 100*(float)received/(float)T7FLASHSIZE );
00240         fwrite((file_buffer + 3), 1, 0x80, fp);
00241         if (ferror (fp)) {
00242             fclose (fp);
00243             printf ("Error writing to the FLASH BIN file.\r\n");
00244             return TERM_ERR;
00245         }
00246     }
00247     printf("\n");
00248     // Send Message to T7 ECU to say that we have finished
00249     if (!can_send_timeout (T7SEC_ID, T7_dump_end, 8, T7MESSAGETIMEOUT)) {
00250         fclose(fp);
00251         return FALSE;
00252     }
00253     // Wait for response
00254     if (!can_wait_timeout(T7SEC_RX, T7RxMsg, 8, T7MESSAGETIMEOUT)) {
00255         fclose(fp);
00256         return FALSE;
00257     }
00258 // Send Ack
00259     T7_dump_ack[3] = T7RxMsg[0] & 0xBF;
00260     if (!can_send_timeout (T7ACK_ID, T7_dump_ack, 8, T7MESSAGETIMEOUT)) {
00261         printf("ERROR closing1: %5.1f %% done\r\n", 100*(float)received/(float)T7FLASHSIZE);
00262         printf("err t7utils line: %d\r\n", __LINE__ );
00263         fclose(fp);
00264         return FALSE;
00265     }
00266     if (T7RxMsg[3] != 0xC2) {
00267         printf("ERROR closing2: %5.1f %% done\r\n", 100*(float)received/(float)T7FLASHSIZE);
00268         printf("err t7utils line: %d\r\n", __LINE__ );
00269         fclose(fp);
00270         return FALSE;
00271     }
00272     timer.stop();
00273     printf("SUCCESS! Getting the FLASH dump took %#.1f seconds.\r\n",timer.read());
00274     fclose(fp);
00275     return TRUE;
00276 }
00277 
00278 bool t7_erase() {
00279     char T7_erase_msga[]   = { 0x40, 0xA1, 0x02, 0x31, 0x52, 0x00, 0x00, 0x00 };
00280     char T7_erase_msgb[]   = { 0x40, 0xA1, 0x02, 0x31, 0x53, 0x00, 0x00, 0x00 };
00281     char T7_erase_confirm[]   = { 0x40, 0xA1, 0x01, 0x3E, 0x00, 0x00, 0x00, 0x00 };
00282     char T7_erase_ack[]     = { 0x40, 0xA1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00 };
00283     char data[8];
00284     int i;
00285 
00286     printf("Erasing T7 ECU FLASH...\r\n");
00287 
00288     data[3] = 0;
00289     i = 0;
00290     while ( data[3] != 0x71 && i < 10) {
00291         // Send "Request to ERASE" to Trionic
00292         if (!can_send_timeout (T7SEC_ID, T7_erase_msga, 8, T7MESSAGETIMEOUT)) {
00293             printf("err t7utils line: %d\r\n", __LINE__ );
00294             return FALSE;
00295         }
00296         if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00297             printf("err t7utils line: %d\r\n", __LINE__ );
00298             return FALSE;
00299         }
00300         T7_erase_ack[3] = data[0] & 0xBF;
00301         if (!can_send_timeout (T7ACK_ID, T7_erase_ack, 8, T7MESSAGETIMEOUT)) {
00302             printf("err t7utils line: %d\r\n", __LINE__ );
00303             return FALSE;
00304         }
00305         wait_ms(100);
00306         i++;
00307         printf(".");
00308     }
00309     printf("\r\n");
00310     // Check to see if erase operation lasted longer than 1 sec...
00311     if (i >=10) {
00312         printf("Second Message took too long'\r\n");
00313         return FALSE;
00314     }
00315     data[3] = 0;
00316     i = 0;
00317     while ( data[3] != 0x71 && i < 200) {
00318         // Send "Request to ERASE" to Trionic
00319         if (!can_send_timeout (T7SEC_ID, T7_erase_msgb, 8, T7MESSAGETIMEOUT)) {
00320             printf("err t7utils line: %d\r\n", __LINE__ );
00321             return FALSE;
00322         }
00323         if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00324             printf("err t7utils line: %d\r\n", __LINE__ );
00325             return FALSE;
00326         }
00327         T7_erase_ack[3] = data[0] & 0xBF;
00328         if (!can_send_timeout (T7ACK_ID, T7_erase_ack, 8, T7MESSAGETIMEOUT)) {
00329             printf("err t7utils line: %d\r\n", __LINE__ );
00330             return FALSE;
00331         }
00332         wait_ms(100);
00333         i++;
00334         printf(".");
00335     }
00336     printf("\r\n");
00337     // Check to see if erase operation lasted longer than 20 sec...
00338     if (i >=200) {
00339         printf("Second Message took too long'\r\n");
00340         return FALSE;
00341     }
00342 
00343     // Confirm erase was successful?
00344     // (Note: no acknowledgements used for some reason)
00345     if (!can_send_timeout (T7SEC_ID, T7_erase_confirm, 8, T7MESSAGETIMEOUT)) {
00346         printf("err t7utils line: %d\r\n", __LINE__ );
00347         return FALSE;
00348     }
00349     if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00350         printf("err t7utils line: %d\r\n", __LINE__ );
00351         return FALSE;
00352     }
00353     if ( data[3] != 0x7E ) {
00354         printf("err t7utils line: %d\r\n", __LINE__ );
00355         return FALSE;
00356     }
00357     wait_ms(100);
00358     if (!can_send_timeout (T7SEC_ID, T7_erase_confirm, 8, T7MESSAGETIMEOUT)) {
00359         printf("err t7utils line: %d\r\n", __LINE__ );
00360         return FALSE;
00361     }
00362     if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00363         printf("err t7utils line: %d\r\n", __LINE__ );
00364         return FALSE;
00365     }
00366     if ( data[3] != 0x7E ) {
00367         printf("err t7utils line: %d\r\n", __LINE__ );
00368         return FALSE;
00369     }
00370     printf("SUCCESS: The FLASH has been erased.\r\n");
00371     return TRUE;
00372 }
00373 
00374 bool t7_flash_raw() {
00375     char T7_flash_jumpa[]   = T7FLAJP1A;
00376     char T7_flash_jumpb[]   = T7FLAJP1B;
00377     char T7_flash_end[]     = T7FLA_END;
00378     char T7_flash_exit[]    = T7FLAEXIT;
00379     char T7_flash_ack[]     = T7FLA_ACK;
00380     char data[8];
00381     int i, k;
00382 
00383     // fopen modified.bin here?
00384     // need lots of fcloses though
00385     printf("Checking the FLASH BIN file...\r\n");
00386     FILE *fp = fopen("/local/modified.bin", "r");    // Open "modified.bin" on the local file system for reading
00387     if (!fp) {
00388         printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");;
00389         return TERM_ERR;
00390     }
00391     // obtain file size - it should match the size of the FLASH chips:
00392     fseek (fp , 0 , SEEK_END);
00393     uint32_t file_size = ftell (fp);
00394     rewind (fp);
00395 
00396     // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU
00397     uint8_t stack_byte = 0;
00398     uint32_t stack_long = 0;
00399     if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
00400     stack_long |= (stack_byte << 24);
00401     if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
00402     stack_long |= (stack_byte << 16);
00403     if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
00404     stack_long |= (stack_byte << 8);
00405     if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
00406     stack_long |= stack_byte;
00407     rewind (fp);
00408 
00409     if (file_size != T7FLASHSIZE || stack_long != T7POINTER) {
00410         fclose(fp);
00411         printf("The BIN file does not appear to be for a T7 ECU :-(\r\n");
00412         printf("BIN file size: %#010x, FLASH chip size: %#010x, Pointer: %#010x.\r\n", file_size, T7FLASHSIZE, stack_long);
00413         return TERM_ERR;
00414     }
00415 
00416     timer.reset();
00417     timer.start();
00418 
00419     // Send "Request Download - tool to module" to Trionic
00420     if (!can_send_timeout (T7SEC_ID, T7_flash_jumpa, 8, T7MESSAGETIMEOUT)) {
00421         printf("err t7utils line: %d\r\n", __LINE__ );
00422         fclose(fp);
00423         return FALSE;
00424     }
00425     if (!can_send_timeout (T7SEC_ID, T7_flash_jumpb, 8, T7MESSAGETIMEOUT)) {
00426         printf("err t7utils line: %d\r\n", __LINE__ );
00427         fclose(fp);
00428         return FALSE;
00429     }
00430     if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00431         printf("err t7utils line: %d\r\n", __LINE__ );
00432         fclose(fp);
00433         return FALSE;
00434     }
00435     T7_flash_ack[3] = data[0] & 0xBF;
00436     if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
00437         printf("err t7utils line: %d\r\n", __LINE__ );
00438         fclose(fp);
00439         return FALSE;
00440     }
00441     if ( data[3] != 0x74 ) {
00442         printf("Cannot Update FLASH, message refused.\r\n");
00443         printf("err t7utils line: %d\r\n", __LINE__ );
00444         fclose(fp);
00445         return FALSE;
00446     }
00447 
00448     uint32_t address = 0;
00449 
00450     printf("  0.00 %% complete.\r");
00451     while (address < T7FLASHSIZE) {
00452 
00453 //        data[0] = 0x4A; // 0x40 send, | 0x0A (10) messages to follow
00454 //        data[0] = 0x42; // 0x40 send, | 0x02 (2) messages to follow
00455         data[0] = 0x40; // 0x40 send, | 0x00 (0) messages to follow
00456         data[1] = 0xA1;
00457 //        data[2] = 0x41; // length+1 (64 Bytes)
00458 //        data[2] = 0x11; // length+1 (16 Bytes)
00459         data[2] = 0x05; // length+1 (4 Bytes)
00460         data[3] = 0x36; // Data Transfer
00461         for ( k = 4; k < 8; k++ )
00462             //data[k] = *(bin + bin_count++);
00463             if (!fread(&data[k],1,1,fp)) {
00464                 fclose(fp);
00465                 printf("Error reading the BIN file MODIFIED.BIN\r\n");
00466                 return FALSE;
00467             }
00468 //      /* DEBUG info...
00469 //        for (k = 0; k < 8; k++ ) printf("0x%02X ", data[k] );
00470 //        for (k = 2; k < 8; k++ ) printf("%c ", data[k] );
00471 //        printf(" data\r\n");
00472 
00473         if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
00474             printf("err t7utils line: %d\r\n", __LINE__ );
00475             fclose(fp);
00476             return FALSE;
00477         }
00478         /*
00479                 for (i = 9; i>=0; i--) {
00480         //        for (i = 1; i>=0; i--) {
00481                     data[0] = i;
00482                     // data[1] = 0xA1;
00483                     for ( k = 2; k < 8; k++ )
00484                         //data[k] = *(bin + bin_count++);
00485                         if (!fread(&data[k],1,1,fp)) {
00486                             fclose(fp);
00487                             printf("Error reading the BIN file MODIFIED.BIN\r\n");
00488                             return FALSE;
00489                         }
00490         //            /* DEBUG info...
00491         //            for (k = 0; k < 8; k++ ) printf("0x%02X ", data[k] );
00492         //            for (k = 2; k < 8; k++ ) printf("%c ", data[k] );
00493         //            printf(" data\r\n");
00494 
00495         //            printf("%6.2f\r", 100*(float)address/(float)T7FLASHSIZE );
00496                     wait_ms(1);
00497         //            wait_ms(10);   // 31/3/12 this longer wait might be needed for i-bus connections...
00498                     if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
00499                         printf("err t7utils line: %d\r\n", __LINE__ );
00500                         fclose(fp);
00501                         return FALSE;
00502                     }
00503                 }
00504         */
00505 //        address += 0x40;
00506 //        address += 0x10;
00507         address += 0x04;
00508         if (!can_wait_timeout(T7SEC_RX, data, 8, T7LONGERTIMEOUT)) {
00509             printf("err t7utils line: %d\r\n", __LINE__ );
00510             fclose(fp);
00511             return FALSE;
00512         }
00513         // Send acknowledgement
00514         T7_flash_ack[3] = data[0] & 0xBF;
00515         if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
00516             printf("err t7utils line: %d\r\n", __LINE__ );
00517             fclose(fp);
00518             return FALSE;
00519         }
00520         if ( data[3] != 0x76 ) {
00521             printf("err t7utils line: %d\r\n", __LINE__ );
00522             fclose(fp);
00523             return FALSE;
00524         }
00525         if (!(address % 0x80))
00526             printf("%6.2f\r", 100*(float)address/(float)T7FLASHSIZE );
00527     }
00528     printf("\n");
00529     /*
00530         // Send "Request Data Transfer Exit" to Trionic
00531         if (!can_send_timeout (T7SEC_ID, T7_flash_end, 8, T7MESSAGETIMEOUT)) {
00532             printf("err t7utils line: %d\r\n", __LINE__ );
00533             fclose(fp);
00534             return FALSE;
00535         }
00536         if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00537             printf("err t7utils line: %d\r\n", __LINE__ );
00538             fclose(fp);
00539             return FALSE;
00540         }
00541         T7_flash_ack[3] = data[0] & 0xBF;
00542         if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
00543             printf("err t7utils line: %d\r\n", __LINE__ );
00544             fclose(fp);
00545             return FALSE;
00546         }
00547         if ( data[3] != 0x77 ) {
00548             printf("Cannot Update FLASH, message refused.\r\n");
00549             printf("err t7utils line: %d\r\n", __LINE__ );
00550             fclose(fp);
00551             return FALSE;
00552         }
00553         // Send "Request Data Transfer Exit" to Trionic
00554         if (!can_send_timeout (T7SEC_ID, T7_flash_exit, 8, T7MESSAGETIMEOUT)) {
00555             printf("err t7utils line: %d\r\n", __LINE__ );
00556             fclose(fp);
00557             return FALSE;
00558         }
00559         if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00560             printf("err t7utils line: %d\r\n", __LINE__ );
00561             fclose(fp);
00562             return FALSE;
00563         }
00564         T7_flash_ack[3] = data[0] & 0xBF;
00565         if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
00566             printf("err t7utils line: %d\r\n", __LINE__ );
00567             fclose(fp);
00568             return FALSE;
00569         }
00570         if ( data[3] != 0x71 ) {
00571             printf("Cannot Update FLASH, message refused.\r\n");
00572             printf("err t7utils line: %d\r\n", __LINE__ );
00573             fclose(fp);
00574             return FALSE;
00575         }
00576     */
00577     timer.stop();
00578     printf("SUCCESS! Programming the FLASH took %#.1f seconds.\r\n",timer.read());
00579     fclose(fp);
00580     return TRUE;
00581 }
00582 
00583 
00584 bool t7_flash() {
00585     char T7_flash_jumpa[]   = T7FLABINA;
00586     char T7_flash_jumpb[]   = T7FLABINB;
00587     char T7_flash_jumpc[]   = T7FLAHDRA;
00588     char T7_flash_jumpd[]   = T7FLAHDRB;
00589     char T7_flash_end[]     = T7FLA_END;
00590     char T7_flash_exit[]    = T7FLAEXIT;
00591     char T7_flash_ack[]     = T7FLA_ACK;
00592     char data[8];
00593     int i, k;
00594 
00595     // fopen modified.bin here?
00596     // need lots of fcloses though
00597     printf("Checking the FLASH BIN file...\r\n");
00598     FILE *fp = fopen("/local/modified.bin", "r");    // Open "modified.bin" on the local file system for reading
00599     if (!fp) {
00600         printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");;
00601         return TERM_ERR;
00602     }
00603     // obtain file size - it should match the size of the FLASH chips:
00604     fseek (fp , 0 , SEEK_END);
00605     uint32_t file_size = ftell (fp);
00606     rewind (fp);
00607 
00608     // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU
00609     uint8_t stack_byte = 0;
00610     uint32_t stack_long = 0;
00611     if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
00612     stack_long |= (stack_byte << 24);
00613     if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
00614     stack_long |= (stack_byte << 16);
00615     if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
00616     stack_long |= (stack_byte << 8);
00617     if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
00618     stack_long |= stack_byte;
00619     rewind (fp);
00620 
00621     if (file_size != T7FLASHSIZE || stack_long != T7POINTER) {
00622         fclose(fp);
00623         printf("The BIN file does not appear to be for a T7 ECU :-(\r\n");
00624         printf("BIN file size: %#010x, FLASH chip size: %#010x, Pointer: %#010x.\r\n", file_size, T7FLASHSIZE, stack_long);
00625         return TERM_ERR;
00626     }
00627 
00628     timer.reset();
00629     timer.start();
00630 
00631     // Send "Request Download - tool to module" to Trionic
00632     if (!can_send_timeout (T7SEC_ID, T7_flash_jumpa, 8, T7MESSAGETIMEOUT)) {
00633         printf("err t7utils line: %d\r\n", __LINE__ );
00634         fclose(fp);
00635         return FALSE;
00636     }
00637     if (!can_send_timeout (T7SEC_ID, T7_flash_jumpb, 8, T7MESSAGETIMEOUT)) {
00638         printf("err t7utils line: %d\r\n", __LINE__ );
00639         fclose(fp);
00640         return FALSE;
00641     }
00642     if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00643         printf("err t7utils line: %d\r\n", __LINE__ );
00644         fclose(fp);
00645         return FALSE;
00646     }
00647     T7_flash_ack[3] = data[0] & 0xBF;
00648     if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
00649         printf("err t7utils line: %d\r\n", __LINE__ );
00650         fclose(fp);
00651         return FALSE;
00652     }
00653     if ( data[3] != 0x74 ) {
00654         printf("Cannot Update FLASH, message refused.\r\n");
00655         printf("err t7utils line: %d\r\n", __LINE__ );
00656         fclose(fp);
00657         return FALSE;
00658     }
00659 
00660     uint32_t address = 0;
00661 
00662     printf("  0.00 %% complete.\r");
00663 // FLASH main Binary image up to address 0x7B000
00664     while (address < 0x70000) {
00665         data[0] = 0x40; // 0x40 send, | 0x00 (0) messages to follow
00666         data[1] = 0xA1;
00667         data[2] = 0x05; // length+1 (4 Bytes)
00668         data[3] = 0x36; // Data Transfer
00669         for ( k = 4; k < 8; k++ )
00670             if (!fread(&data[k],1,1,fp)) {
00671                 fclose(fp);
00672                 printf("Error reading the BIN file MODIFIED.BIN\r\n");
00673                 return FALSE;
00674             }
00675         if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
00676             printf("err t7utils line: %d\r\n", __LINE__ );
00677             fclose(fp);
00678             return FALSE;
00679         }
00680         address += 0x04;
00681         if (!can_wait_timeout(T7SEC_RX, data, 8, T7LONGERTIMEOUT)) {
00682             printf("err t7utils line: %d\r\n", __LINE__ );
00683             fclose(fp);
00684             return FALSE;
00685         }
00686         // Send acknowledgement
00687         T7_flash_ack[3] = data[0] & 0xBF;
00688         if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
00689             printf("err t7utils line: %d\r\n", __LINE__ );
00690             fclose(fp);
00691             return FALSE;
00692         }
00693         if ( data[3] != 0x76 ) {
00694             printf("err t7utils line: %d\r\n", __LINE__ );
00695             fclose(fp);
00696             return FALSE;
00697         }
00698         if (!(address % 0x80))
00699             printf("%6.2f\r", 100*(float)address/(float)T7FLASHSIZE );
00700     }
00701 
00702     // Send "Request Download - tool to module" to Trionic
00703     if (!can_send_timeout (T7SEC_ID, T7_flash_jumpc, 8, T7MESSAGETIMEOUT)) {
00704         printf("err t7utils line: %d\r\n", __LINE__ );
00705         fclose(fp);
00706         return FALSE;
00707     }
00708     if (!can_send_timeout (T7SEC_ID, T7_flash_jumpd, 8, T7MESSAGETIMEOUT)) {
00709         printf("err t7utils line: %d\r\n", __LINE__ );
00710         fclose(fp);
00711         return FALSE;
00712     }
00713     if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00714         printf("err t7utils line: %d\r\n", __LINE__ );
00715         fclose(fp);
00716         return FALSE;
00717     }
00718     T7_flash_ack[3] = data[0] & 0xBF;
00719     if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
00720         printf("err t7utils line: %d\r\n", __LINE__ );
00721         fclose(fp);
00722         return FALSE;
00723     }
00724     if ( data[3] != 0x74 ) {
00725         printf("Cannot Update FLASH, message refused.\r\n");
00726         printf("err t7utils line: %d\r\n", __LINE__ );
00727         fclose(fp);
00728         return FALSE;
00729     }
00730 
00731     address = 0x7FF00;
00732     fseek (fp , 0x7FF00 , SEEK_SET);
00733 
00734 // FLASH BIN file Header
00735     while (address < T7FLASHSIZE) {
00736         data[0] = 0x40; // 0x40 send, | 0x00 (0) messages to follow
00737         data[1] = 0xA1;
00738         data[2] = 0x05; // length+1 (4 Bytes)
00739         data[3] = 0x36; // Data Transfer
00740         for ( k = 4; k < 8; k++ )
00741             if (!fread(&data[k],1,1,fp)) {
00742                 fclose(fp);
00743                 printf("Error reading the BIN file MODIFIED.BIN\r\n");
00744                 return FALSE;
00745             }
00746         if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
00747             printf("err t7utils line: %d\r\n", __LINE__ );
00748             fclose(fp);
00749             return FALSE;
00750         }
00751         address += 0x04;
00752         if (!can_wait_timeout(T7SEC_RX, data, 8, T7LONGERTIMEOUT)) {
00753             printf("err t7utils line: %d\r\n", __LINE__ );
00754             fclose(fp);
00755             return FALSE;
00756         }
00757         // Send acknowledgement
00758         T7_flash_ack[3] = data[0] & 0xBF;
00759         if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
00760             printf("err t7utils line: %d\r\n", __LINE__ );
00761             fclose(fp);
00762             return FALSE;
00763         }
00764         if ( data[3] != 0x76 ) {
00765             printf("err t7utils line: %d\r\n", __LINE__ );
00766             fclose(fp);
00767             return FALSE;
00768         }
00769         if (!(address % 0x80))
00770             printf("%6.2f\r", 100*(float)address/(float)T7FLASHSIZE );
00771     }
00772 
00773 
00774     printf("\n");
00775     printf("Restarting T7 ECU");
00776 /*
00777         // Send "Request Data Transfer Exit" to Trionic
00778         if (!can_send_timeout (T7SEC_ID, T7_flash_end, 8, T7MESSAGETIMEOUT)) {
00779             printf("err t7utils line: %d\r\n", __LINE__ );
00780             fclose(fp);
00781             return FALSE;
00782         }
00783         if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00784             printf("err t7utils line: %d\r\n", __LINE__ );
00785             fclose(fp);
00786             return FALSE;
00787         }
00788         T7_flash_ack[3] = data[0] & 0xBF;
00789         if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
00790             printf("err t7utils line: %d\r\n", __LINE__ );
00791             fclose(fp);
00792             return FALSE;
00793         }
00794         if ( data[3] != 0x77 ) {
00795             printf("Cannot Update FLASH, message refused.\r\n");
00796             printf("err t7utils line: %d\r\n", __LINE__ );
00797             fclose(fp);
00798             return FALSE;
00799         }
00800 //
00801         // Send "Request Data Transfer Exit" to Trionic
00802         if (!can_send_timeout (T7SEC_ID, T7_flash_exit, 8, T7MESSAGETIMEOUT)) {
00803             printf("err t7utils line: %d\r\n", __LINE__ );
00804             fclose(fp);
00805             return FALSE;
00806         }
00807         if (!can_wait_timeout(T7SEC_RX, data, 8, T7MESSAGETIMEOUT)) {
00808             printf("err t7utils line: %d\r\n", __LINE__ );
00809             fclose(fp);
00810             return FALSE;
00811         }
00812         T7_flash_ack[3] = data[0] & 0xBF;
00813         if (!can_send_timeout (T7ACK_ID, T7_flash_ack, 8, T7MESSAGETIMEOUT)) {
00814             printf("err t7utils line: %d\r\n", __LINE__ );
00815             fclose(fp);
00816             return FALSE;
00817         }
00818         if ( data[3] != 0x71 ) {
00819             printf("Cannot Update FLASH, message refused.\r\n");
00820             printf("err t7utils line: %d\r\n", __LINE__ );
00821             fclose(fp);
00822             return FALSE;
00823         }
00824 */
00825     timer.stop();
00826     printf("SUCCESS! Programming the FLASH took %#.1f seconds.\r\n",timer.read());
00827     fclose(fp);
00828     return TRUE;
00829 }