//////////////////////////////////////////////////////////////////////// // H E A D E R //////////////////////////////////////////////////////////////////////// ecu : MRSZ_FIX; origin : RustyX; revision: 1.0; author : RustyX (me@rustyx.org); comment : MRSZ reanimator.; comment : Attempts to erase the unerasable "internal ECU error".; // MRSZ CPU: 68HC711K4 // // Commands: // 0 IDENT // 4 FS_LESEN // 5 FS_LOESCHEN // 6 SPEICHER_LESEN // 7 speicher_schreiben // 8 C_C_LESEN // 9 C_C_AUFTRAG // B STATUS_LESEN // E c_pruefstempel_lesen // F pruefstempel_schreiben // 32 mrsz? // 80 crash lesen? // 81 crash loeschen? // 90 SG_LOGIN // 9E diagnose_erhalten // 9F DIAGNOSE_ENDE //////////////////////////////////////////////////////////////////////// // CONSTANTS //////////////////////////////////////////////////////////////////////// // *** SG - PARAMETER *** // // Konzept 6 // Baudrate 9600 // Reizadresse 0xA4 // Wakeup-Zeit 0 ms // Idle-Zeit 0 ms // Timeout-Zeit 1000 ms // Regenerations-Zeit 25 ms // // param MRS2: 05 15 00 06 00 80 25 A4 00 00 00 00 00 E8 03 19 00 14 00 02 00 int PARAMETER[] = {6,9600,0xA4,0,0,1000,25,20,2}; int AWLEN[] = {-1,0}; int LENPOS = 1; int CTRLPOS = 2; int OK = 0xA0; int EEPROM_START=0xD80; int EEPROM_END1=0xEA0; int EEPROM_END=0x1000; char TEL_ID_READ[] = { 0xA4,0x04,0x00 }; char TEL_DIAG_START[] = { 0xA4,0x04,0x9E }; char TEL_DIAG_END[] = { 0xA4,0x04,0x9F }; char TEL_TC_READ[] = { 0xA4,0x05,0x04,0x00 }; char TEL_TC_CLEAR[] = { 0xA4,0x04,0x05 }; char TEL_SG_LOGIN[] = { 0xA4,0x06,0x90,0xFF,0xFF }; char TEL_MEM_READ[] = { 0xA4,0x07,0x06,0x00,0x00,0x10 }; char TEL_MEM_WRITE[] = { 0xA4,0x16,0x07,0xab,0xcd }; char TEL_END_DIAG[] = { 0xA4,0x04,0x9F }; char FF16[] = { 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF }; char ID1[] = { 0x00,0x1F,0x00,0x3F, 0x00,0x5F,0x00,0x7F, 0x00,0x9F,0x00,0xBF }; table JobResult[2][] = { {"SB" , "STATUS_TEXT" }, {"0xA0" , "OKAY" }, {"0xA1" , "BUSY" }, {"0xA2" , "ERROR_ECU_REJECTED" }, {"0xB0" , "ERROR_ECU_PARAMETER" }, {"0xB1" , "ERROR_ECU_FUNCTION" }, {"0xB2" , "ERROR_ECU_NUMBER" }, {"0xFF" , "ERROR_ECU_NACK" }, {"" , "ERROR_ECU_UNKNOWN_STATUSBYTE" } }; #define CHECK_FOR_ERRORS tabset("JobResult");tab_suche_index("SB",res[CTRLPOS]);tabget(s,"STATUS_TEXT");JOB_STATUS=s;\ if(res[CTRLPOS]!=OK){send_and_receive(res,TEL_DIAG_END);return;}if(res[LENPOS]!=datalen(res)){send_and_receive(res,TEL_DIAG_END);JOB_STATUS="ERROR_ECU_INCORRECT_LEN";return;} //////////////////////////////////////////////////////////////////////// // J O B S //////////////////////////////////////////////////////////////////////// job( name : INITIALISIERUNG; comment : Initializes the program; result : DONE; type : int; defrslt : ; comment : 0 = Error; comment : 1 = OK; ) { open_communication(); set_repeat_counter(1); set_communication_pars(PARAMETER); set_answer_length(AWLEN); DONE = 1; } //////////////////////////////////////////////////////////////////////// job( name : ERASE_ALL_ERRORS; comment : Clears all stored errors, including the "internal ECU error".; comment : ; comment : Note: module coding should be correct BEFORE running this; comment : command.; comment : ; comment : Author: RustyX (me@rustyx.org); result : JOB_STATUS; type : string; defrslt : ; comment : "OKAY" in case of success; ) { unsigned char res[]; unsigned char s[]; unsigned char s2[]; unsigned char eeprom[]; unsigned char partnum[]; int codingidx; int i; int j; int len; // check ECU ID A4 and ID_HW_NR=02 send_and_receive(res,TEL_ID_READ); CHECK_FOR_ERRORS; codingidx = res[8]; if (res[7]>2 || codingidx>16) { JOB_STATUS="ERROR_UNSUPPORTED_ECU_VERSION"; var_result_data("IDENT",res); return; } bcd2ascii(partnum,res,3,4); send_and_receive(res,TEL_DIAG_START); // check FS_LOESCHEN fails with ERROR_ECU_REJECTED send_and_receive(res,TEL_TC_CLEAR); if (res[CTRLPOS]!=0xA2) { CHECK_FOR_ERRORS; send_and_receive(res,TEL_DIAG_END); return; } // check ROM ID "MRSZ BMW" send_and_receive(res,TEL_SG_LOGIN); CHECK_FOR_ERRORS; dataclear(s); s=TEL_MEM_READ; s[3]=0xFF; s[4]=0xC0; send_and_receive(res,s); CHECK_FOR_ERRORS; dataclear(s); datacopy(s,res,5,16); s[8]=0; if (strcmp(s,"MRSZ BMW")) { send_and_receive(res,TEL_DIAG_END); JOB_STATUS="ERROR_UNSUPPORTED_ECU_VERSION"; var_result_data("ROM_ID",s); return; } // read EEPROM dataclear(eeprom); i=EEPROM_START; while (i>8; s[4]=i&0xFF; send_and_receive(res,s); CHECK_FOR_ERRORS; i+=0x10; dataclear(s); datacopy(s,res,3,16); datacat(eeprom,s); } len=datalen(ID1); while (len>=6) { i=0x52; j=datalen(eeprom)-len; dataclear(s); while (i=j) { if (!strcmp(partnum,"88374799")) { i=0xB6; } else if (!strcmp(partnum,"88372521")) { i=0x80; } else { send_and_receive(res,TEL_DIAG_END); JOB_STATUS="ERROR_UNSUPPORTED_ECU_VERSION"; var_result_string("ERROR_DETAILS","Pattern not found in EEPROM"); return; } } j=i-0x50; while (j>8; s[4]=(EEPROM_START+i)&0xFF; datacat(s,FF16); send_and_receive(res,s); CHECK_FOR_ERRORS; } JOB_STATUS="OKAY"; var_result_string("JOB_STATUS_COMMENT0", "DONE, now switch off the car for 30 seconds!"); var_result_string("JOB_STATUS_COMMENT1", ""); var_result_string("JOB_STATUS_COMMENT2", "Did the fix work for you? Donations are welcome! :)"); send_and_receive(res,TEL_DIAG_END); } //////////////////////////////////////////////////////////////////////// job( name : READ_EEPROM; comment : Reads EEPROM contents (for debugging purposes); result : JOB_STATUS; type : string; defrslt : ; comment : "OKAY" in case of success; result : RESULT_DATA; type : data; defrslt : ; comment : EEPROM data; ) { unsigned char res[]; unsigned char s[]; unsigned char s2[]; unsigned char eeprom[]; int i; // check ECU ID A4 and ID_HW_NR=02 send_and_receive(res,TEL_ID_READ); CHECK_FOR_ERRORS; if (res[7]>2) { JOB_STATUS="ERROR_UNSUPPORTED_ECU_VERSION"; hex2ascii(s,res,3,datalen(res)-3); var_result_string("IDENT",s); return; } // read EEPROM dataclear(eeprom); i=EEPROM_START; while (i>8; s[4]=i&0xFF; send_and_receive(res,s); CHECK_FOR_ERRORS; itoax(s2,i); i+=0x10; datacopy(s,res,3,16); datacat(eeprom,s); } JOB_STATUS="OKAY"; RESULT_DATA=eeprom; }