Just4Trionic - CAN and BDM FLASH programmer for Saab cars
Fork of Just4Trionic by
Revision 5:1775b4b13232, committed 2015-04-25
- Comitter:
- Just4pLeisure
- Date:
- Sat Apr 25 17:07:08 2015 +0000
- Parent:
- 4:682d96ff6d79
- Commit message:
- 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;
Changed in this revision
diff -r 682d96ff6d79 -r 1775b4b13232 bdm.cpp --- a/bdm.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/bdm.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -38,6 +38,10 @@ #define CMD_BKPTHIGH '2' ///< pull BKPT high #define CMD_RESETLOW '3' ///< pull RESET low #define CMD_RESETHIGH '4' ///< pull RESET high +#define CMD_BERR_LOW '5' ///< pull BERR low +#define CMD_BERR_HIGH '6' ///< pull BERR high +#define CMD_BERR_INPUT '7' ///< make BERR an input + #define CMDGROUP_MCU 'c' ///< target MCU management commands #define CMD_STOPCHIP 'S' ///< stop @@ -72,6 +76,7 @@ #define CMD_WRITESYSREG 'W' ///< write system register #define CMD_READADREG 'a' ///< read A/D register #define CMD_WRITEADREG 'A' ///< write A/D register +#define CMD_DISPLAYREGS 'd' ///< BD32 like display all registers #define CMDGROUP_TRIONIC 'T' #define CMD_TRIONICDUMP 'D' ///< dumps memory contents @@ -99,7 +104,8 @@ return TERM_ERR -void bdm() { +void bdm() +{ bdm_show_help(); // set up LED pins @@ -167,7 +173,8 @@ @return command flag (success / failure) */ -uint8_t execute_bdm_cmd() { +uint8_t execute_bdm_cmd() +{ uint8_t cmd_length = strlen(cmd_buffer); char cmd = *(cmd_buffer + 1); @@ -210,6 +217,18 @@ // pull RESET high case CMD_RESETHIGH: return reset_high(); + + // pull BERR low + case CMD_BERR_LOW: + return berr_low(); + + // pull BERR high + case CMD_BERR_HIGH: + return berr_high(); + + // make BERR an input + case CMD_BERR_INPUT: + return berr_input(); } break; @@ -404,16 +423,20 @@ // registers case CMDGROUP_REGISTER: // get register code - if (cmd_length < 4 || !ascii2int(&cmd_addr, cmd_buffer + 3, 1)) { + if (cmd_length == 2 && (cmd != CMD_DISPLAYREGS)) { // broken parametre return TERM_ERR; - } - - // get optional value - if (cmd_length > 4 && - !ascii2int(&cmd_value, cmd_buffer + 4, 8)) { - // broken parametre - return TERM_ERR; + } else { + if (cmd_length < 4 || !ascii2int(&cmd_addr, cmd_buffer + 3, 1)) { + // broken parametre + return TERM_ERR; + } + // get optional value + if (cmd_length > 4 && + !ascii2int(&cmd_value, cmd_buffer + 4, 8)) { + // broken parametre + return TERM_ERR; + } } switch (cmd) { @@ -448,6 +471,85 @@ return (cmd_length == 12 && adreg_write((uint8_t)cmd_addr, &cmd_value) == TERM_OK) ? TERM_OK : TERM_ERR; + + // Display all registers + case CMD_DISPLAYREGS: + printf(" D0-7"); + for (uint8_t i = 0; i < 8; i++) { + if (adreg_read(&cmd_result, i) != TERM_OK) { + return TERM_ERR; + } + printf(" %08X", cmd_result); + } +// + printf("\r\n"); + printf(" A0-7"); + for (uint8_t i = 8; i < 16; i++) { + if (adreg_read(&cmd_result, i) != TERM_OK) { + return TERM_ERR; + } + printf(" %08X", cmd_result); + } + printf("\r\n"); +// + if (sysreg_read(&cmd_result, 0x0) != TERM_OK) { + return TERM_ERR; + } + printf(" RPC %08X", cmd_result); + if (sysreg_read(&cmd_result, 0xC) != TERM_OK) { + return TERM_ERR; + } + printf(" USP %08X", cmd_result); + if (sysreg_read(&cmd_result, 0xE) != TERM_OK) { + return TERM_ERR; + } + printf(" SFC %08X SR 10S--210---XNZVC\r\n", cmd_result); +// + if (sysreg_read(&cmd_result, 0x1) != TERM_OK) { + return TERM_ERR; + } + printf(" CPC %08X", cmd_result); + if (sysreg_read(&cmd_result, 0xD) != TERM_OK) { + return TERM_ERR; + } + printf(" SSP %08X", cmd_result); + if (sysreg_read(&cmd_result, 0xF) != TERM_OK) { + return TERM_ERR; + } + printf(" DFC %08X", cmd_result); + if (sysreg_read(&cmd_result, 0xB) != TERM_OK) { + return TERM_ERR; + } + printf(" %04X ", cmd_result); + for (uint32_t i = 0; i < 16; i++) { + cmd_result & (1 << (15-i)) ? printf("1") : printf("0"); + } + printf("\r\n"); +// + if (sysreg_read(&cmd_result, 0xA)!= TERM_OK) { + return TERM_ERR; + } + printf(" VBR %08X", cmd_result); + if (sysreg_read(&cmd_result, 0x8)!= TERM_OK) { + return TERM_ERR; + } + printf(" ATEMP %08X", cmd_result); + if (sysreg_read(&cmd_result, 0x9) != TERM_OK) { + return TERM_ERR; + } + printf(" FAR %08X\r\n", cmd_result); +// + printf(" !CONNNECTED:%d", PIN_NC.read()); + printf(" POWER:%d", PIN_PWR.read()); + printf(" !RESET:%d", PIN_RESET.read()); + printf(" !BUSERR:%d", PIN_BERR.read()); + printf(" BKPT/DSCLK:%d", PIN_BKPT.read()); + printf(" FREEZE:%d", PIN_FREEZE.read()); + printf(" DSO:%d", PIN_DSO.read()); + printf(" DSI:%d", PIN_DSI.read()); + printf("\r\n"); +// + return TERM_OK; } break; @@ -482,7 +584,8 @@ return TERM_ERR; } -void bdm_show_help() { +void bdm_show_help() +{ printf("Just4Trionic BDM Command Menu\r\n"); printf("=============================\r\n"); printf("TD - and DUMP T5 FLASH BIN file\r\n"); @@ -496,7 +599,8 @@ printf("\r\n"); return; } -void bdm_show_full_help() { +void bdm_show_full_help() +{ printf("Just4Trionic BDM Command Menu\r\n"); printf("=============================\r\n"); printf("TD - and DUMP T5 FLASH BIN file\r\n"); @@ -512,6 +616,9 @@ printf("a2 - pull BKPT high\r\n"); printf("a3 - pull RESET low\r\n"); printf("a4 - pull RESET high\r\n"); + printf("a5 - pull BERR low\r\n"); + printf("a6 - pull BERR high\r\n"); + printf("a7 - make BERR an input\r\n"); printf("\r\n"); printf("MCU Management Commands - c\r\n"); printf("===========================\r\n"); @@ -563,6 +670,7 @@ printf("\r\n"); printf("MCU Register Commands - r\r\n"); printf("=========================\r\n"); + printf("rd Display all registers (like BD32)\r\n"); printf("rrRR - read system register RR\r\n"); printf(" 00 - RPC, 01 - PCC, 0B - SR, 0C - USP, 0D - SSP\r\n"); printf(" 0e - SFC, 0f - DFC, 08 - ATEMP, 09 - FAR, 0a - VBR\r\n");
diff -r 682d96ff6d79 -r 1775b4b13232 bdmcpu32.cpp --- a/bdmcpu32.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/bdmcpu32.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -63,8 +63,23 @@ #define BDM_WORDSIZE 0x40 ///< word (2 bytes) #define BDM_LONGSIZE 0x80 ///< long word (4 bytes) +// Bit-Banding memory region constants and macros +#define RAM_BASE 0x20000000 +#define RAM_BB_BASE 0x22000000 +#define PERIHERALS_BASE 0x40000000 +#define PERIHERALS_BB_BASE 0x42000000 +#define LPC1768_AHB_BANK_0 0x2007C000 +#define LPC1768_AHB_BANK_1 0x20080000 +#define LPC1768_AHB_BANK_SIZE 0x00004000 +#define LPC1768_PERIPH_BANK 0x2009C000 +#define LPC1768_PERIPH_SIZE 0x00004000 + +#define varBit(Variable,BitNumber) (*(uint32_t *) (RAM_BB_BASE | (((uint32_t)&Variable - RAM_BASE) << 5) | ((BitNumber) << 2))) +#define periphBit(Peripheral,BitNumber) (*(uint32_t *) (PERIHERALS_BB_BASE | (((uint32_t)&Peripheral - PERIHERALS_BASE) << 5) | ((BitNumber) << 2))) +#define bitAlias(Variable,BitNumber) (*(uint32_t *) (RAM_BB_BASE | (((uint32_t)&Variable - RAM_BASE) << 5) | ((BitNumber) << 2))) + // static variables -static uint32_t bdm_response; ///< result of BDM read/write operation +__attribute__((section("AHBSRAM0"))) static uint32_t bdm_response = 0; ///< result of BDM read/write operation // private functions bool bdm_read(uint32_t* result, uint16_t cmd, const uint32_t* addr); @@ -72,8 +87,14 @@ //bool bdm_read_continue(uint32_t* result, const uint32_t* addr, uint16_t next_cmd); bool bdm_write(const uint32_t* addr, uint16_t cmd, const uint32_t* value); //bool bdm_write_overlap(const uint32_t* addr, uint16_t cmd, const uint32_t* value, uint16_t next_cmd); -void bdm_clk(uint16_t value, uint8_t num_bits); +// +//void bdm_clk(uint16_t value, uint8_t num_bits); +void bdm_clk_slow(uint16_t value, uint8_t num_bits); void bdm_clk_fast(uint16_t value, uint8_t num_bits); +void bdm_clk_turbo(uint16_t value, uint8_t num_bits); +void bdm_clk_nitrous(uint16_t value, uint8_t num_bits); +void (*bdm_clk)(uint16_t value, uint8_t num_bits) = bdm_clk_slow; +// void bdm_clear(); //----------------------------------------------------------------------------- @@ -82,7 +103,8 @@ @return status flag */ -uint8_t stop_chip() { +uint8_t stop_chip() +{ // not connected if (!IS_CONNECTED) { return TERM_ERR; @@ -95,7 +117,11 @@ PIN_BKPT.output(); // wait for target MCU to settle - wait_ms(MCU_SETTLE_TIME); + //wait_ms(MCU_SETTLE_TIME); + timeout.reset(); + timeout.start(); + while (!IN_BDM & (timeout.read_ms() < MCU_SETTLE_TIME)) + timeout.stop(); // check if succeeded if (!IN_BDM) { @@ -113,7 +139,8 @@ @return status flag */ -uint8_t reset_chip() { +uint8_t reset_chip() +{ // not connected if (!IS_CONNECTED) { return TERM_ERR; @@ -148,7 +175,8 @@ @return status flag */ -uint8_t run_chip(const uint32_t* addr) { +uint8_t run_chip(const uint32_t* addr) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -162,9 +190,18 @@ bdm_clk(BDM_GO, CMD_BIT_COUNT); // set BKPT back as input - PIN_BKPT.input(); +// PIN_BKPT.input(); return TERM_OK; + // wait for target MCU to settle + timeout.reset(); + timeout.start(); +// while (!IS_RUNNING & (timeout.read_ms() < MCU_SETTLE_TIME)) + while (IN_BDM & (timeout.read_ms() < MCU_SETTLE_TIME)) + timeout.stop(); + +// return IS_RUNNING ? TERM_OK : TERM_ERR; + return !IN_BDM ? TERM_OK : TERM_ERR; } //----------------------------------------------------------------------------- @@ -173,7 +210,8 @@ @return status flag */ -uint8_t restart_chip() { +uint8_t restart_chip() +{ // not connected if (!IS_CONNECTED) { return TERM_ERR; @@ -188,11 +226,11 @@ PIN_BKPT.output(); PIN_RESET.output(); // wait for target MCU to settle - wait_ms(MCU_SETTLE_TIME); + wait_ms(10*MCU_SETTLE_TIME); // rising edge on RESET line PIN_RESET.write(1); // wait for target MCU to settle - wait_ms(MCU_SETTLE_TIME); + wait_ms(10*MCU_SETTLE_TIME); // set RESET back as an input PIN_RESET.input(); @@ -213,7 +251,8 @@ @return status flag */ -uint8_t step_chip() { +uint8_t step_chip() +{ // not connected if (!IS_CONNECTED) { return TERM_ERR; @@ -246,7 +285,8 @@ /** Pulls BKPT pin low. */ -uint8_t bkpt_low() { +uint8_t bkpt_low() +{ PIN_BKPT.write(0); PIN_BKPT.output(); @@ -257,7 +297,8 @@ /** Pulls BKPT pin high. */ -uint8_t bkpt_high() { +uint8_t bkpt_high() +{ PIN_BKPT.write(1); PIN_BKPT.output(); @@ -268,7 +309,8 @@ /** Pulls RESET pin low. */ -uint8_t reset_low() { +uint8_t reset_low() +{ PIN_RESET.write(0); PIN_RESET.output(); @@ -279,7 +321,8 @@ /** Pulls RESET pin high. */ -uint8_t reset_high() { +uint8_t reset_high() +{ PIN_RESET.write(1); PIN_RESET.output(); @@ -288,6 +331,41 @@ //----------------------------------------------------------------------------- /** + Pulls BERR pin low. +*/ +uint8_t berr_low() +{ + PIN_BERR.write(0); + PIN_BERR.output(); + + return TERM_OK; +} + +//----------------------------------------------------------------------------- +/** + Pulls BERR pin high. +*/ +uint8_t berr_high() +{ + PIN_BERR.write(1); + PIN_BERR.output(); + + return TERM_OK; +} + +//----------------------------------------------------------------------------- +/** + Makes BERR pin an input. +*/ +uint8_t berr_input() +{ + PIN_BERR.write(1); + + return TERM_OK; +} + +//----------------------------------------------------------------------------- +/** Returns byte from the specified memory location; MCU must be in background mode. @@ -296,7 +374,8 @@ @return status flag */ -uint8_t memread_byte(uint8_t* result, const uint32_t* addr) { +uint8_t memread_byte(uint8_t* result, const uint32_t* addr) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -322,7 +401,8 @@ @return status flag */ -uint8_t memread_word(uint16_t* result, const uint32_t* addr) { +uint8_t memread_word(uint16_t* result, const uint32_t* addr) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -348,7 +428,8 @@ @return status flag */ -uint8_t memread_long(uint32_t* result, const uint32_t* addr) { +uint8_t memread_long(uint32_t* result, const uint32_t* addr) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -374,7 +455,8 @@ @return status flag */ -uint8_t memdump_byte(uint8_t* result) { +uint8_t memdump_byte(uint8_t* result) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -400,7 +482,8 @@ @return status flag */ -uint8_t memdump_word(uint16_t* result) { +uint8_t memdump_word(uint16_t* result) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -426,7 +509,8 @@ @return status flag */ -uint8_t memdump_long(uint32_t* result) { +uint8_t memdump_long(uint32_t* result) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -452,7 +536,8 @@ @return status flag */ -uint8_t memwrite_byte(const uint32_t* addr, uint8_t value) { +uint8_t memwrite_byte(const uint32_t* addr, uint8_t value) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -478,7 +563,8 @@ @return status flag */ -uint8_t memwrite_word(const uint32_t* addr, uint16_t value) { +uint8_t memwrite_word(const uint32_t* addr, uint16_t value) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -504,7 +590,8 @@ @return status flag */ -uint8_t memwrite_long(const uint32_t* addr, const uint32_t* value) { +uint8_t memwrite_long(const uint32_t* addr, const uint32_t* value) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -530,7 +617,8 @@ @return status flag */ -uint8_t memfill_byte(uint8_t value) { +uint8_t memfill_byte(uint8_t value) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -556,7 +644,8 @@ @return status flag */ -uint8_t memfill_word(uint16_t value) { +uint8_t memfill_word(uint16_t value) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -582,7 +671,8 @@ @return status flag */ -uint8_t memfill_long(const uint32_t* value) { +uint8_t memfill_long(const uint32_t* value) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -606,7 +696,8 @@ @return status flag */ -uint8_t memread_byte_cmd(const uint32_t* addr) { +uint8_t memread_byte_cmd(const uint32_t* addr) +{ if (!IN_BDM) return TERM_ERR; @@ -628,7 +719,8 @@ @return status flag */ -uint8_t memread_word_cmd(const uint32_t* addr) { +uint8_t memread_word_cmd(const uint32_t* addr) +{ if (!IN_BDM) return TERM_ERR; @@ -651,7 +743,8 @@ @return status flag */ -uint8_t memread_long_cmd(const uint32_t* addr) { +uint8_t memread_long_cmd(const uint32_t* addr) +{ if (!IN_BDM) return TERM_ERR; @@ -673,7 +766,8 @@ @return status flag */ -uint8_t memwrite_byte_cmd(const uint32_t* addr) { +uint8_t memwrite_byte_cmd(const uint32_t* addr) +{ if (!IN_BDM) return TERM_ERR; @@ -695,7 +789,8 @@ @return status flag */ -uint8_t memwrite_word_cmd(const uint32_t* addr) { +uint8_t memwrite_word_cmd(const uint32_t* addr) +{ if (!IN_BDM) return TERM_ERR; @@ -718,7 +813,8 @@ @return status flag */ -uint8_t memwrite_long_cmd(const uint32_t* addr) { +uint8_t memwrite_long_cmd(const uint32_t* addr) +{ if (!IN_BDM) return TERM_ERR; @@ -743,7 +839,8 @@ @return status flag */ -uint8_t memread_read_byte(uint8_t* result, const uint32_t* addr) { +uint8_t memread_read_byte(uint8_t* result, const uint32_t* addr) +{ if (!IN_BDM) return TERM_ERR; // write the optional address @@ -764,7 +861,8 @@ @return status flag */ -uint8_t memread_write_byte(uint8_t* result, const uint32_t* addr) { +uint8_t memread_write_byte(uint8_t* result, const uint32_t* addr) +{ if (!IN_BDM) return TERM_ERR; // write the optional address @@ -785,7 +883,8 @@ @return status flag */ -uint8_t memread_nop_byte(uint8_t* result, const uint32_t* addr) { +uint8_t memread_nop_byte(uint8_t* result, const uint32_t* addr) +{ if (!IN_BDM) return TERM_ERR; // write the optional address @@ -806,7 +905,8 @@ @return status flag */ -uint8_t memwrite_write_byte(const uint32_t* addr, uint8_t value) { +uint8_t memwrite_write_byte(const uint32_t* addr, uint8_t value) +{ if (!IN_BDM) return TERM_ERR; // write the optional address @@ -829,7 +929,8 @@ @return status flag */ -uint8_t memwrite_read_byte(const uint32_t* addr, uint8_t value) { +uint8_t memwrite_read_byte(const uint32_t* addr, uint8_t value) +{ if (!IN_BDM) return TERM_ERR; // write the optional address @@ -852,7 +953,8 @@ @return status flag */ -uint8_t memwrite_nop_byte(const uint32_t* addr, uint8_t value) { +uint8_t memwrite_nop_byte(const uint32_t* addr, uint8_t value) +{ if (!IN_BDM) return TERM_ERR; // write the optional address @@ -877,15 +979,16 @@ @return status flag */ -uint8_t memwrite_word_write_word(const uint32_t* addr, const uint16_t value1, const uint16_t value2) { +uint8_t memwrite_word_write_word(const uint32_t* addr, const uint16_t value1, const uint16_t value2) +{ return (IN_BDM && - bdm_command(BDM_WRITE + BDM_WORDSIZE) && // write command code - bdm_address(addr) && // write the address - bdm_put((uint32_t*)&value1, BDM_WORDSIZE) && // write the first value - bdm_ready(BDM_WRITE + BDM_WORDSIZE) && // wait until MCU responds and overlap the next write command - bdm_address(addr) && // write the address (same address for second word) - bdm_put((uint32_t*)&value2, BDM_WORDSIZE) && // write the second value - bdm_ready(BDM_NOP)) ? TERM_OK : TERM_ERR; // wait until MCU responds + bdm_command(BDM_WRITE + BDM_WORDSIZE) && // write command code + bdm_address(addr) && // write the address + bdm_put((uint32_t*)&value1, BDM_WORDSIZE) && // write the first value + bdm_ready(BDM_WRITE + BDM_WORDSIZE) && // wait until MCU responds and overlap the next write command + bdm_address(addr) && // write the address (same address for second word) + bdm_put((uint32_t*)&value2, BDM_WORDSIZE) && // write the second value + bdm_ready(BDM_NOP)) ? TERM_OK : TERM_ERR; // wait until MCU responds } //----------------------------------------------------------------------------- @@ -901,14 +1004,15 @@ @return status flag */ -uint8_t memwrite_word_read_word(uint16_t* result, const uint32_t* addr, const uint16_t value) { +uint8_t memwrite_word_read_word(uint16_t* result, const uint32_t* addr, const uint16_t value) +{ return (IN_BDM && - bdm_command(BDM_WRITE + BDM_WORDSIZE) && // write command code - bdm_address(addr) && // write the address - bdm_put((uint32_t*)&value, BDM_WORDSIZE) && // write the value - bdm_ready(BDM_READ + BDM_WORDSIZE) && // wait until MCU responds and overlap the next read command - bdm_address(addr) && // write the address (same address for reading the result) - bdm_get((uint32_t*)result, BDM_WORDSIZE, BDM_NOP)) ? TERM_OK : TERM_ERR; // receive the response word + bdm_command(BDM_WRITE + BDM_WORDSIZE) && // write command code + bdm_address(addr) && // write the address + bdm_put((uint32_t*)&value, BDM_WORDSIZE) && // write the value + bdm_ready(BDM_READ + BDM_WORDSIZE) && // wait until MCU responds and overlap the next read command + bdm_address(addr) && // write the address (same address for reading the result) + bdm_get((uint32_t*)result, BDM_WORDSIZE, BDM_NOP)) ? TERM_OK : TERM_ERR; // receive the response word } //----------------------------------------------------------------------------- @@ -920,7 +1024,8 @@ @return status flag */ -uint8_t memget_word(uint16_t* result) { +uint8_t memget_word(uint16_t* result) +{ if (!IN_BDM) return TERM_ERR; // receive the response word @@ -936,7 +1041,8 @@ @return status flag */ -uint8_t memget_long(uint32_t* result) { +uint8_t memget_long(uint32_t* result) +{ if (!IN_BDM) return TERM_ERR; // receive the response words @@ -952,7 +1058,8 @@ @return status flag */ -uint8_t sysreg_read(uint32_t* result, uint8_t reg) { +uint8_t sysreg_read(uint32_t* result, uint8_t reg) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -976,7 +1083,8 @@ @return status flag */ -uint8_t sysreg_write(uint8_t reg, const uint32_t* value) { +uint8_t sysreg_write(uint8_t reg, const uint32_t* value) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -1001,7 +1109,8 @@ @return status flag */ -uint8_t adreg_read(uint32_t* result, uint8_t reg) { +uint8_t adreg_read(uint32_t* result, uint8_t reg) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -1013,7 +1122,6 @@ bdm_clear(); return TERM_ERR; } - return TERM_OK; } @@ -1026,7 +1134,8 @@ @return status flag */ -uint8_t adreg_write(uint8_t reg, const uint32_t* value) { +uint8_t adreg_write(uint8_t reg, const uint32_t* value) +{ // check state if (!IN_BDM) { return TERM_ERR; @@ -1052,7 +1161,8 @@ @return succ / fail */ -bool bdm_read(uint32_t* result, uint16_t cmd, const uint32_t* addr) { +bool bdm_read(uint32_t* result, uint16_t cmd, const uint32_t* addr) +{ *result = 0; // write command code @@ -1107,7 +1217,8 @@ @return succ / fail */ -bool bdm_write(const uint32_t* addr, uint16_t cmd, const uint32_t* value) { +bool bdm_write(const uint32_t* addr, uint16_t cmd, const uint32_t* value) +{ // write command code bdm_clk(cmd, CMD_BIT_COUNT); if (bdm_response > BDM_NOTREADY) { @@ -1151,25 +1262,28 @@ return (bdm_response == BDM_CMDCMPLTE); } -bool bdm_command (uint16_t cmd) { +bool bdm_command (uint16_t cmd) +{ // write command code - bdm_clk_fast(cmd, CMD_BIT_COUNT); + bdm_clk(cmd, CMD_BIT_COUNT); return (bdm_response > BDM_NOTREADY) ? false : true; } -bool bdm_address (const uint32_t* addr) { +bool bdm_address (const uint32_t* addr) +{ // write an address // first word - bdm_clk_fast((uint16_t)((*addr) >> 16), CMD_BIT_COUNT); + bdm_clk((uint16_t)((*addr) >> 16), CMD_BIT_COUNT); if (bdm_response > BDM_NOTREADY) { return false; } // second word - bdm_clk_fast((uint16_t)(*addr), CMD_BIT_COUNT); + bdm_clk((uint16_t)(*addr), CMD_BIT_COUNT); return (bdm_response > BDM_NOTREADY) ? false : true; } -bool bdm_get (uint32_t* result, uint8_t size, uint16_t next_cmd) { +bool bdm_get (uint32_t* result, uint8_t size, uint16_t next_cmd) +{ // receive response words *result = 0; uint8_t wait_cnt; @@ -1178,7 +1292,7 @@ // wait while MCU prepares the response wait_cnt = ERR_COUNT; do { - bdm_clk_fast(next_cmd, CMD_BIT_COUNT); + bdm_clk(next_cmd, CMD_BIT_COUNT); } while (bdm_response == BDM_NOTREADY && --wait_cnt > 0); // save the result @@ -1193,24 +1307,26 @@ return true; } -bool bdm_put (const uint32_t* value, uint8_t size) { +bool bdm_put (const uint32_t* value, uint8_t size) +{ // write the value if (size & BDM_LONGSIZE) { - bdm_clk_fast((uint16_t)((*value) >> 16), CMD_BIT_COUNT); + bdm_clk((uint16_t)((*value) >> 16), CMD_BIT_COUNT); if (bdm_response > BDM_NOTREADY) { return false; } } - bdm_clk_fast((uint16_t)(*value), CMD_BIT_COUNT); + bdm_clk((uint16_t)(*value), CMD_BIT_COUNT); return (bdm_response > BDM_NOTREADY) ? false : true; } -bool bdm_ready (uint16_t next_cmd) { +bool bdm_ready (uint16_t next_cmd) +{ // wait until MCU responds uint8_t wait_cnt = ERR_COUNT; do { // read response - bdm_clk_fast(next_cmd, CMD_BIT_COUNT); + bdm_clk(next_cmd, CMD_BIT_COUNT); } while (bdm_response == BDM_NOTREADY && --wait_cnt > 0); // check if command succeeded @@ -1220,12 +1336,74 @@ //----------------------------------------------------------------------------- /** + Sets the speed at which BDM data is trransferred. + + @param mode SLOW, FAST, TURBO, NITROUS +*/ +void bdm_clk_mode(bdm_speed mode) +{ + switch (mode) { + case NITROUS: + bdm_clk = &bdm_clk_nitrous; + break; + case TURBO: + bdm_clk = &bdm_clk_turbo; + break; + case FAST: + bdm_clk = &bdm_clk_fast; + break; + case SLOW: + default: + bdm_clk = &bdm_clk_slow; + break; + } + return; +} + +//----------------------------------------------------------------------------- +/** Writes a word to target MCU via BDM line and gets the response. @param value value to write @param num_bits value size, bits */ -void bdm_clk(uint16_t value, uint8_t num_bits) { +/* +void bdm_clk(uint16_t value, uint8_t num_bits) +{ +// PIN_BKPT.output(); + PIN_DSI.output(); + // clock the value via BDM + bdm_response = ((uint32_t)value) << (32 - num_bits); + while (num_bits--) { + // falling edge on BKPT/DSCLK + PIN_BKPT.write(0); + // set DSI bit + PIN_DSI.write(bdm_response & 0x80000000); + bdm_response <<= 1; + // read DSO bit + bdm_response |= PIN_DSO.read(); + // short delay +// for (uint8_t c = 1; c; c--); +// wait_us(1); + // rising edge on BKPT/DSCLK + PIN_BKPT.write(1); + // short delay +// for (uint8_t c = 1; c; c--); +// wait_us(1); + } + PIN_DSI.input(); +} +*/ + +//----------------------------------------------------------------------------- +/** + Writes a word to target MCU via BDM line and gets the response. + + @param value value to write + @param num_bits value size, bits +*/ + +void bdm_clk_slow(uint16_t value, uint8_t num_bits) { // PIN_BKPT.output(); PIN_DSI.output(); // clock the value via BDM @@ -1246,47 +1424,12 @@ // rising edge on BKPT/DSCLK PIN_BKPT.write(1); // short delay - for (uint8_t c = 1; c; c--); +// for (uint8_t c = 1; c; c--); // wait_us(1); } PIN_DSI.input(); } - -//----------------------------------------------------------------------------- -/** - Writes a word to target MCU via BDM line and gets the response. - - @param value value to write - @param num_bits value size, bits -*/ -/* -void bdm_clk_fast(uint16_t value, uint8_t num_bits) { -// PIN_BKPT.output(); - PIN_DSI.output(); - // clock the value via BDM - bdm_response = ((uint32_t)value) << (32 - num_bits); -// bool dsi; - while (num_bits--) { - - // falling edge on BKPT/DSCLK - PIN_BKPT.write(0); - // set DSI bit - PIN_DSI.write(bdm_response & 0x80000000); - bdm_response <<= 1; - // read DSO bit - bdm_response |= PIN_DSO.read(); - // short delay -// for (uint8_t c = 1; c; c--); -// wait_us(1); - // rising edge on BKPT/DSCLK - PIN_BKPT.write(1); - // short delay - for (uint8_t c = 1; c; c--); -// wait_us(1); - } - PIN_DSI.input(); -} -//*/ +// //----------------------------------------------------------------------------- /** @@ -1299,60 +1442,123 @@ @param num_bits value size, bits */ -//* -void bdm_clk_fast(uint16_t value, uint8_t num_bits) { +void bdm_clk_fast(uint16_t value, uint8_t num_bits) +{ - //Set BKPT -// PIN_BKPT.write(1); -// LPC_GPIO2->FIOSET = (1 << 4); -// PIN_BKPT.output(); - -// uint32_t mask = LPC_GPIO2->FIOMASK; -// LPC_GPIO2->FIOMASK = ~((1 << 4) | (1 << 2)); //Make DSI an output LPC_GPIO2->FIODIR |= (1 << 2); // clock the value via BDM bdm_response = ((uint32_t)value) << (32 - num_bits); + // Clock BDM Data in from DSO and out to DSI while (num_bits--) { // set DSI bit -// LPC_GPIO2->FIOPIN = ((bool)(bdm_response & 0x80000000) << 2); - //if (bdm_response & 0x80000000) - // LPC_GPIO2->FIOSET = (1 << 2); - //else - // LPC_GPIO2->FIOCLR = (1 << 2); - (bdm_response & 0x80000000) ? LPC_GPIO2->FIOSET = (1 << 2) : LPC_GPIO2->FIOCLR = (1 << 2); - - //*((volatile unsigned int *)0x23380a88) = (bool)(bdm_response & 0x80000000); - //*((volatile unsigned int *)0x23380a88) = bdm_response >> 31; - //*((volatile unsigned int *)0x23380a9c) = 1; - //used to set the P2.7 pin is slower (about 3 cycles) than this one - //GPIO2->FIOPIN=0x80 - // falling edge on BKPT/DSCLK + // falling edge on BKPT/DSCLK LPC_GPIO2->FIOCLR = (1 << 4); - //*((volatile unsigned int *)0x23380a90) = 0; -// for (uint8_t c = 1; c; c--); -// // read DSO bit + // read DSO bit // (bdm_response <<= 1) |= (bool)((LPC_GPIO0->FIOPIN) & (1 << 11)); -- OLD CONNECTION to PIN 27 (bdm_response <<= 1) |= (bool)((LPC_GPIO2->FIOPIN) & (1 << 1)); - //(bdm_response <<= 1) |= *((volatile unsigned int *)0x23380a84); // rising edge on BKPT/DSCLK LPC_GPIO2->FIOSET = (1 << 4); - //*((volatile unsigned int *)0x23380a90) = 1; + // introduce a delay to insure that BDM clock isn't too fast + for (uint8_t c = 9; c; c--); // was 5 + } + //Make DSI an input + LPC_GPIO2->FIODIR &= ~(1 << 2); +} +//----------------------------------------------------------------------------- + +/** + Writes a word to target MCU via BDM line and gets the response. + This 'turbo' version uses 'bit-banding' to read and write individual + bits directly. This should be faster than the 'fast' version because + the complex calculation to find the address of the BDM word 'bit-band' + region is only done once per call rather than several, simpler, + calculations and bit-shifts that the slow and fast functions do for + each bit. + + The 68332 must have been 'prepped' before using the 'turbo' version + because the BDM interface can go twice as fast once the 68332 + clock is increased from 8 MHz to 16 MHz + + @param value value to write + @param num_bits value size, bits +*/ + +void bdm_clk_turbo(uint16_t value, uint8_t num_bits) +{ + //Make DSI an output + LPC_GPIO2->FIODIR |= (1 << 2); + bdm_response = (uint32_t)value; + // calculate a pointer to the bitband alias region address of the most significant bit of the BDM word (NOTE num_bits-1) + uint32_t *bdm_response_bit_alias = &bitAlias(bdm_response,num_bits-1); + // Clock BDM Data in from DSO and out to DSI + while (num_bits--) { + // set DSI bit (port 2, bit 2) + bitAlias(LPC_GPIO2->FIOPIN,2) = *bdm_response_bit_alias; + // falling edge on BKPT/DSCLK + LPC_GPIO2->FIOCLR = (1 << 4); + // read DSO bit (port 2, bit 1) ( -- OLD CONNECTION WAS to PIN 27 -- port 2, bit 11) + *bdm_response_bit_alias = bitAlias(LPC_GPIO2->FIOPIN,1); + // introduce a delay to insure that BDM clock isn't too fast + for (uint8_t c = 2; c; c--); // was 2 + // rising edge on BKPT/DSCLK + LPC_GPIO2->FIOSET = (1 << 4); + // point to the next bit (pointer will be decremented by sizeof pointer) + bdm_response_bit_alias--; + // introduce a delay to insure that BDM clock isn't too fast + for (uint8_t c = 7; c; c--); // was 2 + } + //Make DSI an input + LPC_GPIO2->FIODIR &= ~(1 << 2); +} +//----------------------------------------------------------------------------- + +/** + Writes a word to target MCU via BDM line and gets the response. + + This 'nitrous' version uses is the same as the 'turbo' version but + without minimal delays and will only work with the faster CPU in T8 + once the ECU has been 'prepped' + + @param value value to write + @param num_bits value size, bits +*/ + +void bdm_clk_nitrous(uint16_t value, uint8_t num_bits) +{ + //Make DSI an output + LPC_GPIO2->FIODIR |= (1 << 2); + bdm_response = (uint32_t)value; + // calculate a pointer to the bitband alias region address of the most significant bit of the BDM word (NOTE num_bits-1) + uint32_t *bdm_response_bit_alias = &bitAlias(bdm_response,num_bits-1); + // Clock BDM Data in from DSO and out to DSI + while (num_bits--) { + // set DSI bit (port 2, bit 2) + bitAlias(LPC_GPIO2->FIOPIN,2) = *bdm_response_bit_alias; + // falling edge on BKPT/DSCLK + LPC_GPIO2->FIOCLR = (1 << 4); + // read DSO bit (port 2, bit 1) ( -- OLD CONNECTION WAS to PIN 27 -- port 2, bit 11) + *bdm_response_bit_alias = bitAlias(LPC_GPIO2->FIOPIN,1); + // introduce a delay to insure that BDM clock isn't too fast + //for (uint8_t c = 2; c; c--); + // rising edge on BKPT/DSCLK + LPC_GPIO2->FIOSET = (1 << 4); + // point to the next bit (pointer will be decremented by sizeof pointer) + bdm_response_bit_alias--; + // introduce a delay to insure that BDM clock isn't too fast for (uint8_t c = 1; c; c--); } //Make DSI an input LPC_GPIO2->FIODIR &= ~(1 << 2); -// LPC_GPIO2->FIOMASK = mask; } +//----------------------------------------------------------------------------- -//*/ - -//----------------------------------------------------------------------------- /** Clears the BDM interface after errors. */ -void bdm_clear() { +void bdm_clear() +{ bdm_clk (BDM_NOP, CMD_BIT_COUNT); bdm_clk (BDM_NOP, CMD_BIT_COUNT); bdm_clk (BDM_NOP, CMD_BIT_COUNT);
diff -r 682d96ff6d79 -r 1775b4b13232 bdmcpu32.h --- a/bdmcpu32.h Wed Sep 11 11:55:51 2013 +0000 +++ b/bdmcpu32.h Sat Apr 25 17:07:08 2015 +0000 @@ -31,9 +31,9 @@ // MCU status macros #ifndef IGNORE_VCC_PIN // #define IS_CONNECTED (PIN_PWR) - #define IS_CONNECTED (bool)((LPC_GPIO1->FIOPIN) & (1 << 30)) // PIN_POWER is p19 p1.30 +#define IS_CONNECTED (bool)((LPC_GPIO1->FIOPIN) & (1 << 30)) // PIN_POWER is p19 p1.30 #else - #define IS_CONNECTED true +#define IS_CONNECTED true #endif // IGNORE_VCC_PIN //#define IN_BDM (PIN_FREEZE) @@ -51,6 +51,18 @@ uint8_t bkpt_high(); uint8_t reset_low(); uint8_t reset_high(); +uint8_t berr_low(); +uint8_t berr_high(); +uint8_t berr_input(); + +// BDM Clock speed +enum bdm_speed { + SLOW, + FAST, + TURBO, + NITROUS +}; +void bdm_clk_mode(bdm_speed mode); // memory uint8_t memread_byte(uint8_t* result, const uint32_t* addr);
diff -r 682d96ff6d79 -r 1775b4b13232 bdmdriver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bdmdriver.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -0,0 +1,453 @@ +/******************************************************************************* + +bdmdriver.cpp +(c) 2014 by Sophie Dexter + +BD32 like 'syscall' processor for BDM resident driver functions + +******************************************************************************** + +WARNING: Use at your own risk, sadly this software comes with no guarantees. +This software is provided 'free' and in good faith, but the author does not +accept liability for any damage arising from its use. + +*******************************************************************************/ + +#include "bdmdriver.h" + +FILE *fp = NULL; + +//private functions +bool bdmSyscallPuts (void); +bool bdmSyscallPutchar(void); +bool bdmSyscallGets(void); +bool bdmSyscallGetchar(void); +bool bdmSyscallGetstat(void); +bool bdmSyscallFopen(void); +bool bdmSyscallFclose(void); +bool bdmSyscallFread(void); +bool bdmSyscallFwrite(void); +bool bdmSyscallFtell(void); +bool bdmSyscallFseek(void); +bool bdmSyscallFgets(void); +bool bdmSyscallFputs(void); +bool bdmSyscallEval(void); +bool bdmSyscallFreadsrec(void); + +//----------------------------------------------------------------------------- +/** +Loads the contenst of a uint8_t array into the target's memory starting at the +specified address + +@param dataArray[] uint8_t array conataining data for BDM tartget +@param startAddress Start address to load BDM memory to + +@return succ / fail +*/ +bool bdmLoadMemory(uint8_t dataArray[], uint32_t startAddress, uint32_t dataArraySize) +{ +// for (uint32_t i = 0; i < sizeof(residentDriver); i++) { +// if(memwrite_byte(&driverAddress, residentDriver[i]) != TERM_OK) return false; +// driverAddress++; +// } + uint32_t driverSize = dataArraySize; + uint32_t driverOffset = 0; + uint32_t driverLong = 0; + uint16_t driverWord = 0; + uint8_t driverByte = 0; + // Check that there is something to send + if (driverSize == 0) return false; + // Send the first 1-4 bytes as efficiently as possible over BDM + switch (driverSize % 4) { + case 3: + driverWord = (dataArray[driverOffset++] << 8) | dataArray[driverOffset++]; + if(memwrite_word(&startAddress, driverWord) != TERM_OK) return false; + driverByte = dataArray[driverOffset++]; + if(memfill_byte(driverByte) != TERM_OK) return false; + break; + case 2: + driverWord = (dataArray[driverOffset++] << 8) | dataArray[driverOffset++]; + if(memwrite_word(&startAddress, driverWord) != TERM_OK) return false; + break; + case 1: + driverByte = dataArray[driverOffset++]; + if(memwrite_byte(&startAddress, driverByte) != TERM_OK) return false; + break; + case 0: + for (uint32_t i = 0; i < 4; i++) { + driverLong <<= 8; + driverLong |= dataArray[driverOffset++]; + } + if(memwrite_long(&startAddress, &driverLong) != TERM_OK) return false; + break; +// default: // There shouldn't be a default case + } + // transfer the rest as 'longs' to make best use of BDM transfer speed +// printf("driverOffset 0x%08x, driverSize 0x%08x\r\n", driverOffset, driverSize); + while (driverOffset < driverSize) { + for (uint32_t i = 0; i < 4; i++) { + driverLong <<= 8; + driverLong |= dataArray[driverOffset++]; + } + if(memfill_long(&driverLong) != TERM_OK) return false; + } +// printf("driverOffset 0x%08x, driverSize 0x%08x\r\n", driverOffset, driverSize); + return true; +} + +//----------------------------------------------------------------------------- +/** +Starts a BDM resident driver at the current PC (Program Counter) or a specified +if given. The driver is allowed to run for a maximum period, maxtime, specified +as milliseconds. + +@param addr BDM driver address (0 to continue from current PC) +@param maxtime how long to allow driver to execute (milliseconds) + +@return succ / fail +*/ +bool bdmRunDriver(uint32_t addr, uint32_t maxtime) +{ + // Start BDM driver and allow it up to 200 milliseconds to update 256 Bytes + // Upto 25 pulses per byte, 16us per pulse, 256 Bytes + // 25 * 16 * 256 = 102,400us plus overhead for driver code execution time + // Allowing up to 200 milliseconds seems like a good allowance. + if (run_chip(&addr) != TERM_OK) { + printf("Failed to start BDM driver.\r\n"); + return false; + } + timeout.reset(); + timeout.start(); + // T5 ECUs' BDM interface seem to have problems when the running the CPU and + // sometimes shows the CPU briefly switching between showing BDM mode or that + // the CPU is running. + // I 'debounce' the interface state to workaround this erratic bahaviour + for (uint32_t debounce = 0; debounce < 5; debounce++) { + while (IS_RUNNING) { + debounce = 0; + if (timeout.read_ms() > maxtime) { + printf("Driver did not return to BDM mode.\r\n"); + timeout.stop(); + return false; + } + } + wait_us(1); + } + timeout.stop(); + return true; +} + + +//----------------------------------------------------------------------------- +/** +Starts a BDM resident driver at the current PC (Program Counter) or a specified +if given. The driver is allowed to run for a maximum period, maxtime, specified +as milliseconds. + +@param addr BDM driver address (0 to continue from current PC) +@param maxtime how long to allow driver to execute (milliseconds) + +@return DONE, CONTINUE, ERROR + +*/ + +uint8_t bdmProcessSyscall(void) +{ + + uint32_t syscall = 0xFFFFFFFF; + if (adreg_read(&syscall, 0x0) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return ERROR; + } + syscall &= 0xFF; +// printf("SYSCALL 0x%08x\r\n", syscall); + switch (syscall) { + case QUIT: + if (adreg_read(&syscall, 0x1) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return ERROR; + } + return DONE; + case PUTS: + if (!bdmSyscallPuts()) return ERROR; + break; + case PUTCHAR: + if (!bdmSyscallPutchar()) return ERROR; + break; + case GETS: + if (!bdmSyscallGets()) return ERROR; + break; + case GETCHAR: + if (!bdmSyscallGetchar()) return ERROR; + break; + case GETSTAT: + if (!bdmSyscallGetstat()) return ERROR; + break; + case FOPEN: + if (!bdmSyscallFopen()) return ERROR; + break; + case FCLOSE: + if (!bdmSyscallFclose()) return ERROR; + break; + case FREAD: + if (!bdmSyscallFread()) return ERROR; + break; + case FWRITE: + if (!bdmSyscallFwrite()) return ERROR; + break; + case FTELL: + if (!bdmSyscallFtell()) return ERROR; + break; + case FSEEK: + if (!bdmSyscallFseek()) return ERROR; + break; + case FGETS: + if (!bdmSyscallFgets()) return ERROR; + break; + case FPUTS: + if (!bdmSyscallFputs()) return ERROR; + break; + case EVAL: + if (!bdmSyscallEval()) return ERROR; + break; + case FREADSREC: + if (!bdmSyscallFreadsrec()) return ERROR; + break; + default: + printf("!!! Unknown BDM Syscall !!!\r\n"); + return ERROR; + } + return CONTINUE; +} + + +bool bdmSyscallPuts() +{ + uint32_t bdm_string_address = 0, bdm_return = 0; + if (adreg_read(&bdm_string_address, 0x8) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } +// a loop to read chars from BDM into a string + char bdm_string[256]; + for (uint32_t i = 0; i < sizeof(bdm_string); i++) { + bdm_string[i] = 0x0; + } + uint32_t i = 0; + do { + if (memread_byte((uint8_t*)(bdm_string+i), &bdm_string_address) != TERM_OK) { + printf("Failed to read BDM memory at address 0x%08x.\r\n", bdm_string_address); + return false; + } + bdm_string_address++; + } while ( (bdm_string[i++] != 0x0) && (i < sizeof(bdm_string)) ); +// print the string to stdout (USB virtual serial port) + printf(bdm_string); +// Send BDM return code in D0 (always 0x0 for PUTS) + if (adreg_write(0x0, &bdm_return) != TERM_OK) { + printf("Failed to write BDM register.\r\n"); + return false; + } + return true; +} + +bool bdmSyscallPutchar() +{ + uint32_t bdm_character = 0, bdm_return = 0; + // read char from BDM + if (adreg_read(&bdm_character, 0x1) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } + // print the char to USB virtual serial port + pc.putc((char)bdm_character); + // Send BDM return code in D0 (always 0x0 for PUTCHAR) + if (adreg_write(0x0, &bdm_return) != TERM_OK) { + printf("Failed to write BDM register.\r\n"); + return false; + } + return true; +} + +bool bdmSyscallGets() +{ + printf("BDM GETS Syscall not supported.\r\n"); + return ERROR; +} + +bool bdmSyscallGetchar() +{ + // get a char from the USB virtual serial port + uint32_t bdm_return = (uint32_t)pc.getc(); + // Send the char to BDM in D0 + if (adreg_write(0x0, &bdm_return) != TERM_OK) { + printf("Failed to write BDM register.\r\n"); + return false; + } + return true; +} + +bool bdmSyscallGetstat(void) +{ + printf("BDM GETSTAT Syscall not supported.\r\n"); + return false; +} + +bool bdmSyscallFopen(void) +{ + uint32_t bdm_filename_address = 0, bdm_filemode_address = 0; + if (adreg_read(&bdm_filename_address, 0x8) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } + if (adreg_read(&bdm_filemode_address, 0x9) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } + // a loop to initialise the strings to 0x0 + char filename_string[80], filemode_string[5]; + uint32_t i = 0; + for (i = 0; i < sizeof(filename_string); i++) { + filename_string[i] = 0x0; + } + for (i = 0; i < sizeof(filemode_string); i++) { + filemode_string[i] = 0x0; + } + i = 0; + // a loop to read chars from BDM into a string + do { + if (memread_byte((uint8_t*)filename_string[i], &bdm_filename_address) != TERM_OK) { + printf("Failed to read BDM memory at address 0x%08x.\r\n", bdm_filename_address); + return false; + } + bdm_filename_address++; + } while ( (filename_string[i++] != 0x0) && (i < sizeof(filename_string)) ); + do { + if (memread_byte((uint8_t*)filemode_string[i], &bdm_filemode_address) != TERM_OK) { + printf("Failed to read BDM memory at address 0x%08x.\r\n", bdm_filemode_address); + return false; + } + bdm_filemode_address++; + } while ( (filemode_string[i++] != 0x0) && (i < sizeof(filemode_string)) ); + // Open the file + fp = fopen(filename_string, filemode_string); // Open "modified.hex" on the local file system for reading + // Send BDM return code in D0 + if (adreg_write(0x0, (uint32_t*)fp) != TERM_OK) { + printf("Failed to write BDM register.\r\n"); + return false; + } + return true; +} + +bool bdmSyscallFclose(void) +{ + uint32_t close_result = fclose(fp); + // Send BDM return code in D0 + if (adreg_write(0x0, &close_result) != TERM_OK) { + printf("Failed to write BDM register.\r\n"); + return false; + } + return true; +} + +bool bdmSyscallFread(void) +{ + uint32_t bdm_byte_count, bdm_buffer_address, bdm_file_handle = NULL; + if (adreg_read(&bdm_file_handle, 0x1) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } + if (adreg_read(&bdm_byte_count, 0x2) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } + if (adreg_read(&bdm_buffer_address, 0x9) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } + uint32_t bytes_read = fread(&file_buffer[0],1,bdm_byte_count,fp); + for (uint32_t byte_count = 0; byte_count < bytes_read; byte_count++) { + if (byte_count == 0x0) { + if(memwrite_byte(&bdm_buffer_address, file_buffer[byte_count]) != TERM_OK) return false; + } else { + if(memfill_byte(file_buffer[byte_count]) != TERM_OK) return false; + } + } + if (adreg_write(0x0, &bytes_read) != TERM_OK) { + printf("Failed to write BDM register.\r\n"); + return false; + } + return true; +} + +bool bdmSyscallFwrite(void) +{ + printf("BDM FWRITE Syscall not supported.\r\n"); + return false; +} + +bool bdmSyscallFtell(void) +{ + printf("BDM FTELL Syscall not supported.\r\n"); + return false; +} + +bool bdmSyscallFseek(void) +{ + uint32_t bdm_byte_offset, bdm_file_origin, bdm_file_handle = NULL; + if (adreg_read(&bdm_file_handle, 0x1) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } + if (adreg_read(&bdm_byte_offset, 0x2) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } + if (adreg_read(&bdm_file_origin, 0x3) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } + uint32_t origin; + switch (bdm_file_origin) { + case 0x2: + origin = SEEK_END; + break; + case 0x1: + origin = SEEK_CUR; + break; + case 0x0: + default: + origin = SEEK_SET; + break; + } + uint32_t fseek_result = fseek ( fp ,bdm_byte_offset ,origin ); + if (adreg_write(0x0, &fseek_result) != TERM_OK) { + printf("Failed to write BDM register.\r\n"); + return false; + } + return true; +} + +bool bdmSyscallFgets(void) +{ + printf("BDM FGETS Syscall not supported.\r\n"); + return false; +} + +bool bdmSyscallFputs(void) +{ + printf("BDM FPUTS Syscall not supported.\r\n"); + return false; +} + +bool bdmSyscallEval(void) +{ + printf("BDM EVAL Syscall not supported.\r\n"); + return false; +} + +bool bdmSyscallFreadsrec(void) +{ + printf("BDM FREADSREC Syscall not supported.\r\n"); + return false; +}
diff -r 682d96ff6d79 -r 1775b4b13232 bdmdriver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bdmdriver.h Sat Apr 25 17:07:08 2015 +0000 @@ -0,0 +1,55 @@ +/******************************************************************************* + +bdmdriver.cpp +(c) 2014 by Sophie Dexter + +******************************************************************************** + +WARNING: Use at your own risk, sadly this software comes with no guarantees. +This software is provided 'free' and in good faith, but the author does not +accept liability for any damage arising from its use. + +*******************************************************************************/ + +#ifndef __BDMDRIVER_H__ +#define __BDMDRIVER_H__ + +#include "mbed.h" + +#include "common.h" +#include "bdmcpu32.h" + +// public functions +bool bdmLoadMemory(uint8_t dataArray[], uint32_t loadAddress, uint32_t dataArraySize); +bool bdmRunDriver(uint32_t addr, uint32_t maxtime); +uint8_t bdmProcessSyscall(void); + +enum bdmSyscall { + QUIT = 0, + PUTS = 1, + PUTCHAR = 2, + GETS = 3, + GETCHAR = 4, + GETSTAT = 5, + FOPEN = 6, + FCLOSE = 7, + FREAD = 8, + FWRITE = 9, + FTELL = 10, + FSEEK = 11, + FGETS = 12, + FPUTS = 13, + EVAL = 14, + FREADSREC = 15 +}; + +enum bdmSyscallResult { + DONE, + CONTINUE, + ERROR + }; + +#endif // __BDMDRIVER_H__ +//----------------------------------------------------------------------------- +// EOF +//----------------------------------------------------------------------------- \ No newline at end of file
diff -r 682d96ff6d79 -r 1775b4b13232 bdmtrionic.cpp --- a/bdmtrionic.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/bdmtrionic.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -65,6 +65,7 @@ bool flash_am28(const uint32_t* addr, uint16_t value); bool get_flash_id(uint8_t* make, uint8_t* type); +bool run_bdm_driver(uint32_t addr, uint32_t maxtime); //----------------------------------------------------------------------------- /** @@ -160,7 +161,14 @@ flash_size = T7FLASHSIZE; break; case AMD29F010: - printf("I have found AMD29F010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n"); + case SST39SF010: + case AMICA29010L: + printf("I have found 29/39F010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n"); + reset_func = &reset_am29; + flash_size = T55FLASHSIZE; + break; + case ATMEL29C010: + printf("I have found Atmel 29C010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n"); reset_func = &reset_am29; flash_size = T55FLASHSIZE; break; @@ -176,6 +184,11 @@ reset_func = &reset_am28; flash_size = T52FLASHSIZE; break; + case ATMEL29C512: + printf("I have found Atmel 29C512 type FLASH chips; I must be connected to a repaired T5.2 ECU :-)\r\n"); + reset_func = &reset_am28; + flash_size = T52FLASHSIZE; + break; default: // unknown flash type printf("I could not work out what FLASH chips or TRIONIC ECU I am connected to :-(\r\n"); @@ -207,15 +220,11 @@ while (byte_count < FILE_BUF_LENGTH) { // get long word if (memget_long(&long_value) != TERM_OK) return TERM_ERR; - addr += 4; // send memory value to file_buffer before saving to mbed 'disk' - file_buffer[byte_count] = ((uint8_t)(long_value >> 24)); - file_buffer[byte_count+1] = ((uint8_t)(long_value >> 16)); - file_buffer[byte_count+2] = ((uint8_t)(long_value >> 8)); - file_buffer[byte_count+3] = ((uint8_t)long_value); - byte_count +=4; - // make the activity led twinkle - ACTIVITYLEDON; + file_buffer[byte_count++] = ((uint8_t)(long_value >> 24)); + file_buffer[byte_count++] = ((uint8_t)(long_value >> 16)); + file_buffer[byte_count++] = ((uint8_t)(long_value >> 8)); + file_buffer[byte_count++] = ((uint8_t)long_value); } fwrite(file_buffer, 1, FILE_BUF_LENGTH, fp); if (ferror (fp)) { @@ -224,8 +233,11 @@ return TERM_ERR; } printf("%6.2f\r", 100*(float)addr/(float)flash_size ); + // make the activity led twinkle + ACTIVITYLEDON; + addr += FILE_BUF_LENGTH; } - printf("\n"); + printf("100.00\r\n"); // should 'clear' the BDM connection here but bdm_clear won't compile from here // instead do a memread (or anything really) but ignore the result because it's not needed for anything memread_long(&long_value, &addr); @@ -408,11 +420,19 @@ flash_size = T7FLASHSIZE; break; case AMD29F010: - printf("I have found AMD29F010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n"); + case SST39SF010: + case AMICA29010L: + printf("I have found 29/39F010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n"); reset_func = &reset_am29; flash_func = &flash_am29; flash_size = T55FLASHSIZE; break; + case ATMEL29C010: + printf("I have found Atmel 29C010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n"); + reset_func = &reset_am29; + flash_func = NULL; + flash_size = T55FLASHSIZE; + break; case AMD28F010: case INTEL28F010: printf("I have found 28F010 type FLASH chips; I must be connected to a T5.5 ECU :-)\r\n"); @@ -427,20 +447,26 @@ flash_func = &flash_am28; flash_size = T52FLASHSIZE; break; + case ATMEL29C512: + printf("I have found Atmel 29C512 type FLASH chips; I must be connected to a repaired T5.2 ECU :-)\r\n"); + reset_func = &reset_am29; + flash_func = NULL; + flash_size = T52FLASHSIZE; + break; default: // unknown flash type printf("I could not work out what FLASH chips or TRIONIC ECU I am connected to :-(\r\n"); return TERM_ERR; } - // reset the FLASH chips - printf("Reset the FLASH chip(s) to prepare them for Erasing\r\n"); if (!reset_func()) return TERM_ERR; + printf("Checking the FLASH BIN file...\r\n"); - FILE *fp = fopen("/local/modified.hex", "r"); // Open "modified.hex" on the local file system for reading + FILE *fp = fopen("/local/modified.bin", "r"); // Open "modified.bin" on the local file system for reading +// FILE *fp = fopen("/local/original.bin", "r"); // Open "original.bin" on the local file system for reading if (!fp) { - printf("Error: I could not find the BIN file MODIFIED.HEX\r\n");; + printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");; return TERM_ERR; } // obtain file size - it should match the size of the FLASH chips: @@ -449,17 +475,13 @@ rewind (fp); // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU - uint8_t stack_byte = 0; + uint8_t stack_bytes[4] = {0, 0, 0, 0}; uint32_t stack_long = 0; - if (!fread(&stack_byte,1,1,fp)) return TERM_ERR; - stack_long |= (stack_byte << 24); - if (!fread(&stack_byte,1,1,fp)) return TERM_ERR; - stack_long |= (stack_byte << 16); - if (!fread(&stack_byte,1,1,fp)) return TERM_ERR; - stack_long |= (stack_byte << 8); - if (!fread(&stack_byte,1,1,fp)) return TERM_ERR; - stack_long |= stack_byte; + if (!fread(&stack_bytes[0],1,4,fp)) return TERM_ERR; rewind (fp); + for(uint32_t i=0; i<4; i++) { + (stack_long <<= 8) |= stack_bytes[i]; + } if (flash_size == T52FLASHSIZE && (file_size != T52FLASHSIZE || stack_long != T5POINTER)) { fclose(fp); @@ -486,86 +508,801 @@ return TERM_ERR; } - timer.reset(); - timer.start(); - uint32_t curr_addr = 0; switch (type) { - // AM29Fxxx chips (retrofitted to Trionic 5.x; original to T7) case AMD29BL802C: - case AMD29F400B: case AMD29F400T: case AMD29F010: - printf("Erasing 29BL802/F400/010 type FLASH chips...\r\n"); - if (!erase_am29()) { - printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n"); - return TERM_ERR; - } - break; - // AM28F010 chip (Trionic 5.x original) + case SST39SF010: + case AMICA29010L: + case ATMEL29C010: case AMD28F010: case INTEL28F010: case AMD28F512: case INTEL28F512: - printf("Erasing 28F010/512 type FLASH chips...\r\n"); - if (!erase_am28(&curr_addr, &flash_size)) { - printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n"); - return TERM_ERR; - } - break; - default: - // unknown flash type - shouldn't get here hence "Strange!" - printf("Strange! I couldn't work out how to erase the FLASH chips in the TRIONIC ECU that I am connected to :-(\r\n"); - return TERM_ERR; - } + case ATMEL29C512: { + // BDM FLASH Driver + /* + uint8_t flashDriver5[] = {\ + 0x60,0x00,0x04,0x08,\ + 0x7C,0x2F,0x2D,0x5C,0x2A,0x0D,0x00,0x00,\ + 0x02,0x03,0x00,0x03,0x41,0xFA,0xFF,0xF6,\ + 0x10,0xBB,0x30,0xEE,0x70,0x01,0x52,0x43,\ + 0x4E,0x75,\ + 0x20,0x7C,0x00,0xFF,0xFA,0x00,0x08,0x10,\ + 0x00,0x04,0x66,0x4E,0xD0,0xFC,0x00,0x04,\ + 0x10,0xFC,0x00,0x7F,0x08,0x10,0x00,0x03,\ + 0x67,0xFA,0xD0,0xFC,0x00,0x1C,0x42,0x10,\ + 0xD0,0xFC,0x00,0x23,0x30,0xBC,0x3F,0xFF,\ + 0xD0,0xFC,0x00,0x04,0x70,0x07,0x30,0xC0,\ + 0x30,0xBC,0x68,0x70,0xD0,0xFC,0x00,0x06,\ + 0x30,0xC0,0x30,0xFC,0x30,0x30,0x30,0xC0,\ + 0x30,0xBC,0x50,0x30,0xD0,0xFC,0x01,0xBE,\ + 0x70,0x40,0x30,0xC0,0x30,0x80,0x30,0x3C,\ + 0x55,0xF0,0x4E,0x71,0x51,0xC8,0xFF,0xFC,\ + 0x60,0x18,0xD0,0xFC,0x00,0x08,0x30,0xFC,\ + 0x69,0x08,0x08,0x10,0x00,0x09,0x67,0xFA,\ + 0x31,0x3C,0x68,0x08,0xD0,0xFC,0x00,0x48,\ + 0x42,0x50,0x4E,0x75,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x2C,0x3C,0x00,0x00,0x55,0x55,\ + 0x2E,0x3C,0x00,0x00,0xAA,0xAA,0x2A,0x46,\ + 0x53,0x8D,0x2C,0x47,0x45,0xF8,0x00,0x00,\ + 0x47,0xFA,0xFF,0xDE,0x3C,0x87,0x3A,0x86,\ + 0x3C,0xBC,0x90,0x90,0x36,0xDA,0x36,0x92,\ + 0x3C,0x87,0x3A,0x86,0x3C,0xBC,0xF0,0xF0,\ + 0x20,0x3A,0xFF,0xC6,0x72,0x02,0x48,0x41,\ + 0x74,0x01,0x0C,0x00,0x00,0x25,0x67,0x50,\ + 0x0C,0x00,0x00,0xB8,0x67,0x4A,0x74,0x04,\ + 0x0C,0x00,0x00,0x5D,0x67,0x42,0x74,0x01,\ + 0xE3,0x99,0x0C,0x00,0x00,0xA7,0x67,0x38,\ + 0x0C,0x00,0x00,0xB4,0x67,0x32,0x74,0x02,\ + 0x0C,0x00,0x00,0x20,0x67,0x2A,0x0C,0x00,\ + 0x00,0xA4,0x67,0x24,0x0C,0x00,0x00,0xB5,\ + 0x67,0x1E,0x74,0x04,0x0C,0x00,0x00,0xD5,\ + 0x67,0x16,0x74,0x03,0xE3,0x99,0x0C,0x00,\ + 0x00,0x23,0x67,0x0C,0xE3,0x99,0x0C,0x00,\ + 0x00,0x81,0x67,0x04,0x72,0x00,0x74,0x00,\ + 0x47,0xFA,0xFF,0x6A,0x26,0x81,0x47,0xFA,\ + 0xFF,0x68,0x16,0x82,0x4E,0x75,\ + 0x45,0x72,0x61,0x73,0x69,0x6E,0x67,0x20,\ + 0x46,0x4C,0x41,0x53,0x48,0x20,0x63,0x68,\ + 0x69,0x70,0x73,0x0D,0x0A,0x00,0x41,0xFA,\ + 0xFF,0xE8,0x70,0x01,0x12,0x3A,0xFF,0x44,\ + 0x53,0x01,0x67,0x16,0x53,0x01,0x67,0x00,\ + 0x00,0xB8,0x53,0x01,0x67,0x00,0x01,0x0A,\ + 0x53,0x01,0x67,0x00,0x01,0x3A,0x60,0x00,\ + 0x01,0x3A,0x4B,0xF8,0x00,0x00,0x24,0x3A,\ + 0xFF,0x1E,0x26,0x02,0x3A,0xBC,0xFF,0xFF,\ + 0x3A,0xBC,0xFF,0xFF,0x42,0x55,0x4A,0x35,\ + 0x28,0xFF,0x67,0x28,0x7A,0x19,0x1B,0xBC,\ + 0x00,0x40,0x28,0xFF,0x42,0x35,0x28,0xFF,\ + 0x72,0x15,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0x1B,0xBC,0x00,0xC0,0x28,0xFF,0x72,0x0C,\ + 0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x4A,0x35,\ + 0x28,0xFF,0x66,0x06,0x53,0x82,0x66,0xCC,\ + 0x60,0x04,0x53,0x45,0x66,0xD0,0x42,0x55,\ + 0x4A,0x55,0x4A,0x05,0x67,0x00,0x00,0xE4,\ + 0x24,0x03,0x50,0xC4,0x2A,0x3C,0x03,0xE8,\ + 0x03,0xE8,0x72,0x20,0x1B,0x81,0x28,0xFF,\ + 0x1B,0x81,0x28,0xFF,0x32,0x3C,0x55,0xF0,\ + 0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x4E,0xBA,\ + 0xFE,0x24,0x1B,0xBC,0x00,0xA0,0x28,0xFF,\ + 0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0xB8,0x35,0x28,0xFF,0x66,0x08,0x48,0x45,\ + 0x53,0x82,0x66,0xE6,0x60,0x04,0x53,0x45,\ + 0x66,0xC8,0x42,0x55,0x4A,0x55,0x4A,0x45,\ + 0x67,0x00,0x00,0x98,0x60,0x00,0x00,0x90,\ + 0x70,0x01,0x42,0x83,0x1D,0x87,0x08,0x00,\ + 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0x80,\ + 0x08,0x00,0x1D,0x87,0x08,0x00,0x1B,0x86,\ + 0x08,0x00,0x1D,0xBC,0x00,0x10,0x08,0x00,\ + 0x2A,0x00,0x4E,0xBA,0xFD,0xD0,0x20,0x05,\ + 0x1A,0x30,0x09,0x90,0x08,0x05,0x00,0x07,\ + 0x66,0x20,0x08,0x05,0x00,0x05,0x67,0xE8,\ + 0x1A,0x30,0x09,0x90,0x08,0x05,0x00,0x07,\ + 0x66,0x10,0x1D,0x87,0x08,0x00,0x1B,0x86,\ + 0x08,0x00,0x1D,0xBC,0x00,0xF0,0x08,0x00,\ + 0x60,0x40,0x53,0x80,0x67,0xAE,0x60,0x36,\ + 0x42,0x83,0x3C,0x87,0x3A,0x86,0x3C,0xBC,\ + 0x00,0x80,0x3C,0x87,0x3A,0x86,0x3C,0xBC,\ + 0x00,0x10,0x4E,0xBA,0xFD,0x88,0x3A,0x15,\ + 0x08,0x05,0x00,0x07,0x66,0x18,0x08,0x05,\ + 0x00,0x05,0x67,0xEE,0x3A,0x15,0x08,0x05,\ + 0x00,0x07,0x66,0x0A,0x3C,0x87,0x3A,0x86,\ + 0x3C,0xBC,0x00,0xF0,0x60,0x04,0x42,0x80,\ + 0x60,0x02,0x70,0x01,0x4E,0x75,\ + 0x47,0xFB,0x01,0x70,0x00,0x00,0x04,0x50,\ + 0x28,0x49,0x24,0x3C,0x00,0x00,0x01,0x00,\ + 0x12,0x3A,0xFD,0xDA,0x53,0x01,0x67,0x14,\ + 0x53,0x01,0x67,0x5A,0x53,0x01,0x67,0x00,\ + 0x00,0xBC,0x53,0x01,0x67,0x00,0x01,0x00,\ + 0x60,0x00,0x01,0x2E,0x10,0x33,0x28,0xFF,\ + 0x0C,0x00,0x00,0xFF,0x67,0x28,0x7A,0x19,\ + 0x19,0xBC,0x00,0x40,0x28,0xFF,0x19,0x80,\ + 0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0x19,0xBC,0x00,0xC0,0x28,0xFF,\ + 0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0xB0,0x34,0x28,0xFF,0x66,0x06,0x53,0x82,\ + 0x66,0xCA,0x60,0x04,0x53,0x05,0x66,0xD0,\ + 0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\ + 0x00,0xE8,0x60,0x00,0x00,0xE0,0x20,0x0C,\ + 0xD0,0x82,0xC0,0xBC,0x00,0x00,0x00,0x01,\ + 0x08,0x40,0x00,0x00,0x16,0x33,0x28,0xFF,\ + 0x0C,0x03,0x00,0xFF,0x67,0x48,0x1D,0x87,\ + 0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\ + 0x00,0xA0,0x08,0x00,0x19,0x83,0x28,0xFF,\ + 0xC6,0x3C,0x00,0x80,0x18,0x34,0x28,0xFF,\ + 0x1A,0x04,0xC8,0x3C,0x00,0x80,0xB8,0x03,\ + 0x67,0x24,0x08,0x05,0x00,0x05,0x67,0xEC,\ + 0x18,0x34,0x28,0xFF,0xC8,0x3C,0x00,0x80,\ + 0xB8,0x03,0x67,0x12,0x1D,0x87,0x08,0x00,\ + 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\ + 0x08,0x00,0x60,0x00,0x00,0x84,0x53,0x82,\ + 0x66,0xA6,0x60,0x78,0x36,0x33,0x28,0xFE,\ + 0x0C,0x43,0xFF,0xFF,0x67,0x3A,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0x00,0xA0,0x39,0x83,\ + 0x28,0xFE,0xC6,0x7C,0x00,0x80,0x38,0x34,\ + 0x28,0xFE,0x3A,0x04,0xC8,0x7C,0x00,0x80,\ + 0xB8,0x43,0x67,0x1C,0x08,0x05,0x00,0x05,\ + 0x67,0xEC,0x38,0x34,0x28,0xFE,0xC8,0x7C,\ + 0x00,0x80,0xB8,0x43,0x67,0x0A,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x38,\ + 0x55,0x82,0x66,0xB8,0x60,0x2E,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0xA0,0xA0,0x39,0xB3,\ + 0x28,0xFE,0x28,0xFE,0x55,0x82,0x66,0xF6,\ + 0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0x34,0x3C,0x01,0x00,0x36,0x33,\ + 0x28,0xFE,0xB6,0x74,0x28,0xFE,0x66,0x08,\ + 0x55,0x82,0x66,0xF2,0x42,0x80,0x60,0x02,\ + 0x70,0x01,0x4E,0x75,\ + 0x4F,0xFB,0x01,0x70,0x00,0x00,0x02,0xF4,\ + 0x4E,0xBA,0xFC,0x0A,0x4E,0xBA,0xFC,0x84,\ + 0x4E,0xBA,0xFD,0x32,0x4A,0xFA,0x42,0x80,\ + 0x22,0x40,0x4E,0xBA,0xFE,0x88,0x4A,0xFA,\ + 0xD2,0xFC,0x01,0x00,0x60,0xF4 + }; - timer.stop(); - printf("Erasing took %#.1f seconds.\r\n",timer.read()); - - printf("Programming the FLASH chips...\r\n"); + uint8_t flashDriver6[] = {\ + 0x60,0x00,0x04,0x0A,\ + 0x7C,0x2F,0x2D,0x5C,0x2A,0x0D,0x00,0x00,\ + 0x02,0x03,0x00,0x03,0x41,0xFA,0xFF,0xF6,\ + 0x10,0xBB,0x30,0xEE,0x70,0x01,0x4A,0xFA,\ + 0x52,0x43,0x4E,0x75,\ + 0x20,0x7C,0x00,0xFF,0xFA,0x00,0x08,0x10,\ + 0x00,0x04,0x66,0x4E,0xD0,0xFC,0x00,0x04,\ + 0x10,0xFC,0x00,0x7F,0x08,0x10,0x00,0x03,\ + 0x67,0xFA,0xD0,0xFC,0x00,0x1C,0x42,0x10,\ + 0xD0,0xFC,0x00,0x23,0x30,0xBC,0x3F,0xFF,\ + 0xD0,0xFC,0x00,0x04,0x70,0x07,0x30,0xC0,\ + 0x30,0xBC,0x68,0x70,0xD0,0xFC,0x00,0x06,\ + 0x30,0xC0,0x30,0xFC,0x30,0x30,0x30,0xC0,\ + 0x30,0xBC,0x50,0x30,0xD0,0xFC,0x01,0xBE,\ + 0x70,0x40,0x30,0xC0,0x30,0x80,0x30,0x3C,\ + 0x55,0xF0,0x4E,0x71,0x51,0xC8,0xFF,0xFC,\ + 0x60,0x18,0xD0,0xFC,0x00,0x08,0x30,0xFC,\ + 0x69,0x08,0x08,0x10,0x00,0x09,0x67,0xFA,\ + 0x31,0x3C,0x68,0x08,0xD0,0xFC,0x00,0x48,\ + 0x42,0x50,0x4E,0x75,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x2C,0x3C,0x00,0x00,0x55,0x55,\ + 0x2E,0x3C,0x00,0x00,0xAA,0xAA,0x2A,0x46,\ + 0x53,0x8D,0x2C,0x47,0x45,0xF8,0x00,0x00,\ + 0x47,0xFA,0xFF,0xDE,0x3C,0x87,0x3A,0x86,\ + 0x3C,0xBC,0x90,0x90,0x36,0xDA,0x36,0x92,\ + 0x3C,0x87,0x3A,0x86,0x3C,0xBC,0xF0,0xF0,\ + 0x20,0x3A,0xFF,0xC6,0x72,0x02,0x48,0x41,\ + 0x74,0x01,0x0C,0x00,0x00,0x25,0x67,0x50,\ + 0x0C,0x00,0x00,0xB8,0x67,0x4A,0x74,0x04,\ + 0x0C,0x00,0x00,0x5D,0x67,0x42,0x74,0x01,\ + 0xE3,0x99,0x0C,0x00,0x00,0xA7,0x67,0x38,\ + 0x0C,0x00,0x00,0xB4,0x67,0x32,0x74,0x02,\ + 0x0C,0x00,0x00,0x20,0x67,0x2A,0x0C,0x00,\ + 0x00,0xA4,0x67,0x24,0x0C,0x00,0x00,0xB5,\ + 0x67,0x1E,0x74,0x04,0x0C,0x00,0x00,0xD5,\ + 0x67,0x16,0x74,0x03,0xE3,0x99,0x0C,0x00,\ + 0x00,0x23,0x67,0x0C,0xE3,0x99,0x0C,0x00,\ + 0x00,0x81,0x67,0x04,0x72,0x00,0x74,0x00,\ + 0x47,0xFA,0xFF,0x6A,0x26,0x81,0x47,0xFA,\ + 0xFF,0x68,0x16,0x82,0x4E,0x75,\ + 0x45,0x72,0x61,0x73,0x69,0x6E,0x67,0x20,\ + 0x46,0x4C,0x41,0x53,0x48,0x20,0x63,0x68,\ + 0x69,0x70,0x73,0x0D,0x0A,0x00,0x41,0xFA,\ + 0xFF,0xE8,0x70,0x01,0x12,0x3A,0xFF,0x44,\ + 0x53,0x01,0x67,0x16,0x53,0x01,0x67,0x00,\ + 0x00,0xB8,0x53,0x01,0x67,0x00,0x01,0x0A,\ + 0x53,0x01,0x67,0x00,0x01,0x3A,0x60,0x00,\ + 0x01,0x3A,0x4B,0xF8,0x00,0x00,0x24,0x3A,\ + 0xFF,0x1E,0x26,0x02,0x3A,0xBC,0xFF,0xFF,\ + 0x3A,0xBC,0xFF,0xFF,0x42,0x55,0x4A,0x35,\ + 0x28,0xFF,0x67,0x28,0x7A,0x19,0x1B,0xBC,\ + 0x00,0x40,0x28,0xFF,0x42,0x35,0x28,0xFF,\ + 0x72,0x15,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0x1B,0xBC,0x00,0xC0,0x28,0xFF,0x72,0x0C,\ + 0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x4A,0x35,\ + 0x28,0xFF,0x66,0x06,0x53,0x82,0x66,0xCC,\ + 0x60,0x04,0x53,0x45,0x66,0xD0,0x42,0x55,\ + 0x4A,0x55,0x4A,0x05,0x67,0x00,0x00,0xE4,\ + 0x24,0x03,0x50,0xC4,0x2A,0x3C,0x03,0xE8,\ + 0x03,0xE8,0x72,0x20,0x1B,0x81,0x28,0xFF,\ + 0x1B,0x81,0x28,0xFF,0x32,0x3C,0x55,0xF0,\ + 0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x4E,0xBA,\ + 0xFE,0x22,0x1B,0xBC,0x00,0xA0,0x28,0xFF,\ + 0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0xB8,0x35,0x28,0xFF,0x66,0x08,0x48,0x45,\ + 0x53,0x82,0x66,0xE6,0x60,0x04,0x53,0x45,\ + 0x66,0xC8,0x42,0x55,0x4A,0x55,0x4A,0x45,\ + 0x67,0x00,0x00,0x98,0x60,0x00,0x00,0x90,\ + 0x70,0x01,0x42,0x83,0x1D,0x87,0x08,0x00,\ + 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0x80,\ + 0x08,0x00,0x1D,0x87,0x08,0x00,0x1B,0x86,\ + 0x08,0x00,0x1D,0xBC,0x00,0x10,0x08,0x00,\ + 0x2A,0x00,0x4E,0xBA,0xFD,0xCE,0x20,0x05,\ + 0x1A,0x30,0x09,0x90,0x08,0x05,0x00,0x07,\ + 0x66,0x20,0x08,0x05,0x00,0x05,0x67,0xE8,\ + 0x1A,0x30,0x09,0x90,0x08,0x05,0x00,0x07,\ + 0x66,0x10,0x1D,0x87,0x08,0x00,0x1B,0x86,\ + 0x08,0x00,0x1D,0xBC,0x00,0xF0,0x08,0x00,\ + 0x60,0x40,0x53,0x80,0x67,0xAE,0x60,0x36,\ + 0x42,0x83,0x3C,0x87,0x3A,0x86,0x3C,0xBC,\ + 0x00,0x80,0x3C,0x87,0x3A,0x86,0x3C,0xBC,\ + 0x00,0x10,0x4E,0xBA,0xFD,0x86,0x3A,0x15,\ + 0x08,0x05,0x00,0x07,0x66,0x18,0x08,0x05,\ + 0x00,0x05,0x67,0xEE,0x3A,0x15,0x08,0x05,\ + 0x00,0x07,0x66,0x0A,0x3C,0x87,0x3A,0x86,\ + 0x3C,0xBC,0x00,0xF0,0x60,0x04,0x42,0x80,\ + 0x60,0x02,0x70,0x01,0x4E,0x75,\ + 0x47,0xFB,0x01,0x70,0x00,0x00,0x04,0x4E,\ + 0x28,0x49,0x24,0x3C,0x00,0x00,0x01,0x00,\ + 0x12,0x3A,0xFD,0xDA,0x53,0x01,0x67,0x14,\ + 0x53,0x01,0x67,0x5A,0x53,0x01,0x67,0x00,\ + 0x00,0xBC,0x53,0x01,0x67,0x00,0x01,0x00,\ + 0x60,0x00,0x01,0x2E,0x10,0x33,0x28,0xFF,\ + 0x0C,0x00,0x00,0xFF,0x67,0x28,0x7A,0x19,\ + 0x19,0xBC,0x00,0x40,0x28,0xFF,0x19,0x80,\ + 0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0x19,0xBC,0x00,0xC0,0x28,0xFF,\ + 0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0xB0,0x34,0x28,0xFF,0x66,0x06,0x53,0x82,\ + 0x66,0xCA,0x60,0x04,0x53,0x05,0x66,0xD0,\ + 0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\ + 0x00,0xE8,0x60,0x00,0x00,0xE0,0x20,0x0C,\ + 0xD0,0x82,0xC0,0xBC,0x00,0x00,0x00,0x01,\ + 0x08,0x40,0x00,0x00,0x16,0x33,0x28,0xFF,\ + 0x0C,0x03,0x00,0xFF,0x67,0x48,0x1D,0x87,\ + 0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\ + 0x00,0xA0,0x08,0x00,0x19,0x83,0x28,0xFF,\ + 0xC6,0x3C,0x00,0x80,0x18,0x34,0x28,0xFF,\ + 0x1A,0x04,0xC8,0x3C,0x00,0x80,0xB8,0x03,\ + 0x67,0x24,0x08,0x05,0x00,0x05,0x67,0xEC,\ + 0x18,0x34,0x28,0xFF,0xC8,0x3C,0x00,0x80,\ + 0xB8,0x03,0x67,0x12,0x1D,0x87,0x08,0x00,\ + 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\ + 0x08,0x00,0x60,0x00,0x00,0x84,0x53,0x82,\ + 0x66,0xA6,0x60,0x78,0x36,0x33,0x28,0xFE,\ + 0x0C,0x43,0xFF,0xFF,0x67,0x3A,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0x00,0xA0,0x39,0x83,\ + 0x28,0xFE,0xC6,0x7C,0x00,0x80,0x38,0x34,\ + 0x28,0xFE,0x3A,0x04,0xC8,0x7C,0x00,0x80,\ + 0xB8,0x43,0x67,0x1C,0x08,0x05,0x00,0x05,\ + 0x67,0xEC,0x38,0x34,0x28,0xFE,0xC8,0x7C,\ + 0x00,0x80,0xB8,0x43,0x67,0x0A,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x38,\ + 0x55,0x82,0x66,0xB8,0x60,0x2E,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0xA0,0xA0,0x39,0xB3,\ + 0x28,0xFE,0x28,0xFE,0x55,0x82,0x66,0xF6,\ + 0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0x34,0x3C,0x01,0x00,0x36,0x33,\ + 0x28,0xFE,0xB6,0x74,0x28,0xFE,0x66,0x08,\ + 0x55,0x82,0x66,0xF2,0x42,0x80,0x60,0x02,\ + 0x70,0x01,0x4E,0x75,\ + 0x4F,0xFB,0x01,0x70,0x00,0x00,0x02,0xF2,\ + 0x4E,0xBA,0xFC,0x0A,0x4E,0xBA,0xFC,0x84,\ + 0x4E,0xBA,0xFD,0x32,0x4A,0xFA,0x42,0x80,\ + 0x22,0x40,0x4E,0xBA,0xFE,0x88,0x4A,0xFA,\ + 0xD2,0xFC,0x01,0x00,0x60,0xF4,0x00,0x00 + }; + */ + uint8_t flashDriver[] = {\ + 0x60,0x00,0x04,0x0C,\ + 0x7C,0x2F,0x2D,0x5C,0x2A,0x0D,0x00,0x00,\ + 0x02,0x03,0x00,0x03,0x41,0xFA,0xFF,0xF6,\ + 0x10,0xBB,0x30,0xEE,0x70,0x01,0x4A,0xFA,\ + 0x52,0x43,0x4E,0x75,\ + 0x20,0x7C,0x00,0xFF,0xFA,0x00,0x08,0x10,\ + 0x00,0x04,0x66,0x4E,0xD0,0xFC,0x00,0x04,\ + 0x10,0xFC,0x00,0x7F,0x08,0x10,0x00,0x03,\ + 0x67,0xFA,0xD0,0xFC,0x00,0x1C,0x42,0x10,\ + 0xD0,0xFC,0x00,0x23,0x30,0xBC,0x3F,0xFF,\ + 0xD0,0xFC,0x00,0x04,0x70,0x07,0x30,0xC0,\ + 0x30,0xBC,0x68,0x70,0xD0,0xFC,0x00,0x06,\ + 0x30,0xC0,0x30,0xFC,0x30,0x30,0x30,0xC0,\ + 0x30,0xBC,0x50,0x30,0xD0,0xFC,0x01,0xBE,\ + 0x70,0x40,0x30,0xC0,0x30,0x80,0x30,0x3C,\ + 0x55,0xF0,0x4E,0x71,0x51,0xC8,0xFF,0xFC,\ + 0x60,0x18,0xD0,0xFC,0x00,0x08,0x30,0xFC,\ + 0x69,0x08,0x08,0x10,0x00,0x09,0x67,0xFA,\ + 0x31,0x3C,0x68,0x08,0xD0,0xFC,0x00,0x48,\ + 0x42,0x50,0x4E,0x75,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x2C,0x3C,0x00,0x00,0x55,0x55,\ + 0x2E,0x3C,0x00,0x00,0xAA,0xAA,0x2A,0x46,\ + 0x53,0x8D,0x2C,0x47,0x45,0xF8,0x00,0x00,\ + 0x47,0xFA,0xFF,0xDE,0x3C,0x87,0x3A,0x86,\ + 0x3C,0xBC,0x90,0x90,0x36,0xDA,0x36,0x92,\ + 0x3C,0x87,0x3A,0x86,0x3C,0xBC,0xF0,0xF0,\ + 0x20,0x3A,0xFF,0xC6,0x72,0x02,0x48,0x41,\ + 0x74,0x01,0x0C,0x00,0x00,0x25,0x67,0x50,\ + 0x0C,0x00,0x00,0xB8,0x67,0x4A,0x74,0x04,\ + 0x0C,0x00,0x00,0x5D,0x67,0x42,0x74,0x01,\ + 0xE3,0x99,0x0C,0x00,0x00,0xA7,0x67,0x38,\ + 0x0C,0x00,0x00,0xB4,0x67,0x32,0x74,0x02,\ + 0x0C,0x00,0x00,0x20,0x67,0x2A,0x0C,0x00,\ + 0x00,0xA4,0x67,0x24,0x0C,0x00,0x00,0xB5,\ + 0x67,0x1E,0x74,0x04,0x0C,0x00,0x00,0xD5,\ + 0x67,0x16,0x74,0x03,0xE3,0x99,0x0C,0x00,\ + 0x00,0x23,0x67,0x0C,0xE3,0x99,0x0C,0x00,\ + 0x00,0x81,0x67,0x04,0x72,0x00,0x74,0x00,\ + 0x47,0xFA,0xFF,0x6A,0x26,0x81,0x47,0xFA,\ + 0xFF,0x68,0x16,0x82,0x4E,0x75,\ + 0x45,0x72,0x61,0x73,0x69,0x6E,0x67,0x20,\ + 0x46,0x4C,0x41,0x53,0x48,0x20,0x63,0x68,\ + 0x69,0x70,0x73,0x0D,0x0A,0x00,0x41,0xFA,\ + 0xFF,0xE8,0x70,0x01,0x4A,0xFA,0x12,0x3A,\ + 0xFF,0x42,0x53,0x01,0x67,0x16,0x53,0x01,\ + 0x67,0x00,0x00,0xB8,0x53,0x01,0x67,0x00,\ + 0x01,0x0A,0x53,0x01,0x67,0x00,0x01,0x3A,\ + 0x60,0x00,0x01,0x3A,0x4B,0xF8,0x00,0x00,\ + 0x24,0x3A,0xFF,0x1C,0x26,0x02,0x3A,0xBC,\ + 0xFF,0xFF,0x3A,0xBC,0xFF,0xFF,0x42,0x55,\ + 0x4A,0x35,0x28,0xFF,0x67,0x28,0x7A,0x19,\ + 0x1B,0xBC,0x00,0x40,0x28,0xFF,0x42,0x35,\ + 0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0x1B,0xBC,0x00,0xC0,0x28,0xFF,\ + 0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0x4A,0x35,0x28,0xFF,0x66,0x06,0x53,0x82,\ + 0x66,0xCC,0x60,0x04,0x53,0x45,0x66,0xD0,\ + 0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\ + 0x00,0xE4,0x24,0x03,0x50,0xC4,0x2A,0x3C,\ + 0x03,0xE8,0x03,0xE8,0x72,0x20,0x1B,0x81,\ + 0x28,0xFF,0x1B,0x81,0x28,0xFF,0x32,0x3C,\ + 0x55,0xF0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0x4E,0xBA,0xFE,0x20,0x1B,0xBC,0x00,0xA0,\ + 0x28,0xFF,0x72,0x0C,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0xB8,0x35,0x28,0xFF,0x66,0x08,\ + 0x48,0x45,0x53,0x82,0x66,0xE6,0x60,0x04,\ + 0x53,0x45,0x66,0xC8,0x42,0x55,0x4A,0x55,\ + 0x4A,0x45,0x67,0x00,0x00,0x98,0x60,0x00,\ + 0x00,0x90,0x70,0x01,0x42,0x83,0x1D,0x87,\ + 0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\ + 0x00,0x80,0x08,0x00,0x1D,0x87,0x08,0x00,\ + 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0x10,\ + 0x08,0x00,0x2A,0x00,0x4E,0xBA,0xFD,0xCC,\ + 0x20,0x05,0x1A,0x30,0x09,0x90,0x08,0x05,\ + 0x00,0x07,0x66,0x20,0x08,0x05,0x00,0x05,\ + 0x67,0xE8,0x1A,0x30,0x09,0x90,0x08,0x05,\ + 0x00,0x07,0x66,0x10,0x1D,0x87,0x08,0x00,\ + 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\ + 0x08,0x00,0x60,0x40,0x53,0x80,0x67,0xAE,\ + 0x60,0x36,0x42,0x83,0x3C,0x87,0x3A,0x86,\ + 0x3C,0xBC,0x00,0x80,0x3C,0x87,0x3A,0x86,\ + 0x3C,0xBC,0x00,0x10,0x4E,0xBA,0xFD,0x84,\ + 0x3A,0x15,0x08,0x05,0x00,0x07,0x66,0x18,\ + 0x08,0x05,0x00,0x05,0x67,0xEE,0x3A,0x15,\ + 0x08,0x05,0x00,0x07,0x66,0x0A,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x04,\ + 0x42,0x80,0x60,0x02,0x70,0x01,0x4E,0x75,\ + 0x47,0xFB,0x01,0x70,0x00,0x00,0x04,0x4C,\ + 0x28,0x49,0x24,0x3C,0x00,0x00,0x01,0x00,\ + 0x12,0x3A,0xFD,0xD8,0x53,0x01,0x67,0x14,\ + 0x53,0x01,0x67,0x5A,0x53,0x01,0x67,0x00,\ + 0x00,0xBC,0x53,0x01,0x67,0x00,0x01,0x00,\ + 0x60,0x00,0x01,0x2E,0x10,0x33,0x28,0xFF,\ + 0x0C,0x00,0x00,0xFF,0x67,0x28,0x7A,0x19,\ + 0x19,0xBC,0x00,0x40,0x28,0xFF,0x19,0x80,\ + 0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0x19,0xBC,0x00,0xC0,0x28,0xFF,\ + 0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0xB0,0x34,0x28,0xFF,0x66,0x06,0x53,0x82,\ + 0x66,0xCA,0x60,0x04,0x53,0x05,0x66,0xD0,\ + 0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\ + 0x00,0xE8,0x60,0x00,0x00,0xE0,0x20,0x0C,\ + 0xD0,0x82,0xC0,0xBC,0x00,0x00,0x00,0x01,\ + 0x08,0x40,0x00,0x00,0x16,0x33,0x28,0xFF,\ + 0x0C,0x03,0x00,0xFF,0x67,0x48,0x1D,0x87,\ + 0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\ + 0x00,0xA0,0x08,0x00,0x19,0x83,0x28,0xFF,\ + 0xC6,0x3C,0x00,0x80,0x18,0x34,0x28,0xFF,\ + 0x1A,0x04,0xC8,0x3C,0x00,0x80,0xB8,0x03,\ + 0x67,0x24,0x08,0x05,0x00,0x05,0x67,0xEC,\ + 0x18,0x34,0x28,0xFF,0xC8,0x3C,0x00,0x80,\ + 0xB8,0x03,0x67,0x12,0x1D,0x87,0x08,0x00,\ + 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\ + 0x08,0x00,0x60,0x00,0x00,0x84,0x53,0x82,\ + 0x66,0xA6,0x60,0x78,0x36,0x33,0x28,0xFE,\ + 0x0C,0x43,0xFF,0xFF,0x67,0x3A,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0x00,0xA0,0x39,0x83,\ + 0x28,0xFE,0xC6,0x7C,0x00,0x80,0x38,0x34,\ + 0x28,0xFE,0x3A,0x04,0xC8,0x7C,0x00,0x80,\ + 0xB8,0x43,0x67,0x1C,0x08,0x05,0x00,0x05,\ + 0x67,0xEC,0x38,0x34,0x28,0xFE,0xC8,0x7C,\ + 0x00,0x80,0xB8,0x43,0x67,0x0A,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x38,\ + 0x55,0x82,0x66,0xB8,0x60,0x2E,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0xA0,0xA0,0x39,0xB3,\ + 0x28,0xFE,0x28,0xFE,0x55,0x82,0x66,0xF6,\ + 0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0x34,0x3C,0x01,0x00,0x36,0x33,\ + 0x28,0xFE,0xB6,0x74,0x28,0xFE,0x66,0x08,\ + 0x55,0x82,0x66,0xF2,0x42,0x80,0x60,0x02,\ + 0x70,0x01,0x4E,0x75,\ + 0x4F,0xFB,0x01,0x70,0x00,0x00,0x02,0xF0,\ + 0x4E,0xBA,0xFC,0x08,0x4E,0xBA,0xFC,0x82,\ + 0x4E,0xBA,0xFD,0x30,0x4A,0xFA,0x42,0x80,\ + 0x22,0x40,0x4E,0xBA,0xFE,0x88,0x4A,0xFA,\ + 0xD2,0xFC,0x01,0x00,0x60,0xF4 + }; - timer.reset(); - timer.start(); + /* + uint8_t flashDriver8[] = {\ + 0x60,0x00,0x05,0xC2,0x54,0x72,0x69,0x6F,\ + 0x6E,0x69,0x63,0x20,0x45,0x43,0x55,0x20,\ + 0x46,0x4C,0x41,0x53,0x48,0x20,0x73,0x63,\ + 0x72,0x69,0x70,0x74,0x0D,0x0A,0x00,0x50,\ + 0x72,0x6F,0x67,0x72,0x61,0x6D,0x6D,0x69,\ + 0x6E,0x67,0x20,0x46,0x4C,0x41,0x53,0x48,\ + 0x20,0x63,0x68,0x69,0x70,0x20,0x61,0x64,\ + 0x64,0x72,0x65,0x73,0x73,0x65,0x73,0x3A,\ + 0x0D,0x0A,0x00,0x54,0x72,0x69,0x6F,0x6E,\ + 0x69,0x63,0x20,0x45,0x43,0x55,0x20,0x46,\ + 0x4C,0x41,0x53,0x48,0x20,0x63,0x68,0x69,\ + 0x70,0x73,0x20,0x75,0x70,0x64,0x61,0x74,\ + 0x65,0x64,0x20,0x2D,0x20,0x65,0x6E,0x6A,\ + 0x6F,0x79,0x20,0x3A,0x2D,0x29,0x0D,0x0A,\ + 0x00,0x46,0x4C,0x41,0x53,0x48,0x20,0x73,\ + 0x69,0x7A,0x65,0x3A,0x20,0x30,0x78,0x30,\ + 0x46,0x61,0x64,0x65,0x30,0x20,0x42,0x79,\ + 0x74,0x65,0x73,0x0D,0x0A,0x00,0x30,0x78,\ + 0x30,0x43,0x61,0x66,0x65,0x30,0x2D,0x30,\ + 0x42,0x61,0x62,0x65,0x30,0x0D,0x00,0x72,\ + 0x62,0x00,\ + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,\ + 0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46,\ + 0xE1,0x9A,0x76,0x05,0x42,0x84,0xE9,0x9A,\ + 0x18,0x02,0x02,0x04,0x00,0x0F,0x10,0xFB,\ + 0x40,0xE0,0x51,0xCB,0xFF,0xF2,0x4E,0x75,\ + 0x7C,0x2F,0x2D,0x5C,0x2A,0x0D,0x00,0x00,\ + 0x02,0x03,0x00,0x03,0x41,0xFA,0xFF,0xF6,\ + 0x10,0xBB,0x30,0xEE,0x70,0x01,0x4A,0xFA,\ + 0x52,0x43,0x4E,0x75,\ + 0x20,0x7C,0x00,0xFF,0xFA,0x00,0x08,0x10,\ + 0x00,0x04,0x66,0x4E,0xD0,0xFC,0x00,0x04,\ + 0x10,0xFC,0x00,0x7F,0x08,0x10,0x00,0x03,\ + 0x67,0xFA,0xD0,0xFC,0x00,0x1C,0x42,0x10,\ + 0xD0,0xFC,0x00,0x23,0x30,0xBC,0x3F,0xFF,\ + 0xD0,0xFC,0x00,0x04,0x70,0x07,0x30,0xC0,\ + 0x30,0xBC,0x68,0x70,0xD0,0xFC,0x00,0x06,\ + 0x30,0xC0,0x30,0xFC,0x30,0x30,0x30,0xC0,\ + 0x30,0xBC,0x50,0x30,0xD0,0xFC,0x01,0xBE,\ + 0x70,0x40,0x30,0xC0,0x30,0x80,0x30,0x3C,\ + 0x55,0xF0,0x4E,0x71,0x51,0xC8,0xFF,0xFC,\ + 0x60,0x18,0xD0,0xFC,0x00,0x08,0x30,0xFC,\ + 0x69,0x08,0x08,0x10,0x00,0x09,0x67,0xFA,\ + 0x31,0x3C,0x68,0x08,0xD0,0xFC,0x00,0x48,\ + 0x42,0x50,0x4E,0x75,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x2C,0x3C,0x00,0x00,0x55,0x55,\ + 0x2E,0x3C,0x00,0x00,0xAA,0xAA,0x2A,0x46,\ + 0x53,0x8D,0x2C,0x47,0x45,0xF8,0x00,0x00,\ + 0x47,0xFA,0xFF,0xDE,0x3C,0x87,0x3A,0x86,\ + 0x3C,0xBC,0x90,0x90,0x36,0xDA,0x36,0x92,\ + 0x3C,0x87,0x3A,0x86,0x3C,0xBC,0xF0,0xF0,\ + 0x20,0x3A,0xFF,0xC6,0x72,0x02,0x48,0x41,\ + 0x74,0x01,0x0C,0x00,0x00,0x25,0x67,0x50,\ + 0x0C,0x00,0x00,0xB8,0x67,0x4A,0x74,0x04,\ + 0x0C,0x00,0x00,0x5D,0x67,0x42,0x74,0x01,\ + 0xE3,0x99,0x0C,0x00,0x00,0xA7,0x67,0x38,\ + 0x0C,0x00,0x00,0xB4,0x67,0x32,0x74,0x02,\ + 0x0C,0x00,0x00,0x20,0x67,0x2A,0x0C,0x00,\ + 0x00,0xA4,0x67,0x24,0x0C,0x00,0x00,0xB5,\ + 0x67,0x1E,0x74,0x04,0x0C,0x00,0x00,0xD5,\ + 0x67,0x16,0x74,0x03,0xE3,0x99,0x0C,0x00,\ + 0x00,0x23,0x67,0x0C,0xE3,0x99,0x0C,0x00,\ + 0x00,0x81,0x67,0x04,0x72,0x00,0x74,0x00,\ + 0x47,0xFA,0xFF,0x6A,0x26,0x81,0x47,0xFA,\ + 0xFF,0x68,0x16,0x82,0x4E,0x75,\ + 0x46,0x6F,0x75,0x6E,0x64,0x20,0x61,0x20,\ + 0x54,0x20,0x20,0x20,0x0D,0x0A,0x00,0x00,\ + 0x20,0x3A,0xFF,0x4C,0x48,0x40,0x41,0xFA,\ + 0xFF,0xF1,0x72,0x38,0xE9,0x18,0x65,0x16,\ + 0x72,0x37,0xE3,0x18,0x65,0x10,0x72,0x35,\ + 0x10,0xC1,0x72,0x2E,0x10,0xC1,0x72,0x35,\ + 0xE3,0x18,0x65,0x02,0x72,0x32,0x10,0x81,\ + 0x41,0xFA,0xFF,0xC6,0x70,0x01,0x4A,0xFA,\ + 0x4E,0x75,\ + 0x46,0x49,0x4C,0x45,0x4E,0x41,0x4D,0x45,\ + 0x2E,0x42,0x49,0x4E,0x00,0x45,0x6E,0x74,\ + 0x65,0x72,0x20,0x61,0x20,0x66,0x69,0x6C,\ + 0x65,0x6E,0x61,0x6D,0x65,0x20,0x28,0x75,\ + 0x70,0x20,0x74,0x6F,0x20,0x38,0x20,0x63,\ + 0x68,0x61,0x72,0x61,0x63,0x74,0x65,0x72,\ + 0x73,0x29,0x3A,0x20,0x00,0x00,0x41,0xFA,\ + 0xFF,0xD5,0x70,0x01,0x4A,0xFA,0x41,0xFA,\ + 0xFF,0xC0,0x78,0x08,0x70,0x04,0x4A,0xFA,\ + 0x0C,0x00,0x00,0x0D,0x67,0x26,0x0C,0x00,\ + 0x00,0x2E,0x67,0x20,0x0C,0x00,0x00,0x08,\ + 0x66,0x0A,0xB8,0x00,0x67,0xE6,0x53,0x48,\ + 0x54,0x44,0x60,0x06,0x4A,0x04,0x67,0x0C,\ + 0x10,0xC0,0x12,0x00,0x70,0x02,0x4A,0xFA,\ + 0x51,0xCC,0xFF,0xD2,0x10,0xFC,0x00,0x2E,\ + 0x10,0xFC,0x00,0x42,0x10,0xFC,0x00,0x49,\ + 0x10,0xFC,0x00,0x4E,0x10,0xBC,0x00,0x00,\ + 0x59,0x88,0x70,0x01,0x4A,0xFA,0x41,0xFA,\ + 0xFD,0xB5,0x70,0x01,0x4A,0xFA,0x41,0xFA,\ + 0xFF,0x68,0x43,0xFA,0xFD,0xBD,0x70,0x06,\ + 0x4A,0xFA,0x41,0xFA,0xFF,0x58,0x20,0x80,\ + 0x4E,0x75,\ + 0x45,0x72,0x61,0x73,0x69,0x6E,0x67,0x20,\ + 0x46,0x4C,0x41,0x53,0x48,0x20,0x63,0x68,\ + 0x69,0x70,0x73,0x0D,0x0A,0x00,0x41,0xFA,\ + 0xFF,0xE8,0x70,0x01,0x4A,0xFA,0x12,0x3A,\ + 0xFE,0x52,0x53,0x01,0x67,0x16,0x53,0x01,\ + 0x67,0x00,0x00,0xB8,0x53,0x01,0x67,0x00,\ + 0x01,0x0A,0x53,0x01,0x67,0x00,0x01,0x3A,\ + 0x60,0x00,0x01,0x3A,0x4B,0xF8,0x00,0x00,\ + 0x24,0x3A,0xFE,0x2C,0x26,0x02,0x3A,0xBC,\ + 0xFF,0xFF,0x3A,0xBC,0xFF,0xFF,0x42,0x55,\ + 0x4A,0x35,0x28,0xFF,0x67,0x28,0x7A,0x19,\ + 0x1B,0xBC,0x00,0x40,0x28,0xFF,0x42,0x35,\ + 0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0x1B,0xBC,0x00,0xC0,0x28,0xFF,\ + 0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0x4A,0x35,0x28,0xFF,0x66,0x06,0x53,0x82,\ + 0x66,0xCC,0x60,0x04,0x53,0x45,0x66,0xD0,\ + 0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\ + 0x00,0xE4,0x24,0x03,0x50,0xC4,0x2A,0x3C,\ + 0x03,0xE8,0x03,0xE8,0x72,0x20,0x1B,0x81,\ + 0x28,0xFF,0x1B,0x81,0x28,0xFF,0x32,0x3C,\ + 0x55,0xF0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0x4E,0xBA,0xFD,0x30,0x1B,0xBC,0x00,0xA0,\ + 0x28,0xFF,0x72,0x0C,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0xB8,0x35,0x28,0xFF,0x66,0x08,\ + 0x48,0x45,0x53,0x82,0x66,0xE6,0x60,0x04,\ + 0x53,0x45,0x66,0xC8,0x42,0x55,0x4A,0x55,\ + 0x4A,0x45,0x67,0x00,0x00,0x98,0x60,0x00,\ + 0x00,0x90,0x70,0x01,0x42,0x83,0x1D,0x87,\ + 0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\ + 0x00,0x80,0x08,0x00,0x1D,0x87,0x08,0x00,\ + 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0x10,\ + 0x08,0x00,0x2A,0x00,0x4E,0xBA,0xFC,0xDC,\ + 0x20,0x05,0x1A,0x30,0x09,0x90,0x08,0x05,\ + 0x00,0x07,0x66,0x20,0x08,0x05,0x00,0x05,\ + 0x67,0xE8,0x1A,0x30,0x09,0x90,0x08,0x05,\ + 0x00,0x07,0x66,0x10,0x1D,0x87,0x08,0x00,\ + 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\ + 0x08,0x00,0x60,0x40,0x53,0x80,0x67,0xAE,\ + 0x60,0x36,0x42,0x83,0x3C,0x87,0x3A,0x86,\ + 0x3C,0xBC,0x00,0x80,0x3C,0x87,0x3A,0x86,\ + 0x3C,0xBC,0x00,0x10,0x4E,0xBA,0xFC,0x94,\ + 0x3A,0x15,0x08,0x05,0x00,0x07,0x66,0x18,\ + 0x08,0x05,0x00,0x05,0x67,0xEE,0x3A,0x15,\ + 0x08,0x05,0x00,0x07,0x66,0x0A,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x04,\ + 0x42,0x80,0x60,0x02,0x70,0x01,0x4E,0x75,\ + 0x47,0xFB,0x01,0x70,0x00,0x00,0x02,0x96,\ + 0x28,0x49,0x24,0x3C,0x00,0x00,0x01,0x00,\ + 0x12,0x3A,0xFC,0xE8,0x53,0x01,0x67,0x14,\ + 0x53,0x01,0x67,0x5A,0x53,0x01,0x67,0x00,\ + 0x00,0xBC,0x53,0x01,0x67,0x00,0x01,0x00,\ + 0x60,0x00,0x01,0x2E,0x10,0x33,0x28,0xFF,\ + 0x0C,0x00,0x00,0xFF,0x67,0x28,0x7A,0x19,\ + 0x19,0xBC,0x00,0x40,0x28,0xFF,0x19,0x80,\ + 0x28,0xFF,0x72,0x15,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0x19,0xBC,0x00,0xC0,0x28,0xFF,\ + 0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,\ + 0xB0,0x34,0x28,0xFF,0x66,0x06,0x53,0x82,\ + 0x66,0xCA,0x60,0x04,0x53,0x05,0x66,0xD0,\ + 0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,\ + 0x00,0xE8,0x60,0x00,0x00,0xE0,0x20,0x0C,\ + 0xD0,0x82,0xC0,0xBC,0x00,0x00,0x00,0x01,\ + 0x08,0x40,0x00,0x00,0x16,0x33,0x28,0xFF,\ + 0x0C,0x03,0x00,0xFF,0x67,0x48,0x1D,0x87,\ + 0x08,0x00,0x1B,0x86,0x08,0x00,0x1D,0xBC,\ + 0x00,0xA0,0x08,0x00,0x19,0x83,0x28,0xFF,\ + 0xC6,0x3C,0x00,0x80,0x18,0x34,0x28,0xFF,\ + 0x1A,0x04,0xC8,0x3C,0x00,0x80,0xB8,0x03,\ + 0x67,0x24,0x08,0x05,0x00,0x05,0x67,0xEC,\ + 0x18,0x34,0x28,0xFF,0xC8,0x3C,0x00,0x80,\ + 0xB8,0x03,0x67,0x12,0x1D,0x87,0x08,0x00,\ + 0x1B,0x86,0x08,0x00,0x1D,0xBC,0x00,0xF0,\ + 0x08,0x00,0x60,0x00,0x00,0x84,0x53,0x82,\ + 0x66,0xA6,0x60,0x78,0x36,0x33,0x28,0xFE,\ + 0x0C,0x43,0xFF,0xFF,0x67,0x3A,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0x00,0xA0,0x39,0x83,\ + 0x28,0xFE,0xC6,0x7C,0x00,0x80,0x38,0x34,\ + 0x28,0xFE,0x3A,0x04,0xC8,0x7C,0x00,0x80,\ + 0xB8,0x43,0x67,0x1C,0x08,0x05,0x00,0x05,\ + 0x67,0xEC,0x38,0x34,0x28,0xFE,0xC8,0x7C,\ + 0x00,0x80,0xB8,0x43,0x67,0x0A,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0x00,0xF0,0x60,0x38,\ + 0x55,0x82,0x66,0xB8,0x60,0x2E,0x3C,0x87,\ + 0x3A,0x86,0x3C,0xBC,0xA0,0xA0,0x39,0xB3,\ + 0x28,0xFE,0x28,0xFE,0x55,0x82,0x66,0xF6,\ + 0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,\ + 0xFF,0xFC,0x34,0x3C,0x01,0x00,0x36,0x33,\ + 0x28,0xFE,0xB6,0x74,0x28,0xFE,0x66,0x08,\ + 0x55,0x82,0x66,0xF2,0x42,0x80,0x60,0x02,\ + 0x70,0x01,0x4E,0x75,\ + 0x4F,0xFB,0x01,0x70,0x00,0x00,0x01,0x3A,\ + 0x41,0xFA,0xFA,0x36,0x70,0x01,0x4A,0xFA,\ + 0x4E,0xBA,0xFB,0x10,0x4E,0xBA,0xFB,0x8A,\ + 0x4A,0x42,0x66,0x06,0x74,0x01,0x60,0x00,\ + 0x00,0x42,0x4E,0xBA,0xFC,0x28,0x41,0xFA,\ + 0xFA,0x93,0x24,0x3A,0xFB,0x6E,0x4E,0xBA,\ + 0xFA,0xBE,0x41,0xFA,0xFA,0x79,0x70,0x01,\ + 0x4A,0xFA,0x4E,0xBA,0xFD,0x06,0x4A,0x00,\ + 0x67,0x06,0x74,0x05,0x60,0x00,0x00,0x1C,\ + 0x4A,0xFA,0x41,0xFA,0xFA,0x0F,0x70,0x01,\ + 0x4A,0xFA,0x42,0x80,0x22,0x40,0x4E,0xBA,\ + 0xFE,0x4C,0x4A,0xFA,0xD2,0xFC,0x01,0x00,\ + 0x60,0xF4,0x20,0x7C,0x00,0xFF,0xFA,0x00,\ + 0x08,0x10,0x00,0x04,0x66,0x08,0x02,0x79,\ + 0xFF,0xBF,0x00,0xFF,0xFC,0x14,0x22,0x02,\ + 0x70,0x00,0x4A,0xFA + }; + */ - uint16_t word_value = 0; - uint8_t byte_value = 0; -// bool ret = true; + + //if (prep_t5_do() != TERM_OK) return TERM_ERR; + // Set Program counter to start of BDM driver code + uint32_t driverAddress = 0x100000; + if (sysreg_write(0x0, &driverAddress) != TERM_OK) break; + for (uint32_t i = 0; i < sizeof(flashDriver); i++) { + if(memwrite_byte(&driverAddress, flashDriver[i]) != TERM_OK) return false; + driverAddress++; + } +// if (!bdmLoadMemory(flashDriver, driverAddress, sizeof(flashDriver))) break; + + timer.reset(); + timer.start(); + printf("Erasing FLASH chips...\r\n"); + printf("This can take up to a minute for a T8,\r\n"); + printf("30s for a T7 or 15s for a T5 ECU.\r\n"); + // execute the erase algorithm in the BDM driver + // write the buffer - should complete within 200 milliseconds + // Typical and Maximum Chip Programming times are 9 and 27 seconds for Am29BL802C + // Typical Chip erase time for Am29BL802C is 45 secinds, not including 0x00 programming prior to erasure. + // Allow for at least worst case 27 seconds programming to 0x00 + 3(?) * 45 typical erase time (162 seconds) + // Allow at least 200 seconds erase time 2,000 * (100ms + BDM memread time) + // NOTE: 29/39F010 and 29F400 erase times are considerably lower + +// if (sysreg_write(0x0, &driverAddress) != TERM_OK) return TERM_ERR; +// break; + do { + if (!bdmRunDriver(0x0, 20000)) { + printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n"); + return TERM_ERR; + } + } while (bdmProcessSyscall() == CONTINUE); + +// if (!run_bdm_driver(0x0, 200000)) { +// printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n"); +// return TERM_ERR; +// } + printf("Erasing took %#.1f seconds.\r\n",timer.read()); + + printf("Programming the FLASH chips...\r\n"); // ready to receive data - printf(" 0.00 %% complete.\r"); - while (curr_addr < flash_size) { - // receive bytes from BIN file - //Get a byte - break if no more bytes to get - if (!fread(&byte_value,1,1,fp)) { - fclose(fp); - printf("Error reading the BIN file MODIFIED.HEX"); - break; - } - word_value = (byte_value << 8); - if (!fread(&byte_value,1,1,fp)) { - fclose(fp); - printf("Error reading the BIN file MODIFIED.HEX"); + printf(" 0.00 %% complete.\r"); + while (curr_addr < flash_size) { + // receive bytes from BIN file - break if no more bytes to get + if (!fread(file_buffer,1,0x100,fp)) { + fclose(fp); + printf("Error reading the BIN file MODIFIED.BIN"); + break; + } + if (!bdmLoadMemory((uint8_t*)file_buffer, 0x100700, 0x100)) break; + // write the buffer - should complete within 200 milliseconds + if (!bdmRunDriver(0x0, 200)) break; +// if (!run_bdm_driver(0x0, 200)) break; + + printf("%6.2f\r", 100*(float)curr_addr/(float)flash_size ); + // make the activity LED twinkle + ACTIVITYLEDON; + curr_addr += 0x100; + } break; } - word_value |= byte_value; + // johnc's original method + case AMD29F400B: /// a sort of dummy 'placeholder' as the 'B' chip isn't ever fitted to T7 ECUS + default: { + timer.reset(); + timer.start(); + + // reset the FLASH chips + printf("Reset the FLASH chip(s) to prepare them for Erasing\r\n"); + if (!reset_func()) return TERM_ERR; - // write the word if it is not 0xffff - if (word_value != 0xffff) { - if (!flash_func(&curr_addr, word_value)) break; + switch (type) { + // AM29Fxxx chips (retrofitted to Trionic 5.x; original to T7) + case AMD29BL802C: + case AMD29F400B: + case AMD29F400T: + case AMD29F010: + case SST39SF010: + case AMICA29010L: + printf("Erasing 29BL802/F400/010 type FLASH chips...\r\n"); + if (!erase_am29()) { + printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n"); + return TERM_ERR; + } + break; + // AM28F010 chip (Trionic 5.x original) + case AMD28F010: + case INTEL28F010: + case AMD28F512: + case INTEL28F512: + printf("Erasing 28F010/512 type FLASH chips...\r\n"); + if (!erase_am28(&curr_addr, &flash_size)) { + printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n"); + return TERM_ERR; + } + break; + case ATMEL29C010: + case ATMEL29C512: + printf("Atmel FLASH chips do not require ERASEing :-)\r\n"); + break; + default: + // unknown flash type - shouldn't get here hence "Strange!" + printf("Strange! I couldn't work out how to erase the FLASH chips in the TRIONIC ECU that I am connected to :-(\r\n"); + return TERM_ERR; + } + + timer.stop(); + printf("Erasing took %#.1f seconds.\r\n",timer.read()); + + printf("Programming the FLASH chips...\r\n"); + + timer.reset(); + timer.start(); + + uint16_t word_value = 0; + +// ready to receive data + printf(" 0.00 %% complete.\r"); + while (curr_addr < flash_size) { + // receive bytes from BIN file + //Get a byte - break if no more bytes to get + if (!fread(&file_buffer[0],1,0x2,fp)) { + fclose(fp); + printf("Error reading the BIN file MODIFIED.BIN"); + break; + } + for(uint32_t i=0; i<2; i++) { + (word_value <<= 8) |= file_buffer[i]; + } + + // write the word if it is not 0xffff + if (word_value != 0xffff) { + if (!flash_func(&curr_addr, word_value)) break; + } + + if (!(curr_addr % 0x80)) { + printf("%6.2f\r", 100*(float)curr_addr/(float)flash_size ); + // make the activity LED twinkle + ACTIVITYLEDON; + } + curr_addr += 2; + } } - curr_addr += 2; - - // make the activity LED twinkle - ACTIVITYLEDON; - if (!(curr_addr % 0x80)) - printf("%6.2f\r", 100*(float)curr_addr/(float)flash_size ); } - printf("\n"); timer.stop(); fclose(fp); if (curr_addr == flash_size) { + printf("100.00\r\n"); printf("Programming took %#.1f seconds.\r\n",timer.read()); // "Just4pleisure;)" 'tag' in the empty space at the end of the FLASH chip @@ -577,8 +1314,11 @@ // flash_func(&flash_tag[i].addr, (flash_tag[i].val & word_value)); // } - } else - printf("WARNING: Oh dear, I couldn't program the FLASH at address 0x%8x.\r\n", curr_addr); + } else { + printf("\r\n"); + printf("Programming took %#.1f seconds.\r\n",timer.read()); + printf("WARNING: Oh dear, I couldn't program the FLASH at address 0x%08x.\r\n", curr_addr); + } // reset flash return (reset_func() && (curr_addr == flash_size)) ? TERM_OK : TERM_ERR; @@ -632,13 +1372,15 @@ uint32_t addr = 0x0; uint16_t verify_value; - printf(" 0.0 seconds.\r"); - uint8_t err_cnt = ERR_COUNT; - while (--err_cnt) { - // typical erase time = 1s - // Allow up to 25.5 seconds erase time - wait_ms(100); - wait_ms(100); + printf(" 0.0 seconds.\r"); + timeout.reset(); + timeout.start(); + while (timeout.read() < 200.0) { + // Typical and Maximum Chip Programming times are 9 and 27 seconds for Am29BL802C + // Typical Chip erase time for Am29BL802C is 45 secinds, not including 0x00 programming prior to erasure. + // Allow for at least worst case 27 seconds programming to 0x00 + 3(?) * 45 typical erase time (162 seconds) + // Allow at least 200 seconds erase time 2,000 * (100ms + BDM memread time) + // NOTE: 29/39F010 and 29F400 erase times are considerably lower if (memread_word(&verify_value, &addr) == TERM_OK && verify_value == 0xffff) { // erase completed normally reset_am29(); @@ -647,11 +1389,10 @@ } // make the activity LED twinkle ACTIVITYLEDON; - printf("%4.1f\r", (float)ERR_COUNT/5 - (float)err_cnt/5 ); + printf("%5.1f\r", timeout.read()); } + // erase failed printf("\n"); - - // erase failed reset_am29(); return false; } @@ -682,11 +1423,12 @@ return false; } // verify the result - uint8_t err_cnt = ERR_COUNT; - while (--err_cnt) { - // Allow up to approx 2.55 milliseconds program time (255 * ~10us BDM memread time) - // wait_ms(10); - wait_us(100); + timeout.reset(); + timeout.start(); + while (timeout.read_us() < 500) { + // Typical and Maximum Word Programming times are 9us and 360us for Am29BL802C + // Allow at least 500 microseconds program time 500 * (1us + BDM memread time) + // NOTE: 29/39F010 and 29F400 programming times are considerably lower uint16_t verify_value; if ((memread_word(&verify_value, addr) == TERM_OK) && (verify_value == value)) { @@ -699,6 +1441,56 @@ return false; } + +//----------------------------------------------------------------------------- +/** +Writes a word to a FLASH memory chip and checks the result +MCU must be in background mode. + +@param addr BDM driver address (0 to continue) +@param maxtime how long to allow driver to execute (milliseconds) + +@return succ / fail +*/ +bool run_bdm_driver(uint32_t addr, uint32_t maxtime) +{ + // Start BDM driver and allow it up to 200 milliseconds to update 256 Bytes + // Upto 25 pulses per byte, 16us per pulse, 256 Bytes + // 25 * 16 * 256 = 102,400us plus overhead for driver code execution time + // Allowing up to 200 milliseconds seems like a good allowance. + uint32_t driverAddress = addr; + if (run_chip(&driverAddress) != TERM_OK) { + printf("Failed to start BDM driver.\r\n"); + return false; + } + timeout.reset(); + timeout.start(); + // T5 ECUs' BDM interface seem to have problems when the running the CPU and + // sometimes shows the CPU briefly switching between showing BDM mode or that + // the CPU is running. + // I 'debounce' the interface state to workaround this erratic bahaviour + for (uint32_t debounce = 0; debounce < 5; debounce++) { + while (IS_RUNNING) { + debounce = 0; + if (timeout.read_ms() > maxtime) { + printf("Driver did not return to BDM mode.\r\n"); + timeout.stop(); + return false; + } + } + wait_us(1); + } + timeout.stop(); + // Check return code in D0 register (0 - OK, 1 - FAILED) + uint32_t result = 1; + if (adreg_read(&result, 0x0) != TERM_OK) { + printf("Failed to read BDM register.\r\n"); + return false; + } + return (result == 1) ? false : true; +} + + //----------------------------------------------------------------------------- /** Resets a AM28Fxxx flash memory chip. MCU must be in background mode. @@ -742,10 +1534,11 @@ addr += 2; // // feedback to host computer // pc.putc(TERM_OK); - // make the activity LED twinkle - ACTIVITYLEDON; - if (!(addr % 0x80)) + if (!(addr % 0x80)) { + // make the activity LED twinkle + ACTIVITYLEDON; printf("%6.2f\r", 100*(float)addr/(float)*end_addr ); + } } printf("\n"); @@ -777,8 +1570,11 @@ addr++; // make the activity LED twinkle ACTIVITYLEDON; - if (!(addr % 0x80)) + if (!(addr % 0x80)) { + // make the activity LED twinkle + ACTIVITYLEDON; printf("%6.2f\r", 100*(float)addr/(float)*end_addr ); + } } } printf("\n"); @@ -918,7 +1714,8 @@ uint8_t prep_t5_do(void) { - + // Make sure that BDM clock is SLOW + bdm_clk_mode(SLOW); // reset and freeze the MC68332/377 chip if (restart_chip() != TERM_OK) return TERM_ERR; @@ -940,7 +1737,10 @@ // MC68377 MCR = x111111x01001111 binary after a reset if ((verify_value & 0x7E4F) == 0x7E4F) { printf ("I have found a Trionic 8 ECU.\r\n"); -// Set MC68377 to double it's default speed (16 MHz?) (SYNCR) + // Stop system protection (MDR bit 0 STOP-SYS-PROT) + long_value = 0x00fffa04; + if (memwrite_byte(&long_value, 0x01) != TERM_OK) return TERM_ERR; + // Set MC68377 to double it's default speed (16 MHz?) (SYNCR) long_value = 0x00fffa08; // First set the MFD part (change 4x to 8x) if (memwrite_word(&long_value, 0x6908) != TERM_OK) return TERM_ERR; @@ -951,7 +1751,11 @@ // Disable watchdog and monitors (SYPCR) long_value = 0x00fffa50; if (memwrite_word(&long_value, 0x0000) != TERM_OK) return TERM_ERR; - return TERM_OK; + // Enable internal 6kByte RAM of 68377 at address 0x00100000 (DPTRAM) + long_value = 0x00fff684; + if (memwrite_word(&long_value, 0x1000) != TERM_OK) return TERM_ERR; + // can use fast or turbo or nitrous BDM clock mode once ECU has been prepped and CPU clock is ??MHz +// bdm_clk_mode(NITROUS); } // MC68332 SIMCR = 0000x00011001111 binary after a reset //if ((verify_value & 0x00CF) == 0x00CF) { @@ -985,12 +1789,13 @@ // wait for programming voltage to be ready wait_ms(10); // Enable internal 2kByte RAM of 68332 at address 0x00100000 (TRAMBAR) - //long_value = 0x00fffb04; - //if (memwrite_word(&long_value, 0x1000) != TERM_OK) return TERM_ERR; - return TERM_OK; + long_value = 0x00fffb04; + if (memwrite_word(&long_value, 0x1000) != TERM_OK) return TERM_ERR; + // can use fast or turbo BDM clock mode once ECU has been prepped and CPU clock is 16MHz +// bdm_clk_mode(TURBO); +// bdm_clk_mode(FAST); } -// Unknown MC683xx chip if code reaches this point - return TERM_ERR; + return TERM_OK; }
diff -r 682d96ff6d79 -r 1775b4b13232 bdmtrionic.h --- a/bdmtrionic.h Wed Sep 11 11:55:51 2013 +0000 +++ b/bdmtrionic.h Sat Apr 25 17:07:08 2015 +0000 @@ -25,6 +25,7 @@ #include "common.h" #include "bdmcpu32.h" +#include "bdmdriver.h" // global variables static bool verify_flash = 1;
diff -r 682d96ff6d79 -r 1775b4b13232 canutils.cpp --- a/canutils.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/canutils.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -26,17 +26,20 @@ //LPC_CANx->MOD |= (1 << 1); // Put into listen only mode //LPC_CANx->MOD &= ~(1); // Re-enable CAN controller -void can_disable(uint8_t chan) { +void can_disable(uint8_t chan) +{ // Put a CAN controller into disabled condition chan == 1 ? LPC_CAN1->MOD |= 1 : LPC_CAN2->MOD |= 1; } -void can_enable(uint8_t chan) { +void can_enable(uint8_t chan) +{ // Put a CAN controller in operating mode chan == 1 ? LPC_CAN1->MOD &= ~(1) : LPC_CAN2->MOD &= ~(1); } -void can_configure(uint8_t chan, uint32_t baud, bool listen) { +void can_configure(uint8_t chan, uint32_t baud, bool listen) +{ LPC_CAN_TypeDef *pCANx = (chan == 1) ? LPC_CAN1 : LPC_CAN2; @@ -92,7 +95,8 @@ } -void can_reset_filters() { +void can_reset_filters() +{ // Initialise the Acceptance Filters LPC_CANAF->AFMR = 0x01; // Put Acceptance Filter into reset/configuration mode for (uint16_t i = 0; i < 512; i++) @@ -105,7 +109,8 @@ LPC_CANAF->AFMR = 0x00; // Enable Acceptance Filter all messages should be rejected } -void can_use_filters(bool active) { +void can_use_filters(bool active) +{ active ? LPC_CANAF->AFMR = 0 : LPC_CANAF->AFMR = 2; } @@ -114,7 +119,8 @@ original http://www.dragonwake.com/download/LPC1768/Example/CAN/CAN.c simplified for CAN2 interface and std id (11 bit) only *--------------------------------------------*/ -void can_add_filter(uint8_t chan, uint32_t id) { +void can_add_filter(uint8_t chan, uint32_t id) +{ static int CAN_std_cnt = 0; uint32_t buf0, buf1; @@ -197,29 +203,34 @@ } // CAN2_wrFilter -void can_open() { +void can_open() +{ // activate external can transceiver can.reset(); can_rs_pin = 0; } -void can_close() { +void can_close() +{ // disable external can transceiver can_rs_pin = 1; can.reset(); } -void can_monitor() { +void can_monitor() +{ // Put CAN into silent monitoring mode can.monitor(1); } -void can_active() { +void can_active() +{ // Take CAN out of silent monitoring mode can.monitor(0); } -uint8_t can_set_speed(uint32_t speed) { +uint8_t can_set_speed(uint32_t speed) +{ // 600kbit/s first - basically sets up CAN interface, but to wrong speed - not sure what else it does // can.frequency(600000); // 615kbit/s direct write of 615 kbit/s speed setting @@ -235,7 +246,8 @@ // inputs: none // return: bool TRUE if there was a message, FALSE if no message. // -extern void show_can_message() { +extern void show_can_message() +{ CANMessage can_MsgRx; if (can.read(can_MsgRx)) { CANRXLEDON; @@ -256,7 +268,8 @@ // inputs: none // return: bool TRUE if there was a message, FALSE if no message. // -extern void show_T5can_message() { +extern void show_T5can_message() +{ CANMessage can_MsgRx; if (can.read(can_MsgRx)) { CANRXLEDON; @@ -282,7 +295,8 @@ // inputs: none // return: bool TRUE if there was a message, FALSE if no message. // -extern void show_T7can_message() { +extern void show_T7can_message() +{ CANMessage can_MsgRx; if (can.read(can_MsgRx)) { CANRXLEDON; @@ -324,7 +338,8 @@ // inputs: none // return: bool TRUE if there was a message, FALSE if no message. // -extern void show_T8can_message() { +extern void show_T8can_message() +{ CANMessage can_MsgRx; if (can.read(can_MsgRx)) { CANRXLEDON; @@ -354,7 +369,8 @@ // inputs: none // return: bool TRUE if there was a message, FALSE if no message. // -extern void silent_can_message() { +extern void silent_can_message() +{ CANMessage can_MsgRx; if (can.read(can_MsgRx)) { CANRXLEDON; @@ -369,9 +385,17 @@ // return: TRUE if the CAN message was sent before the 'timeout' expires // FALSE if 'timeout' expires or the message length is wrong // -extern bool can_send_timeout (uint32_t id, char *frame, uint8_t len, uint16_t timeout) { +extern bool can_send_timeout (uint32_t id, char *frame, uint8_t len, uint16_t timeout) +{ CANTimer.reset(); CANTimer.start(); +#ifdef DEBUG + printf("ID:%03x Len:%03x", id, len); + for (char i=0; i<len; i++) { + printf(" %02x", frame[i]); + } + printf("\n\r"); +#endif while (CANTimer.read_ms() < timeout) { if (can.write(CANMessage(id, frame, len))) { CANTimer.stop(); @@ -396,24 +420,25 @@ // return: TRUE if a qualifying message was received // FALSE if 'timeout' expires or the message length is wrong // -extern bool can_wait_timeout (uint32_t id, char *frame, uint8_t len, uint16_t timeout) { +extern bool can_wait_timeout (uint32_t id, char *frame, uint8_t len, uint16_t timeout) +{ CANMessage CANMsgRx; CANTimer.reset(); CANTimer.start(); while (CANTimer.read_ms() < timeout) { if (can.read(CANMsgRx)) { - /* - printf("w%03x8", CANMsgRx.id); - for (char i=0; i<len; i++) { - printf("%02x", CANMsgRx.data[i]); - } - printf("\n\r"); - // */ +#ifdef DEBUG + printf("ID:%03x Len:%03x", CANMsgRx.id, CANMsgRx.len); + for (char i=0; i<len; i++) { + printf(" %02x", CANMsgRx.data[i]); + } + printf("\n\r"); +#endif CANRXLEDON; // led2 = 1; if (CANMsgRx.id == id || id ==0) { CANTimer.stop(); -// if (T5MsgRx.len != len) +// if (CANMsgRx.len != len) // return FALSE; for (int i=0; i<len; i++) frame[i] = CANMsgRx.data[i];
diff -r 682d96ff6d79 -r 1775b4b13232 common.h --- a/common.h Wed Sep 11 11:55:51 2013 +0000 +++ b/common.h Sat Apr 25 17:07:08 2015 +0000 @@ -29,6 +29,8 @@ #include "sizedefs.h" #include "strings.h" #include "interfaces.h" +#include "t8bootloaders.h" +#include "t5bootloaders.h" // build configuration //#define IGNORE_VCC_PIN ///< uncomment to ignore the VCC pin @@ -60,19 +62,33 @@ #define FILE_BUF_LENGTH 0x1000 ///< file buffer size static char file_buffer[FILE_BUF_LENGTH]; ///< file buffer +static const uint8_t T8BootloaderRead[] = T8_BOOTLOADER_DUMP; +static const uint8_t T8BootLoaderWrite[] = T8_BOOTLOADER_PROG; + +static const uint8_t T5BootLoader[] = MYBOOTY; + // FLASH chip manufacturer id values #define AMD 0x01 #define CSI 0x31 #define INTEL 0x89 +#define ATMEL 0x1F +#define SST 0xBF +#define ST 0x20 +#define AMIC 0x37 // FLASH chip type values #define INTEL28F512 0xB8 #define AMD28F512 0x25 -#define INTEL28F010 0xB4 +#define INTEL28F010 0xB4 // and CSI #define AMD28F010 0xA7 -#define AMD29F010 0x20 +#define AMD29F010 0x20 // and ST +#define ATMEL29C512 0x5D +#define ATMEL29C010 0xD5 +#define SST39SF010 0xB5 +#define ST29F010 0x20 +#define AMICA29010L 0xA4 #define AMD29F400T 0x23 -#define AMD29F400B 0xAB +#define AMD29F400B 0xAB // !!! NOT USED IN T7 !!! //#define 29F400T 0x2223 //#define 29F400B 0x22AB #define AMD29BL802C 0x81
diff -r 682d96ff6d79 -r 1775b4b13232 gmlan.cpp --- a/gmlan.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/gmlan.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -1,5 +1,8 @@ #include "gmlan.h" +Timer GMLANtimer; + + void GMLANTesterPresentAll() { char GMLANMsg[] = GMLANTesterPresentFunctional; @@ -7,58 +10,61 @@ ACTIVITYLEDON; } -void GMLANTesterPresentT8() +void GMLANTesterPresent(uint32_t ReqID, uint32_t RespID) { char GMLANMsg[] = GMLANTesterPresentPhysical; - can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT); - can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT); + can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT); + can_wait_timeout(RespID, GMLANMsg, 2, GMLANPTCT); ACTIVITYLEDON; } // All steps needed in preparation for using a bootloader ('Utility File' in GMLAN parlance) -bool GMLANprogrammingSetupProcess() +bool GMLANprogrammingSetupProcess(uint32_t ReqID, uint32_t RespID) { + GMLANTesterPresent(ReqID, RespID); printf("Starting Diagnostic session\r\n"); - if (!GMLANinitiateDiagnostic(GMLANdisableAllDTCs)) { + if (!GMLANinitiateDiagnostic(ReqID, RespID, GMLANdisableAllDTCs)) { printf("Unable to start Diagnostic session\r\n"); return FALSE; } printf("Disabling Normal Communincation Messages\r\n"); - if (!GMLANdisableNormalCommunication()) { + if (!GMLANdisableNormalCommunication(ReqID, RespID)) { printf("Unable to tell T8 to disable normal communication messages\r\n"); return FALSE; } printf("Report Programmed State\r\n"); - if (!GMLANReportProgrammedState()) { + if (!GMLANReportProgrammedState(ReqID, RespID)) { printf("Unable to determine ECU programmed state\r\n"); - return FALSE; } printf("Requesting program mode\r\n"); - if (!GMLANProgrammingMode(GMLANRequestProgrammingNormal)) { + if (!GMLANProgrammingMode(ReqID, RespID, GMLANRequestProgrammingNormal)) { printf("Unable to request programming mode\r\n"); return FALSE; } printf("Starting program session\r\n"); - if (!GMLANProgrammingMode(GMLANEnableProgrammingMode)) { + if (!GMLANProgrammingMode(ReqID, RespID, GMLANEnableProgrammingMode)) { printf("Unable to start program session\r\n"); return FALSE; } + wait_ms(500); // was 5 return TRUE; } // All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance) -bool GMLANprogrammingUtilityFileProcess(char UtilityFile[]) +bool GMLANprogrammingUtilityFileProcess(uint32_t ReqID, uint32_t RespID, const uint8_t UtilityFile[]) { uint16_t i = 0, j = 0, k = 0; uint32_t StartAddress = 0x102400; uint16_t txpnt = 0; char iFrameNumber = 0x21; char GMLANMsg[8]; - //char BootLoader[] = T8Bootloader; // + GMLANTesterPresent(ReqID, RespID); + GMLANtimer.start(); printf("Waiting for Permission to send bootloader\r\n"); - if (!GMLANRequestDownload(GMLANRequestDownloadModeNormal)) { + wait_ms(500); + if (!GMLANRequestDownload(ReqID, RespID, GMLANRequestDownloadModeNormal)) { printf("Unable to request Bootloader Upload\r\n"); return FALSE; } @@ -66,7 +72,7 @@ printf(" 0.00 %% complete.\r"); // for (i=0; i<0x46; i++) { - if (!GMLANDataTransferFirstFrame(0xF0, GMLANDOWNLOAD, StartAddress)) { + if (!GMLANDataTransferFirstFrame(ReqID, RespID, 0xF0, GMLANDOWNLOAD, StartAddress)) { printf("Unable to start Bootloader Upload\r\n"); return FALSE; } @@ -75,48 +81,24 @@ GMLANMsg[0] = iFrameNumber; for (k=1; k<8; k++) GMLANMsg[k] = UtilityFile[txpnt++]; -#ifdef DEBUG - for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) { + if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) { printf("Unable to send Bootloader\r\n"); return FALSE; } ++iFrameNumber &= 0x2F; - wait_ms(1); -// wait_us(500); - } - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) { - printf("I didn't receive a block acknowledge message\r\n"); - return FALSE; - } - while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) { - printf("I'm waiting for a BootLoader Block to upload\r\n"); - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) { - printf("I didn't receive a block acknowledge message after enhanced timeout\r\n"); - return FALSE; - } + wait_ms(2); // was 2 } -#ifdef DEBUG - for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) { - GMLANShowReturnCode(GMLANMsg[3]); + if (!GMLANDataTransferBlockAcknowledge(RespID)) return FALSE; + if (GMLANtimer.read_ms() > 2000) { + GMLANTesterPresent(ReqID, RespID); + GMLANtimer.reset(); } - if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) { - printf("EXITING due to an unexpected CAN message\r\n"); - return FALSE; - } - GMLANTesterPresentT8(); - ACTIVITYLEDON; StartAddress += 0xea; printf("%6.2f\r", 100*(float)txpnt/(float)(16384+(70*4)) ); } wait_ms(1); - if (!GMLANDataTransferFirstFrame(0x0A, GMLANDOWNLOAD, StartAddress)) { + if (!GMLANDataTransferFirstFrame(ReqID, RespID, 0x0A, GMLANDOWNLOAD, StartAddress)) { printf("Unable to finish Bootloader Upload\r\n"); return FALSE; } @@ -125,195 +107,147 @@ for (k=0; k<7; k++) { GMLANMsg[k+1] = UtilityFile[txpnt++]; } - if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) { + if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) { printf("Unable to finish sending Bootloader\r\n"); return FALSE; } - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) return FALSE; -#ifdef DEBUG - for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif printf("%6.2f\r\n", (float)100 ); printf("Starting the bootloader\r\n"); - if (!GMLANDataTransfer(0x06, GMLANEXECUTE, 0x00102460)) { + if (!GMLANDataTransfer(ReqID, RespID, 0x06, GMLANEXECUTE, 0x00102460)) { printf("Unable to start the Bootloader\r\n"); return FALSE; } - wait_ms(500); + wait_ms(500); // was 100 return TRUE; } -bool GMLANinitiateDiagnostic(char level) +bool GMLANinitiateDiagnostic(uint32_t ReqID, uint32_t RespID, char level) { char GMLANMsg[] = GMLANinitiateDiagnosticOperation; GMLANMsg[2] = level; - if (!can_send_timeout(T8RequestId, GMLANMsg, 3, GMLANPTCT)) + if (!can_send_timeout(ReqID, GMLANMsg, 3, GMLANPTCT)) return FALSE; - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) + if (ReqID == T8USDTREQID) return TRUE; + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) return FALSE; while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x10 && GMLANMsg[3] == 0x78) - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) return FALSE; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x10 ) GMLANShowReturnCode(GMLANMsg[3]); return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x50) ? TRUE : FALSE; } -bool GMLANdisableNormalCommunication() +bool GMLANdisableNormalCommunication(uint32_t ReqID, uint32_t RespID) { char GMLANMsg[] = GMLANdisableCommunication; - if (!can_send_timeout(T8RequestId, GMLANMsg, 2, GMLANPTCT)) - return FALSE; - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) + if (!can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT)) return FALSE; - while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78) - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) + if (ReqID == T8USDTREQID) return TRUE; + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) + return FALSE; + while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x28 && GMLANMsg[3] == 0x78) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) return FALSE; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x28 ) GMLANShowReturnCode(GMLANMsg[3]); return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x68) ? TRUE : FALSE; } -bool GMLANReportProgrammedState() +bool GMLANReportProgrammedState(uint32_t ReqID, uint32_t RespID) { char GMLANMsg[] = GMLANReportProgrammed; - if (!can_send_timeout(T8RequestId, GMLANMsg, 2, GMLANPTCT)) + if (!can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT)) return FALSE; - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) return FALSE; - while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78) - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) + while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA2 && GMLANMsg[3] == 0x78) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) return FALSE; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA2 ) GMLANShowReturnCode(GMLANMsg[3]); return (GMLANMsg[0] == 0x02 && GMLANMsg[1] == 0xE2) ? TRUE : FALSE; } -bool GMLANProgrammingMode(char mode) +bool GMLANProgrammingMode(uint32_t ReqID, uint32_t RespID, char mode) { char GMLANMsg[] = GMLANProgramming; GMLANMsg[2] = mode; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if (!can_send_timeout(T8RequestId, GMLANMsg, 3, GMLANPTCT)) + if (!can_send_timeout(ReqID, GMLANMsg, 3, GMLANPTCT)) return FALSE; if (mode == GMLANEnableProgrammingMode) return TRUE; // No response expected when enabling program mode - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) return FALSE; - while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78) - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) + while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA5 && GMLANMsg[3] == 0x78) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) return FALSE; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0xA5 ) GMLANShowReturnCode(GMLANMsg[3]); return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0xE5) ? TRUE : FALSE; } -bool GMLANSecurityAccessRequest(char level, uint16_t& seed) +bool GMLANSecurityAccessRequest(uint32_t ReqID, uint32_t RespID, char level, uint16_t& seed) { char GMLANMsg[] = GMLANSecurityAccessSeed; GMLANMsg[2] = level; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if (!can_send_timeout(T8RequestId, GMLANMsg, 3, GMLANPTCT)) + if (!can_send_timeout(ReqID, GMLANMsg, 3, GMLANPTCT)) return FALSE; - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) return FALSE; - while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78) - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) + while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 && GMLANMsg[3] == 0x78) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) return FALSE; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif seed = GMLANMsg[3] << 8 | GMLANMsg[4]; if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 ) GMLANShowReturnCode(GMLANMsg[3]); return (GMLANMsg[0] == 0x04 && GMLANMsg[1] == 0x67 && GMLANMsg[2] == level) ? TRUE : FALSE; } -bool GMLANSecurityAccessSendKey(char level, uint16_t key) +bool GMLANSecurityAccessSendKey(uint32_t ReqID, uint32_t RespID, char level, uint16_t key) { char GMLANMsg[] = GMLANSecurityAccessKey; GMLANMsg[2] = level+1; GMLANMsg[3] = (key >> 8) & 0xFF; GMLANMsg[4] = key & 0xFF; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if (!can_send_timeout(T8RequestId, GMLANMsg, 5, GMLANPTCT)) + if (!can_send_timeout(ReqID, GMLANMsg, 5, GMLANPTCT)) return FALSE; - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) return FALSE; - while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78) - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) + while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 && GMLANMsg[3] == 0x78) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) return FALSE; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x27 ) GMLANShowReturnCode(GMLANMsg[3]); return (GMLANMsg[0] == 0x02 && GMLANMsg[1] == 0x67 && GMLANMsg[2] == level+1) ? TRUE : FALSE; } -bool GMLANRequestDownload(char dataFormatIdentifier) +bool GMLANRequestDownload(uint32_t ReqID, uint32_t RespID, char dataFormatIdentifier) { char GMLANMsg[] = GMLANRequestDownloadMessage; GMLANMsg[2] = dataFormatIdentifier; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if (!can_send_timeout(T8RequestId, GMLANMsg, 7, GMLANPTCT)) + if (!can_send_timeout(ReqID, GMLANMsg, 7, GMLANPTCT)) + return FALSE; + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) return FALSE; - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) - return FALSE; -// while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78) while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x34 && GMLANMsg[3] == 0x78) { - printf("Erasing\r\n"); - GMLANTesterPresentT8(); - ACTIVITYLEDON; - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) + printf("Waiting\r\n"); + GMLANTesterPresent(T8REQID, T8RESPID); + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) return FALSE; } -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x34 ) GMLANShowReturnCode(GMLANMsg[3]); return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x74) ? TRUE : FALSE; } -bool GMLANDataTransfer(char length, char function, uint32_t address) +bool GMLANDataTransfer(uint32_t ReqID, uint32_t RespID, char length, char function, uint32_t address) { char GMLANMsg[8]; GMLANMsg[0] = length; @@ -324,28 +258,20 @@ GMLANMsg[5] = (char) (address >> 8); GMLANMsg[6] = (char) (address); GMLANMsg[7] = 0xaa; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) + if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) return FALSE; - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) return FALSE; - while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78) - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) + while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) return FALSE; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) GMLANShowReturnCode(GMLANMsg[3]); return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x76) ? TRUE : FALSE; } -bool GMLANDataTransferFirstFrame(char length, char function, uint32_t address) +bool GMLANDataTransferFirstFrame(uint32_t ReqID, uint32_t RespID, char length, char function, uint32_t address) { char GMLANMsg[8]; GMLANMsg[0] = 0x10; @@ -356,55 +282,66 @@ GMLANMsg[5] = (char) (address >> 16); GMLANMsg[6] = (char) (address >> 8); GMLANMsg[7] = (char) (address); -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) + if (!can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) return FALSE; - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) return FALSE; - while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78) - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) + while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) return FALSE; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) GMLANShowReturnCode(GMLANMsg[3]); return (GMLANMsg[0] == 0x30 && GMLANMsg[1] == 0x00 && GMLANMsg[2] == 0x00) ? TRUE : FALSE; } -bool GMLANDataTransferConsecutiveFrame(char framenumber, char data[7]) +bool GMLANDataTransferConsecutiveFrame(uint32_t ReqID, char framenumber, char data[8]) { char GMLANMsg[8]; GMLANMsg[0] = framenumber; for (char k = 0; k < 7; k++ ) GMLANMsg[k+1] = data[k]; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - return (can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) ? TRUE : FALSE; + return (can_send_timeout(ReqID, GMLANMsg, 8, GMLANPTCT)) ? TRUE : FALSE; } -bool GMLANReturnToNormalMode() +bool GMLANDataTransferBlockAcknowledge(uint32_t RespID) { - char GMLANMsg[] = GMLANRetrunToNormalModeMessage; - if (!can_send_timeout(T8RequestId, GMLANMsg, 2, GMLANPTCT)) - return FALSE; - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) + char GMLANMsg[8]; + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) { + printf("\r\nI did not receive a block acknowledge message\r\n"); return FALSE; - while (GMLANMsg[0] == 0x7F && GMLANMsg[2] == 0x78) - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) + } + if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) { + while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) { + printf("\r\nI'm waiting for a block acknowledge message\r\n"); + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) { + printf("I did not receive a block acknowledge message after enhanced timeout\r\n"); + return FALSE; + } + } + if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) { + GMLANShowReturnCode(GMLANMsg[3]); + return FALSE; + } + if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) { + printf("\r\nEXITING due to an unexpected CAN message\r\n"); return FALSE; -#ifdef DEBUG - for (char k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x28 ) + } + } + return TRUE; +} + +bool GMLANReturnToNormalMode(uint32_t ReqID, uint32_t RespID) +{ + char GMLANMsg[] = GMLANReturnToNormalModeMessage; + if (!can_send_timeout(ReqID, GMLANMsg, 2, GMLANPTCT)) + return FALSE; + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCT)) + return FALSE; + while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x20 && GMLANMsg[3] == 0x78) + if (!can_wait_timeout(RespID, GMLANMsg, 8, GMLANPTCTENHANCED)) + return FALSE; + if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x20 ) GMLANShowReturnCode(GMLANMsg[3]); return (GMLANMsg[0] == 0x01 && GMLANMsg[1] == 0x60) ? TRUE : FALSE; }
diff -r 682d96ff6d79 -r 1775b4b13232 gmlan.h --- a/gmlan.h Wed Sep 11 11:55:51 2013 +0000 +++ b/gmlan.h Sat Apr 25 17:07:08 2015 +0000 @@ -11,8 +11,13 @@ #include "common.h" #include "canutils.h" -#define T8RequestId 0x7E0 -#define T8ResponseId 0x7E8 +#define T8REQID 0x7E0 +#define T8RESPID 0x7E8 + +#define T8USDTREQID 0x011 +#define T8UUDTRESPID 0x311 +#define T8USDTRESPID 0x411 + #define GMLANALLNODES 0x101 #define GMLANMESSAGETIMEOUT 50 // 50 milliseconds (0.05 of a second) - Seems to be plenty of time to wait for messages on the CAN bus @@ -24,42 +29,42 @@ #define GMLANTesterPresentPhysical {0x01,0x3E,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa} #define GMLANTesterPresentFunctional {0xFE,0x01,0x3E,0xaa,0xaa,0xaa,0xaa,0xaa} extern void GMLANTesterPresentAll(); -extern void GMLANTesterPresentT8(); +extern void GMLANTesterPresent(uint32_t ReqID, uint32_t RespID); // All steps needed in preparation for using a bootloader ('Utility File' in GMLAN parlance) -bool GMLANprogrammingSetupProcess(); +bool GMLANprogrammingSetupProcess(uint32_t ReqID, uint32_t RespID); // All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance) -bool GMLANprogrammingUtilityFileProcess(char UtilityFile[]); +bool GMLANprogrammingUtilityFileProcess(uint32_t ReqID, uint32_t RespID, const uint8_t UtilityFile[]); // Start a Diagnostic Session #define GMLANinitiateDiagnosticOperation {0x02,0x10,0x02,0xaa,0xaa,0xaa,0xaa,0xaa} #define GMLANdisableAllDTCs 0x02 -bool GMLANinitiateDiagnostic(char level); +bool GMLANinitiateDiagnostic(uint32_t ReqID, uint32_t RespID, char level); // Tell T8 To disable normal communication messages #define GMLANdisableCommunication {0x01,0x28,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa} -bool GMLANdisableNormalCommunication(); +bool GMLANdisableNormalCommunication(uint32_t ReqID, uint32_t RespID); // Tell T8 To report programmed state #define GMLANReportProgrammed {0x01,0xA2,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa} -bool GMLANReportProgrammedState(); +bool GMLANReportProgrammedState(uint32_t ReqID, uint32_t RespID); // Tell T8 To request or initiate programming #define GMLANProgramming {0x02,0xA5,0x00,0xaa,0xaa,0xaa,0xaa,0xaa} #define GMLANRequestProgrammingNormal 0x01 // I or P-Bus speed #define GMLANRequestProgrammingFast 0x02 // 83.333 kbps for single-wire CAN #define GMLANEnableProgrammingMode 0x03 // Tell T8 To initiate programming -bool GMLANProgrammingMode(char mode); +bool GMLANProgrammingMode(uint32_t ReqID, uint32_t RespID, char mode); // authenticate with T8 #define GMLANSecurityAccessSeed {0x02,0x27,0x01,0xaa,0xaa,0xaa,0xaa,0xaa} -bool GMLANSecurityAccessRequest(char level, uint16_t& seed); +bool GMLANSecurityAccessRequest(uint32_t ReqID, uint32_t RespID, char level, uint16_t& seed); #define GMLANSecurityAccessKey {0x04,0x27,0x02,0xCA,0xFE,0xaa,0xaa,0xaa} -bool GMLANSecurityAccessSendKey(char level, uint16_t key); +bool GMLANSecurityAccessSendKey(uint32_t ReqID, uint32_t RespID, char level, uint16_t key); // Tell T8 We are Requesting a download session #define GMLANRequestDownloadMessage {0x06,0x34,0x00,0x00,0x00,0x00,0x00,0xaa} @@ -67,19 +72,20 @@ #define GMLANRequestDownloadModeEncrypted 0x01 #define GMLANRequestDownloadModeCompressed 0x10 #define GMLANRequestDownloadModeCompressedEncrypted 0x11 -bool GMLANRequestDownload(char dataFormatIdentifier); +bool GMLANRequestDownload(uint32_t ReqID, uint32_t RespID, char dataFormatIdentifier); // Data blocks are sent using this message type #define GMLANDataTransferMessage {0x10,0xF0,0x36,0x00,0xCA,0xFE,0xBA,0xBE} #define GMLANDOWNLOAD 0x00 #define GMLANEXECUTE 0x80 -bool GMLANDataTransfer(char length, char function, uint32_t address); -bool GMLANDataTransferFirstFrame(char length, char function, uint32_t address); -bool GMLANDataTransferConsecutiveFrame(char framenumber, char data[7]); +bool GMLANDataTransfer(uint32_t ReqID, uint32_t RespID, char length, char function, uint32_t address); +bool GMLANDataTransferFirstFrame(uint32_t ReqID, uint32_t RespID, char length, char function, uint32_t address); +bool GMLANDataTransferConsecutiveFrame(uint32_t ReqID, char framenumber, char data[7]); +bool GMLANDataTransferBlockAcknowledge(uint32_t RespID); // Tell T8 ECU to return to normal mode after FLASHing -#define GMLANRetrunToNormalModeMessage {0x01,0x20,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa} -bool GMLANReturnToNormalMode(); +#define GMLANReturnToNormalModeMessage {0x01,0x20,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa} +bool GMLANReturnToNormalMode(uint32_t ReqID, uint32_t RespID); // Show a description of GMLAN Return Codes when an error occurs
diff -r 682d96ff6d79 -r 1775b4b13232 interfaces.cpp --- a/interfaces.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/interfaces.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -18,6 +18,8 @@ // A timer for timing how long things take to happen Timer timer; +// A timer for checking that timeout periods aren't exceeded +Timer timeout; // We use CAN on mbed pins 29(CAN_TXD) and 30(CAN_RXD). CAN can(p30, p29);
diff -r 682d96ff6d79 -r 1775b4b13232 interfaces.h --- a/interfaces.h Wed Sep 11 11:55:51 2013 +0000 +++ b/interfaces.h Sat Apr 25 17:07:08 2015 +0000 @@ -24,6 +24,7 @@ extern LocalFileSystem local; //Serial pc(USBTX, USBRX); // tx, rx extern Timer timer; +extern Timer timeout; extern DigitalIn PIN_PWR; // power supply extern DigitalIn PIN_NC; // connection signal
diff -r 682d96ff6d79 -r 1775b4b13232 main.cpp --- a/main.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/main.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -28,9 +28,34 @@ ******************************************************************************** +Version 1.5 (04/2015) + +Added since Version 1.4 + T8 CAN functions: DUMP, FLASH and RECOVERY + Using modified T8Bootloaders that are slightly faster :-) + Algorithms for different types of 5 volt replacement FLASH Chips in T5 ECUs + AMD, ST and AMIC 29F010 types + SST 39F010 + ATMEL 29C512 and 29C010 + +Changes since Version 1.4 + BDM FLASHing uses BD32 like Target Resident Drivers. + Based on my 'universal scripts' + BDM FLASHing much faster now + Always use slow BDM clock function (bdm_clk_slow) for reliability + Even when using the slow method it only takes 8 seconds + longer to FLASH a T8 ECU. + mbed library and compiler changes make it difficult to + maintain the faster bdm functions that rely on software + delay loops for timing. + The file extension of the file to be FLASHed is now the more usual 'BIN'. + i.e. 'modified.bin' instead of 'modified.hex' + +******************************************************************************** + Version 1.4 (07/2013) -Changes since Verion 1.3 +Added since Verion 1.3 Progress indication shown as a percentage, slightly slower but more informative T8 BDM Functionality
diff -r 682d96ff6d79 -r 1775b4b13232 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat Apr 25 17:07:08 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/433970e64889 \ No newline at end of file
diff -r 682d96ff6d79 -r 1775b4b13232 t5bootloaders.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/t5bootloaders.h Sat Apr 25 17:07:08 2015 +0000 @@ -0,0 +1,90 @@ +/******************************************************************************* + +t5bootloaders.h - definitions for the MyBooty bootloader for T5 ECU's +(c) 2010,2011,2012,2013,2014,2015 by Sophie Dexter + +******************************************************************************** + +WARNING: Use at your own risk, sadly this software comes with no guarantees. +This software is provided 'free' and in good faith, but the author does not +accept liability for any damage arising from its use. + +*******************************************************************************/ +#ifndef __T5BOOTLOADERS_H__ +#define __T5BOOTLOADERS_H__ + +// MyBooty bootloader +// +// This is version 2.1 +// +// Start address is 0x5000 +#define MYBOOTY_START 0x5000 +// Send MyBooty in chunks of 0x20 bytes +#define MYBOOTY_CHUNK 0x20 +// The size of the array must be 'padded' out with 0x00's to be a multiple of 0x20 bytes because 't5_can_send_boot_loader' is coded with magic numbers! +#define MYBOOTY {\ +0x4E,0xB8,0x50,0x0C,0x4E,0xB8,0x50,0xAC,0x4E,0xED,0x00,0x04,0x20,0x7C,0x00,0xFF,0xFA,0x04,0x10,0xFC,0x00,0x7F,0x08,0x10,0x00,0x03,0x67,0xFA,0x33,0xFC,0x04,0x05,\ +0x00,0xFF,0xFA,0x48,0x33,0xFC,0x04,0x05,0x00,0xFF,0xFA,0x50,0x33,0xFC,0x04,0x05,0x00,0xFF,0xFA,0x54,0x33,0xFC,0x30,0x30,0x00,0xFF,0xFA,0x52,0x33,0xFC,0x50,0x30,\ +0x00,0xFF,0xFA,0x56,0x02,0x79,0xFF,0xBF,0x00,0xFF,0xFC,0x14,0x00,0x79,0x00,0x10,0x00,0xFF,0xFC,0x14,0x02,0x79,0x8F,0xDF,0x00,0xFF,0xFC,0x16,0x00,0x79,0x00,0x50,\ +0x00,0xFF,0xFC,0x16,0x2A,0x7C,0x00,0x04,0x00,0x00,0x2C,0x7C,0x00,0xFF,0xFA,0x26,0x3C,0x3C,0x55,0x55,0x3E,0x3C,0xAA,0xAA,0x24,0x7C,0x00,0xF0,0x07,0xFF,0x26,0x7C,\ +0x00,0xF0,0x08,0x00,0x40,0xC1,0x00,0x7C,0x07,0x00,0x42,0x12,0x00,0x13,0x00,0x01,0x14,0xBC,0x00,0x01,0x08,0x13,0x00,0x00,0x67,0xFA,0x14,0xBC,0x00,0x04,0x16,0xBC,\ +0x00,0x01,0x42,0x12,0x02,0x13,0x00,0xFE,0x46,0xC1,0x4E,0x75,0x4E,0xB8,0x51,0xE4,0x20,0x7C,0x00,0x00,0x57,0x90,0x22,0x7C,0x00,0x00,0x57,0x98,0x10,0x10,0x12,0xC0,\ +0x12,0xFC,0x00,0x09,0x22,0xFC,0x08,0x08,0x08,0x08,0x32,0xBC,0x08,0x08,0x5B,0x89,0x0C,0x00,0x00,0xC7,0x67,0x00,0x00,0xD8,0x0C,0x00,0x00,0x7F,0x63,0x00,0x00,0x5E,\ +0x0C,0x00,0x00,0xA5,0x67,0x00,0x00,0x42,0x0C,0x00,0x00,0xC0,0x67,0x00,0x00,0x8A,0x0C,0x00,0x00,0xC2,0x67,0x00,0x00,0x9E,0x0C,0x00,0x00,0xC3,0x67,0x00,0x00,0xA4,\ +0x0C,0x00,0x00,0xC8,0x67,0x00,0x00,0xC2,0x0C,0x00,0x00,0xC9,0x67,0x00,0x00,0xC2,0x4E,0xB8,0x52,0x4C,0x0C,0x38,0x00,0xC2,0x57,0x98,0x66,0x90,0x14,0xBC,0x00,0x08,\ +0x08,0x13,0x00,0x06,0x67,0xFA,0x4E,0x75,0x20,0x18,0xE1,0x88,0x80,0x18,0x21,0xC0,0x57,0xA2,0x11,0xD0,0x57,0xA6,0x42,0x11,0x60,0x00,0xFF,0xD6,0x24,0x7C,0x00,0x00,\ +0x57,0xA7,0x70,0x06,0x42,0x81,0x12,0x18,0xD5,0xC1,0x14,0x38,0x57,0xA6,0x14,0xD8,0x52,0x01,0xB2,0x02,0x67,0x0A,0x51,0xC8,0xFF,0xF6,0x42,0x11,0x60,0x00,0xFF,0xB2,\ +0x4E,0xB8,0x54,0xE4,0x12,0xC0,0x67,0x00,0xFF,0xA8,0x22,0x84,0x02,0x79,0xFF,0xBF,0x00,0xFF,0xFC,0x14,0x60,0x00,0xFF,0x9A,0x4E,0xB8,0x56,0xFA,0x4E,0xB8,0x52,0x9C,\ +0x12,0xC0,0x67,0x00,0xFF,0x8C,0x22,0x82,0x02,0x79,0xFF,0xBF,0x00,0xFF,0xFC,0x14,0x60,0x00,0xFF,0x7E,0x02,0x79,0xFF,0xBF,0x00,0xFF,0xFC,0x14,0x42,0x11,0x60,0x00,\ +0xFF,0x70,0x42,0x19,0x22,0xBC,0x00,0x07,0xFF,0xFF,0x60,0x00,0xFF,0x64,0x20,0x18,0xE1,0x88,0x80,0x10,0x24,0x40,0x42,0x19,0x12,0xD2,0x12,0xE2,0x12,0xE2,0x12,0xE2,\ +0x12,0xE2,0x12,0xA2,0x60,0x00,0xFF,0x4A,0x4E,0xB8,0x56,0x70,0x60,0x00,0xFF,0x42,0x4E,0xB8,0x56,0xFA,0x42,0x19,0x22,0xCD,0x12,0xF8,0x57,0xA0,0x12,0xB8,0x57,0xA1,\ +0x60,0x00,0xFF,0x2E,0x20,0x7C,0x00,0x00,0x57,0x90,0x24,0x7C,0x00,0xF0,0x07,0xFF,0x26,0x7C,0x00,0xF0,0x08,0x00,0x40,0xC1,0x00,0x7C,0x07,0x00,0x14,0xBC,0x00,0x02,\ +0x4A,0x13,0x14,0xBC,0x00,0x12,0x08,0x13,0x00,0x00,0x67,0xFA,0x14,0xBC,0x00,0x13,0x08,0x13,0x00,0x06,0x66,0x08,0x46,0xC1,0x3C,0x86,0x3C,0x87,0x60,0xD8,0x14,0xBC,\ +0x00,0x13,0x16,0xBC,0x00,0x08,0x70,0x14,0x74,0x1B,0x14,0x80,0x52,0x00,0x10,0xD3,0xB0,0x02,0x63,0xF6,0x14,0xBC,0x00,0x12,0x08,0x13,0x00,0x00,0x67,0xFA,0x14,0xBC,\ +0x00,0x13,0x08,0x13,0x00,0x06,0x66,0xD6,0x46,0xC1,0x4E,0x75,0x22,0x7C,0x00,0x00,0x57,0x98,0x24,0x7C,0x00,0xF0,0x07,0xFF,0x26,0x7C,0x00,0xF0,0x08,0x00,0x40,0xC1,\ +0x00,0x7C,0x07,0x00,0x14,0xBC,0x00,0x02,0x4A,0x13,0x14,0xBC,0x00,0x06,0x42,0x13,0x14,0xBC,0x00,0x07,0x08,0x13,0x00,0x00,0x67,0xFA,0x70,0x09,0x74,0x10,0x14,0x80,\ +0x52,0x00,0x16,0x99,0xB0,0x02,0x63,0xF6,0x14,0xBC,0x00,0x08,0x16,0xBC,0x00,0x88,0x14,0xBC,0x00,0x06,0x16,0xBC,0x00,0x80,0x46,0xC1,0x4E,0x75,0x10,0x38,0x57,0xA0,\ +0x12,0x38,0x57,0xA1,0x0C,0x00,0x00,0x89,0x66,0x16,0x0C,0x01,0x00,0xB8,0x67,0x00,0x01,0x04,0x0C,0x01,0x00,0xB4,0x67,0x00,0x00,0xF4,0x70,0x04,0x60,0x00,0x02,0x24,\ +0x0C,0x00,0x00,0x01,0x66,0x1E,0x0C,0x01,0x00,0x25,0x67,0x00,0x00,0xE8,0x0C,0x01,0x00,0xA7,0x67,0x00,0x00,0xD8,0x0C,0x01,0x00,0x20,0x67,0x00,0x01,0x8C,0x70,0x05,\ +0x60,0x00,0x02,0x00,0x0C,0x00,0x00,0x31,0x66,0x0E,0x0C,0x01,0x00,0xB4,0x67,0x00,0x00,0xBC,0x70,0x06,0x60,0x00,0x01,0xEC,0x0C,0x00,0x00,0x1F,0x66,0x12,0x0C,0x01,\ +0x00,0xD5,0x67,0x4E,0x0C,0x01,0x00,0x5D,0x67,0x50,0x70,0x07,0x60,0x00,0x01,0xD4,0x0C,0x00,0x00,0xBF,0x66,0x0E,0x0C,0x01,0x00,0xB5,0x67,0x00,0x01,0x4C,0x70,0x08,\ +0x60,0x00,0x01,0xC0,0x0C,0x00,0x00,0x20,0x66,0x0E,0x0C,0x01,0x00,0x20,0x67,0x00,0x01,0x38,0x70,0x09,0x60,0x00,0x01,0xAC,0x0C,0x00,0x00,0x37,0x66,0x0E,0x0C,0x01,\ +0x00,0xA4,0x67,0x00,0x01,0x24,0x70,0x0A,0x60,0x00,0x01,0x98,0x70,0x03,0x60,0x00,0x01,0x92,0x24,0x3C,0x00,0x04,0x00,0x00,0x60,0x06,0x24,0x3C,0x00,0x02,0x00,0x00,\ +0x3B,0x87,0x01,0x70,0x00,0x00,0xAA,0xAA,0x3B,0x46,0x55,0x54,0x3B,0xBC,0x80,0x80,0x01,0x70,0x00,0x00,0xAA,0xAA,0x3B,0x87,0x01,0x70,0x00,0x00,0xAA,0xAA,0x3B,0x46,\ +0x55,0x54,0x3B,0xBC,0x10,0x10,0x01,0x70,0x00,0x00,0xAA,0xAA,0x32,0x3C,0xAB,0xE0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x50,0xC0,0x3C,0x86,0x3C,0x87,0xB0,0x35,0x28,0xFF,\ +0x66,0x00,0x01,0x3E,0x53,0x82,0x66,0xF0,0x60,0x00,0x01,0x32,0x24,0x3C,0x00,0x04,0x00,0x00,0x60,0x06,0x24,0x3C,0x00,0x02,0x00,0x00,0x20,0x02,0x16,0x3C,0x00,0x40,\ +0x18,0x3C,0x00,0xC0,0x3A,0xBC,0xFF,0xFF,0x3A,0xBC,0xFF,0xFF,0x42,0x55,0x4A,0x35,0x28,0xFF,0x67,0x24,0x7A,0x19,0x1B,0x83,0x28,0xFF,0x42,0x35,0x28,0xFF,0x72,0x15,\ +0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x1B,0x84,0x28,0xFF,0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x4A,0x35,0x28,0xFF,0x66,0x0A,0x3C,0x86,0x3C,0x87,0x53,0x82,0x66,0xCC,\ +0x60,0x04,0x53,0x45,0x66,0xD0,0x42,0x55,0x4A,0x55,0x4A,0x05,0x66,0x06,0x70,0x02,0x60,0x00,0x00,0xD0,0x24,0x00,0x50,0xC0,0x16,0x3C,0x00,0x20,0x18,0x3C,0x00,0xA0,\ +0x2A,0x3C,0x03,0xE8,0x03,0xE8,0x1B,0x83,0x28,0xFF,0x1B,0x83,0x28,0xFF,0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x1B,0x84,0x28,0xFF,0x72,0x0C,0x4E,0x71,\ +0x51,0xC9,0xFF,0xFC,0x3C,0x86,0x3C,0x87,0xB0,0x35,0x28,0xFF,0x66,0x08,0x48,0x45,0x53,0x82,0x66,0xE4,0x60,0x04,0x53,0x45,0x66,0xCC,0x42,0x55,0x4A,0x55,0x4A,0x45,\ +0x67,0x00,0x00,0x7E,0x60,0x00,0x00,0x76,0x70,0x01,0x1B,0x87,0x09,0x30,0x00,0x00,0xAA,0xAA,0x1B,0x86,0x09,0x20,0x55,0x54,0x1B,0xBC,0x00,0x80,0x09,0x30,0x00,0x00,\ +0xAA,0xAA,0x1B,0x87,0x09,0x30,0x00,0x00,0xAA,0xAA,0x1B,0x86,0x09,0x20,0x55,0x54,0x1B,0xBC,0x00,0x10,0x09,0x30,0x00,0x00,0xAA,0xAA,0x3C,0x86,0x3C,0x87,0x1A,0x35,\ +0x08,0x00,0x08,0x05,0x00,0x07,0x66,0x2A,0x08,0x05,0x00,0x05,0x67,0xEC,0x1A,0x35,0x08,0x00,0x08,0x05,0x00,0x07,0x66,0x1A,0x1B,0x87,0x09,0x30,0x00,0x00,0xAA,0xAA,\ +0x1B,0x86,0x09,0x20,0x55,0x54,0x1B,0xBC,0x00,0xF0,0x09,0x30,0x00,0x00,0xAA,0xAA,0x60,0x0E,0x53,0x80,0x67,0x00,0xFF,0x94,0x60,0x00,0x00,0x02,0x42,0x80,0x60,0x02,\ +0x70,0x01,0x4E,0x75,0x26,0x7C,0x00,0x00,0x57,0xA2,0x28,0x53,0xBB,0xCC,0x62,0x00,0x01,0x7C,0x42,0x82,0x14,0x2B,0x00,0x04,0x12,0x38,0x57,0xA1,0x0C,0x01,0x00,0x20,\ +0x67,0x00,0x00,0xEE,0x0C,0x01,0x00,0xD5,0x67,0x22,0x0C,0x01,0x00,0x5D,0x67,0x1C,0x0C,0x01,0x00,0xB5,0x67,0x00,0x00,0xDA,0x0C,0x01,0x00,0x20,0x67,0x00,0x00,0xD2,\ +0x0C,0x01,0x00,0xA4,0x67,0x00,0x00,0xCA,0x60,0x00,0x00,0x78,0x20,0x0C,0x02,0x80,0x00,0x00,0x00,0xFF,0x99,0xC0,0x24,0x7C,0x00,0x00,0x58,0x28,0x22,0x3C,0x00,0x00,\ +0x01,0x00,0x35,0xB4,0x18,0xFE,0x18,0xFE,0x55,0x81,0x66,0xF6,0xD5,0xC0,0x22,0x02,0x15,0xB3,0x18,0x04,0x18,0xFF,0x53,0x81,0x66,0xF6,0x95,0xC0,0x3B,0x87,0x01,0x70,\ +0x00,0x00,0xAA,0xAA,0x3B,0x46,0x55,0x54,0x3B,0xBC,0xA0,0xA0,0x01,0x70,0x00,0x00,0xAA,0xAA,0x32,0x3C,0x01,0x00,0x39,0xB2,0x18,0xFE,0x18,0xFE,0x55,0x81,0x66,0xF6,\ +0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x32,0x3C,0x01,0x00,0x36,0x32,0x18,0xFE,0xB6,0x74,0x18,0xFE,0x66,0x00,0x00,0xD4,0x55,0x81,0x66,0xF0,0x60,0x00,\ +0x00,0xC8,0x16,0x3C,0x00,0x40,0x18,0x3C,0x00,0xC0,0x10,0x33,0x28,0x04,0x0C,0x00,0x00,0xFF,0x67,0x24,0x7A,0x19,0x19,0x83,0x28,0xFF,0x19,0x80,0x28,0xFF,0x72,0x15,\ +0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x19,0x84,0x28,0xFF,0x72,0x0C,0x4E,0x71,0x51,0xC9,0xFF,0xFC,0xB0,0x34,0x28,0xFF,0x66,0x06,0x53,0x82,0x66,0xCE,0x60,0x04,0x53,0x05,\ +0x66,0xD4,0x42,0x55,0x4A,0x55,0x4A,0x05,0x67,0x00,0x00,0x82,0x60,0x00,0x00,0x7A,0x12,0x3C,0x00,0xA0,0x20,0x0C,0xD0,0x82,0xC0,0xBC,0x00,0x00,0x00,0x01,0x08,0x40,\ +0x00,0x00,0x16,0x33,0x28,0x04,0x0C,0x03,0x00,0xFF,0x67,0x58,0x1B,0x87,0x09,0x30,0x00,0x00,0xAA,0xAA,0x1B,0x86,0x09,0x20,0x55,0x54,0x1B,0x81,0x09,0x30,0x00,0x00,\ +0xAA,0xAA,0x19,0x83,0x28,0xFF,0xC6,0x3C,0x00,0x80,0x18,0x34,0x28,0xFF,0x1A,0x04,0xC8,0x3C,0x00,0x80,0xB8,0x03,0x67,0x2C,0x08,0x05,0x00,0x05,0x67,0xEC,0x18,0x34,\ +0x28,0xFF,0xC8,0x3C,0x00,0x80,0xB8,0x03,0x67,0x1A,0x1B,0x87,0x09,0x30,0x00,0x00,0xAA,0xAA,0x1B,0x86,0x09,0x20,0x55,0x54,0x1B,0xBC,0x00,0xF0,0x09,0x30,0x00,0x00,\ +0xAA,0xAA,0x60,0x08,0x53,0x82,0x66,0x96,0x42,0x40,0x60,0x02,0x70,0x01,0x4E,0x75,0x24,0x7C,0x00,0x07,0xFF,0xFB,0x42,0x80,0x42,0x81,0x42,0x82,0x42,0x83,0x42,0x84,\ +0x18,0x3C,0x00,0xFD,0x12,0x12,0x67,0x00,0x00,0x6C,0x0C,0x01,0x00,0xFF,0x67,0x00,0x00,0x64,0x10,0x2A,0xFF,0xFF,0x95,0xC1,0x55,0x8A,0xB0,0x04,0x66,0xE6,0x10,0x32,\ +0x18,0x00,0x04,0x00,0x00,0x30,0x0C,0x40,0x00,0x0A,0x65,0x02,0x5F,0x00,0xE9,0x8A,0x84,0x00,0x53,0x01,0x66,0xE8,0xC5,0x43,0x0C,0x04,0x00,0xFE,0x67,0x04,0x52,0x04,\ +0x60,0xC2,0xB6,0x82,0x63,0x2E,0x0C,0x83,0x00,0x07,0xFF,0xFF,0x64,0x26,0x52,0x83,0x24,0x42,0x42,0x80,0x42,0x81,0x3C,0x86,0x3C,0x87,0x12,0x1A,0xD0,0x81,0x12,0x1A,\ +0xD0,0x81,0xB5,0xC3,0x66,0xF0,0xB0,0xB9,0x00,0x07,0xFF,0xFC,0x66,0x06,0x42,0x19,0x22,0x80,0x60,0x04,0x12,0xBC,0x00,0x01,0x4E,0x75,0x24,0x7C,0x00,0x00,0x57,0xA0,\ +0x00,0x79,0x00,0x40,0x00,0xFF,0xFC,0x14,0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x50,0xD5,0x50,0xD5,0x1A,0xBC,0x00,0x90,0x14,0xD5,0x14,0xAD,0x00,0x02,\ +0x50,0xD5,0x50,0xD5,0x0C,0x22,0x00,0x89,0x67,0x64,0x0C,0x12,0x00,0x01,0x67,0x5E,0x0C,0x12,0x00,0x31,0x67,0x58,0x02,0x79,0xFF,0xBF,0x00,0xFF,0xFC,0x14,0x32,0x3C,\ +0xAB,0xE0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x1B,0x87,0x01,0x70,0x00,0x00,0xAA,0xAA,0x1B,0x46,0x55,0x54,0x1B,0xBC,0x00,0x90,0x01,0x70,0x00,0x00,0xAA,0xAA,0x32,0x3C,\ +0x55,0xF0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x14,0xD5,0x14,0xAD,0x00,0x02,0x1B,0x87,0x01,0x70,0x00,0x00,0xAA,0xAA,0x1B,0x46,0x55,0x54,0x1B,0xBC,0x00,0xF0,0x01,0x70,\ +0x00,0x00,0xAA,0xAA,0x32,0x3C,0x55,0xF0,0x4E,0x71,0x51,0xC9,0xFF,0xFC,0x4E,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} + + +#endif \ No newline at end of file
diff -r 682d96ff6d79 -r 1775b4b13232 t5can.cpp --- a/t5can.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/t5can.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -42,7 +42,8 @@ void t5_can_show_help(); void t5_can_show_full_help(); -void t5_can() { +void t5_can() +{ // Start the CAN bus system // Note that at the moment this is only for T5 ECUs at 615 kbits can_open(); @@ -103,7 +104,8 @@ @return command flag (success / failure) */ -uint8_t execute_t5_cmd() { +uint8_t execute_t5_cmd() +{ // uint8_t cmd_length = strlen(cmd_buffer); @@ -151,9 +153,10 @@ // Send a Bootloader file to the T5 ECU case 'b': + return (t5_can_send_boot_loader() && can_set_speed(1000000)) + ? TERM_OK : TERM_ERR; case 'B': - return (t5_can_send_boot_loader() && can_set_speed(1000000)) -// return (t5_can_send_boot_loader() && can_set_speed(615000)) + return (t5_can_send_boot_loader_S19() && can_set_speed(1000000)) ? TERM_OK : TERM_ERR; // Get Checksum from ECU (Bootloader must be uploaded first) @@ -186,8 +189,7 @@ return t5_can_dump_flash(T55FLASHSTART) ? TERM_OK : TERM_ERR; case 'D': - if (!t5_can_get_adaption_data()) - return TERM_ERR; +// if (!t5_can_send_boot_loader_S19()) if (!t5_can_send_boot_loader()) return TERM_ERR; can_set_speed(1000000); @@ -201,10 +203,12 @@ // Send a FLASH update file to the T5 ECU case 'f': - // NOTE 'f' command Just4TESTING! only FLASHes T5.5 ECU (with S19 type file) - return t5_can_send_flash_s19_update(T55FLASHSTART) + // NOTE 'f' command Just4TESTING! only FLASHes T5.5 ECU (with S19 type file) + //return t5_can_send_flash_s19_update(T55FLASHSTART) + return t5_can_send_flash_bin_update(T55FLASHSTART) ? TERM_OK : TERM_ERR; case 'F': +// if (!t5_can_send_boot_loader_S19()) if (!t5_can_send_boot_loader()) return TERM_ERR; can_set_speed(1000000); @@ -251,11 +255,12 @@ // inputs: none // return: none // -void t5_can_show_help() { +void t5_can_show_help() +{ printf("Trionic 5 Command Menu\r\n"); printf("======================\r\n"); - printf("D - Read SRAM adaption and DUMP T5 FLASH BIN file\r\n"); - printf("F - FLASH the update file to the T5 (and write SRAM - not done!)\r\n"); + printf("D - DUMP the T5.x ECU FLASH to a file 'ORIGINAL.BIN'\r\n"); + printf("F - FLASH the update file 'MODIFIED.BIN' to the T5.x\r\n"); printf("\r\n"); printf("r - read SRAM and write it to ADAPTION.RAM file\r\n"); printf("s - read Symbol Table and write it to SYMBOLS.TXT\r\n"); @@ -275,17 +280,18 @@ // inputs: none // return: none // -void t5_can_show_full_help() { +void t5_can_show_full_help() +{ printf("Trionic 5 Command Menu\r\n"); printf("======================\r\n"); - printf("D - Read SRAM adaption and DUMP T5 FLASH BIN file\r\n"); - printf("F - FLASH the update file to the T5 (and write SRAM - not done!)\r\n"); + printf("D - DUMP the T5.x ECU FLASH to a file 'ORIGINAL.BIN'\r\n"); + printf("F - FLASH the update file 'MODIFIED.BIN' to the T5.x\r\n"); printf("\r\n"); printf("b - upload and start MyBooty.S19 bootloader\r\n"); printf("c - get T5 ECU FLASH checksum (need to upload BOOTY.S19 before using this command)\r\n"); printf("d - dump the T5 FLASH BIN file and write it to ORIGINAL.BIN\r\n"); printf("e - erase the FLASH chips in the T5 ECU\r\n"); - printf("f - FLASH the update file MODIFIED.S19 to the T5 ECU\r\n"); + printf("f - FLASH the update file MODIFIED.BIN to the T5 ECU\r\n"); printf("r - read SRAM and write it to ADAPTION.RAM file\r\n"); printf("s - read Symbol Table, display it and write it to SYMBOLS.TXT\r\n"); printf("v - read T5 ECU software version, display it and write it to VERSION.TXT\r\n"); @@ -313,7 +319,8 @@ // inputs: none // return: bool TRUE if there was a message, FALSE if no message. // -bool t5_can_show_can_message() { +bool t5_can_show_can_message() +{ CANMessage can_MsgRx; if (can.read(can_MsgRx)) { printf("w%03x%d", can_MsgRx.id, can_MsgRx.len); @@ -336,7 +343,8 @@ // inputs: none // return: bool TRUE if there all went OK, FALSE if there was an error // -bool t5_can_get_symbol_table() { +bool t5_can_get_symbol_table() +{ printf("Saving the symbol table file\r\n"); FILE *fp = fopen("/local/symbols.txt", "w"); // Open "symbols.txt" on the local file system for writing if (!fp) { @@ -376,7 +384,8 @@ // inputs: none // return: bool TRUE if there all went OK, FALSE if there was an error // -bool t5_can_get_version() { +bool t5_can_get_version() +{ FILE *fp = fopen("/local/version.txt", "w"); // Open "version.txt" on the local file system for writing if (!fp) { perror ("The following error occured"); @@ -416,7 +425,8 @@ // inputs: none // return: bool TRUE if all went OK, FALSE if there was an error. // -bool t5_can_get_adaption_data() { +bool t5_can_get_adaption_data() +{ printf("Saving the SRAM adaption data.\r\n"); FILE *fp = fopen("/local/adaption.RAM", "w"); // Open "adaption.RAM" on the local file system for writing if (!fp) { @@ -468,7 +478,59 @@ // return: bool TRUE if all went OK, // FALSE if the 'bootloader' wasn't sent for some reason. // -bool t5_can_send_boot_loader() { +bool t5_can_send_boot_loader() +{ + uint32_t BootloaderSize = sizeof(T5BootLoader); + uint32_t address = MYBOOTY_START; // Start and execute from address of T5Bootloader + uint32_t count = 0; // progress count of bootloader bytes transferred + char msg[8]; // Construct the bootloader frame for uploading + + printf("Starting the bootloader.\r\n"); + while (count < BootloaderSize) { +// send a bootloader address message + if (!t5_can_send_boot_address((address+count), MYBOOTY_CHUNK)) return FALSE; +// send bootloader frames +// NOTE the last frame sent may have less than 7 real data bytes but 7 bytes are always sent. In this case the unnecessary bytes +// are repeated from the previous frame. This is OK because the T5 ECU knows how many bytes to expect (because the count of bytes +// is sent with the upload address) and ignores any extra bytes in the last frame. + for (uint8_t i=0; i<MYBOOTY_CHUNK; i++) { + msg[1+(i%7)] = T5BootLoader[count+i]; + if (i%7 == 0) msg[0]=i; // set the index number + if ((i%7 == 6) || (i == MYBOOTY_CHUNK-1 )) { + if (!t5_can_send_boot_frame(msg)) return FALSE; + } + } + count += MYBOOTY_CHUNK; + } +// These two lines really shouldn't be necessary but for some reason the first start +// command is ignored and a short delay is required before repeating. Using only a +// delay, even a very long one, doesn't work. +// +// NOTE: This measure isn't required when uploading an external S19 bootloader file! +// + T5StartBootLoader(address); + wait_ms(1); +// + return T5StartBootLoader(address); +} + + +// +// t5_can_send_boot_loader_S19 +// +// Sends a 'bootloader' file, booty.s19 to the T5 ECU. +// The 'bootloader' is stored on the mbed 'local' file system 'disk' and must be in S19 format. +// +// The 'bootloader' is then able to dump or reFLASH the T5 ECU FLASH chips - this is the whole point of the exercise :-) +// +// Sending the 'bootloader' to the T5 ECU takes just over 1 second. +// +// inputs: none +// return: bool TRUE if all went OK, +// FALSE if the 'bootloader' wasn't sent for some reason. +// +bool t5_can_send_boot_loader_S19() +{ printf("Starting the bootloader.\r\n"); FILE *fp = fopen("/local/MyBooty.S19", "r"); // Open "booty.s19" on the local file system for reading if (!fp) { @@ -514,6 +576,7 @@ count--; } // send a bootloader address message +//// printf("address %x count %x\r\n",address ,count-1 ); if (!t5_can_send_boot_address(address, (count-1))) return FALSE; // get and send the bootloader frames for this S-record // NOTE the last frame sent may have less than 7 real data bytes but 7 bytes are always sent. In this case the unnecessary bytes @@ -524,11 +587,13 @@ checksum += c; msg[1+(i%7)] = c; if (i%7 == 0) msg[0]=i; // set the index number - if ((i%7 == 6) || (i == count - 2)) + if ((i%7 == 6) || (i == count - 2)) { +//// printf("Sending %2x %2x %2x %2x %2x %2x %2x %2x \r\n", msg[0], msg[1], msg[2], msg[3], msg[4], msg[5], msg[6], msg[7] ); if (!t5_can_send_boot_frame(msg)) { fclose(fp); return FALSE; } + } } // get the checksum if ((checksum += SRecGetByte(fp)) != 0xFF) { @@ -545,6 +610,7 @@ case '8': case '9': asize = 11 - (c - '0'); // 2, 3 or 4 bytes for address + address = 0; // get the number of bytes (in ascii format) in this S-record line there must be just the address and the checksum // so return with an error if other than this! if ((c = SRecGetByte(fp)) != (asize + 1)) break; @@ -604,7 +670,8 @@ // inputs: none // return: bool TRUE if all went OK, // -bool t5_can_get_checksum() { +bool t5_can_get_checksum() +{ uint32_t checksum = 0; if (!t5_boot_checksum_command(&checksum)) { printf("Error The ECU's checksum is wrong!\r\n"); @@ -622,7 +689,8 @@ // inputs: none // outputs: bool TRUE if all went OK. // -bool t5_can_bootloader_reset() { +bool t5_can_bootloader_reset() +{ printf("Exiting the bootloader and restarting the T5 ECU.\r\n"); if (!t5_boot_reset_command()) { printf("Error trying to reset the T5 ECU!\r\n"); @@ -670,7 +738,8 @@ // inputs: start T5 ecu start address // return: bool TRUE if all went OK. // -bool t5_can_get_start_and_chip_types(uint32_t* start) { +bool t5_can_get_start_and_chip_types(uint32_t* start) +{ *start = 0; uint8_t make = 0; uint8_t type = 0; @@ -689,23 +758,44 @@ case INTEL: printf("INTEL "); break; + case ATMEL: + printf("ATMEL "); + break; + case SST: + printf("SST "); + break; + case ST: + printf("ST "); + break; + case AMIC: + printf("AMIC "); + break; default: - printf("UNKNOWN FLASH chips - check pin65 has enough volts!\r\n"); + printf("\r\nUNKNOWN Manufacturer Id: %02x - Also check pin65 has enough volts!\r\n", make); } switch (type) { case AMD28F512: case INTEL28F512: printf("28F512 FLASH chips.\r\n"); break; + case ATMEL29C512: + printf("29C512 FLASH chips.\r\n"); + break; + case ATMEL29C010: + printf("29C010 FLASH chips.\r\n"); + break; case AMD28F010: case INTEL28F010: printf("28F010 FLASH chips.\r\n"); break; case AMD29F010: + case SST39SF010: +// case ST29F010: // Same as AMD29F010 + case AMICA29010L: printf("29F010 FLASH chips.\r\n"); break; default: - printf("UNKNOWN - check pin65 has enough volts!\r\n"); + printf("UNKNOWN Device Id: %02x - Also check pin65 has enough volts!\r\n", type); return FALSE; } return TRUE; @@ -739,7 +829,8 @@ // inputs: none // return: bool TRUE if all went OK. // -bool t5_can_erase_flash() { +bool t5_can_erase_flash() +{ printf("Erasing the FLASH chips.\r\n"); if (!t5_boot_erase_command()) { printf("Error The ECU's FLASH has not been erased!\r\n"); @@ -762,7 +853,8 @@ // return: bool TRUE if all went OK, FALSE if there was an error. // -bool t5_can_dump_flash(uint32_t start) { +bool t5_can_dump_flash(uint32_t start) +{ printf("Saving the original FLASH BIN file.\r\n"); FILE *fp = fopen("/local/original.bin", "w"); // Open "original.bin" on the local file system for writing if (!fp) { @@ -771,6 +863,7 @@ } uint32_t address = start + 5; // Mysterious reason for starting at 5 !!! char FLASHdata[6]; + printf(" 0.00 %% complete.\r"); while (address < TRIONICLASTADDR) { if (!t5_can_read_data(FLASHdata, address)) { fclose (fp); @@ -783,6 +876,7 @@ printf ("Error writing to the FLASH BIN file.\r\n"); return FALSE; } + printf("%6.2f\r", 100*(float)(address-start)/(float)(TRIONICLASTADDR - start) ); } // There are a few more bytes to get because because the bin file is not an exact multiple of 6 bytes! // the % (modulo) mathematics function tells us how many bytes there are still to get @@ -796,6 +890,7 @@ printf ("Error writing to the FLASH BIN file.\r\n"); return FALSE; } + printf("100.00 %% complete.\r\n"); fclose(fp); return TRUE; } @@ -804,7 +899,7 @@ // // t5_can_send_flash_bin_update // -// Sends a FLASH update file, modified.hex to the T5 ECU. +// Sends a FLASH update file, modified.bin to the T5 ECU. // The FLASH update file is stored on the local file system and must be in hex format. // // FLASHing a T5.5 ECU takes around 40 seconds. FLASHing T5.2 ECUs should take about half of this time @@ -814,11 +909,12 @@ // return: bool TRUE if all went OK, // FALSE if the FLASH update failed for some reason. // -bool t5_can_send_flash_bin_update(uint32_t start) { +bool t5_can_send_flash_bin_update(uint32_t start) +{ printf("Programming the FLASH chips.\r\n"); - FILE *fp = fopen("/local/modified.hex", "r"); // Open "modified.s19" on the local file system for reading + FILE *fp = fopen("/local/modified.bin", "r"); // Open "modified.bin" on the local file system for reading if (!fp) { - printf("Error: I could not find the BIN file MODIFIED.HEX\r\n"); + printf("Error: I could not find the BIN file MODIFIED.BIN\r\n"); return FALSE; } @@ -857,15 +953,15 @@ uint32_t curr_addr = start; // address to put FLASH data uint8_t byte_value = 0; + printf(" 0.00 %% complete.\r"); while (curr_addr <= TRIONICLASTADDR) { // send a bootloader address message if (!t5_can_send_boot_address(curr_addr, 0x80)) { fclose(fp); - printf("Error sending CAN message"); + printf("\r\nError sending Block Start message. Address: %08x\r\n",curr_addr); return FALSE; } - curr_addr += 0x80; // Construct and send the bootloader frames // NOTE the last frame sent may have less than 7 real data bytes but 7 bytes are always sent. In this case the unnecessary bytes // are repeated from the previous frame. This is OK because the T5 ECU knows how many bytes to expect (because the count of bytes @@ -873,7 +969,7 @@ for (uint8_t i=0; i<0x80; i++) { if (!fread(&byte_value,1,1,fp)) { fclose(fp); - printf("Error reading the BIN file MODIFIED.HEX"); + printf("\r\nError reading the BIN file MODIFIED.BIN\r\n"); return FALSE; } msg[1+(i%7)] = byte_value; @@ -881,11 +977,15 @@ if ((i%7 == 6) || (i == 0x80 - 1)) if (!t5_can_send_boot_frame(msg)) { fclose(fp); - printf("Error sending CAN message"); + printf("\r\nError sending a Block data message. Address: %08x, Index: %02x\r\n",curr_addr, i); return FALSE; } + } + curr_addr += 0x80; + printf("%6.2f\r", 100*(float)(curr_addr - start)/(float)(TRIONICLASTADDR - start) ); } + printf("100.00 %% complete.\r\n"); fclose(fp); return TRUE; } @@ -903,7 +1003,8 @@ // return: bool TRUE if all went OK, // FALSE if the FLASH update failed for some reason. // -bool t5_can_send_flash_s19_update(uint32_t start) { +bool t5_can_send_flash_s19_update(uint32_t start) +{ printf("Programming the FLASH chips.\r\n"); FILE *fp = fopen("/local/modified.s19", "r"); // Open "modified.s19" on the local file system for reading if (!fp) { @@ -1014,7 +1115,8 @@ // inputs: none // return: bool TRUE if all went OK, // -bool t5_can_get_last_address() { +bool t5_can_get_last_address() +{ uint32_t last_address = 0; uint16_t mode = 0; if (!t5_boot_c3_command(&last_address, &mode)) {
diff -r 682d96ff6d79 -r 1775b4b13232 t5can.h --- a/t5can.h Wed Sep 11 11:55:51 2013 +0000 +++ b/t5can.h Sat Apr 25 17:07:08 2015 +0000 @@ -33,6 +33,7 @@ bool t5_can_get_symbol_table(); bool t5_can_get_version(); bool t5_can_get_adaption_data(); +bool t5_can_send_boot_loader_S19(); bool t5_can_send_boot_loader(); bool t5_can_get_checksum(); bool t5_can_bootloader_reset();
diff -r 682d96ff6d79 -r 1775b4b13232 t7can.cpp --- a/t7can.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/t7can.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -282,7 +282,7 @@ printf("Trionic 7 Command Menu\r\n"); printf("======================\r\n"); printf("D - DUMP the T7 ECU FLASH to a file 'ORIGINAL.BIN'\r\n"); - printf("F - FLASH the update file 'MODIFIED.HEX' to the T7\r\n"); + printf("F - FLASH the update file 'MODIFIED.BIN' to the T7\r\n"); printf("\r\n"); printf("I - Try to open CAN I-Bus (47619 Bit/s)\r\n"); printf("P - Try to open CAN P-Bus (500 kBit/s)\r\n"); @@ -305,7 +305,7 @@ printf("Trionic 7 Command Menu\r\n"); printf("======================\r\n"); printf("D - DUMP the T7 ECU FLASH to a file 'ORIGINAL.BIN'\r\n"); - printf("F - FLASH the update file 'MODIFIED.HEX' to the T7\r\n"); + printf("F - FLASH the update file 'MODIFIED.BIN' to the T7\r\n"); printf("\r\n"); printf("I - Try to open CAN I-Bus (47619 Bit/s)\r\n"); printf("P - Try to open CAN P-Bus (500 kBit/s)\r\n");
diff -r 682d96ff6d79 -r 1775b4b13232 t7utils.cpp --- a/t7utils.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/t7utils.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -380,12 +380,12 @@ char data[8]; int i, k; - // fopen modified.hex here? + // fopen modified.bin here? // need lots of fcloses though printf("Checking the FLASH BIN file...\r\n"); - FILE *fp = fopen("/local/modified.hex", "r"); // Open "modified.hex" on the local file system for reading + FILE *fp = fopen("/local/modified.bin", "r"); // Open "modified.bin" on the local file system for reading if (!fp) { - printf("Error: I could not find the BIN file MODIFIED.HEX\r\n");; + printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");; return TERM_ERR; } // obtain file size - it should match the size of the FLASH chips: @@ -462,7 +462,7 @@ //data[k] = *(bin + bin_count++); if (!fread(&data[k],1,1,fp)) { fclose(fp); - printf("Error reading the BIN file MODIFIED.HEX\r\n"); + printf("Error reading the BIN file MODIFIED.BIN\r\n"); return FALSE; } // /* DEBUG info... @@ -484,7 +484,7 @@ //data[k] = *(bin + bin_count++); if (!fread(&data[k],1,1,fp)) { fclose(fp); - printf("Error reading the BIN file MODIFIED.HEX\r\n"); + printf("Error reading the BIN file MODIFIED.BIN\r\n"); return FALSE; } // /* DEBUG info... @@ -592,12 +592,12 @@ char data[8]; int i, k; - // fopen modified.hex here? + // fopen modified.bin here? // need lots of fcloses though printf("Checking the FLASH BIN file...\r\n"); - FILE *fp = fopen("/local/modified.hex", "r"); // Open "modified.hex" on the local file system for reading + FILE *fp = fopen("/local/modified.bin", "r"); // Open "modified.bin" on the local file system for reading if (!fp) { - printf("Error: I could not find the BIN file MODIFIED.HEX\r\n");; + printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");; return TERM_ERR; } // obtain file size - it should match the size of the FLASH chips: @@ -669,7 +669,7 @@ for ( k = 4; k < 8; k++ ) if (!fread(&data[k],1,1,fp)) { fclose(fp); - printf("Error reading the BIN file MODIFIED.HEX\r\n"); + printf("Error reading the BIN file MODIFIED.BIN\r\n"); return FALSE; } if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) { @@ -740,7 +740,7 @@ for ( k = 4; k < 8; k++ ) if (!fread(&data[k],1,1,fp)) { fclose(fp); - printf("Error reading the BIN file MODIFIED.HEX\r\n"); + printf("Error reading the BIN file MODIFIED.BIN\r\n"); return FALSE; } if (!can_send_timeout (T7SEC_ID, data, 8, T7MESSAGETIMEOUT)) {
diff -r 682d96ff6d79 -r 1775b4b13232 t8bootloaders.h --- a/t8bootloaders.h Wed Sep 11 11:55:51 2013 +0000 +++ b/t8bootloaders.h Sat Apr 25 17:07:08 2015 +0000 @@ -1,8 +1,17 @@ #ifndef __T8BOOTLOADERS_H__ #define __T8BOOTLOADERS_H__ - -#define T8BootloaderProg {\ +//0x77ED eor 0x4739 = 0x30D4 12,500 4.5454 ms with 5.5 MHz Clock +// 0x11,0x77,0xED,0x39,0x32,0x66,0x11, +//0x6029 eor 0x4739 = 0x2710 10,000 4.5454 ms with 5.5 MHz Clock +// 0x11,0x60,0x29,0x39,0x32,0x66,0x11, +//0x5A75 eor 0x4739 = 0x1D4C 7,500 4.5454 ms with 5.5 MHz Clock +// 0x11,0x5A,0x75,0x39,0x32,0x66,0x11, +//0x54B1 eor 0x4739 = 0x1388 5,000 4.5454 ms with 5.5 MHz Clock +// 0x11,0x54,0xB1,0x39,0x32,0x66,0x11, +//0x4EFD eor 0x4739 = 0x09C4 2,500 0.909 ms with 5.5 MHz Clock +// 0x11,0x4E,0xFD,0x39,0x32,0x66,0x11, +#define T8_BOOTLOADER_PROG {\ 0x77,0xD1,0x77,0x7D,0x1B,0x09,0x77,\ 0xD1,0x77,0x7D,0x1B,0x7D,0x77,0x1D,\ 0x39,0x1C,0x05,0x00,0x39,0x78,0x0B,\ @@ -1990,7 +1999,7 @@ 0x39,0x97,0x8D,0x6D,0x05,0x51,0x39,\ 0x32,0x75,0x45,0x47,0xC1,0x39,0x3A,\ 0x77,0x45,0x47,0x38,0x39,0x3A,0x46,\ - 0x11,0x77,0xED,0x39,0x32,0x66,0x11,\ + 0x11,0x60,0x29,0x39,0x32,0x66,0x11,\ 0x47,0x79,0x39,0x3B,0x77,0x05,0x46,\ 0x29,0x39,0x38,0x59,0x51,0x47,0x29,\ 0x65,0x38,0x39,0x16,0x3F,0x38,0x3B,\ @@ -2385,7 +2394,17 @@ 0x6D,0x43,0x4D,0x00,0x36,0x43,0x36,\ 0x44,0x54,0x45,0x43,0x00,0x49,0x00} //16384 -#define T8Bootloader {\ +//0x77ED eor 0x4739 = 0x30D4 12,500 4.5454 ms with 5.5 MHz Clock +// 0x11,0x77,0xED,0x39,0x32,0x66,0x11, +//0x6029 eor 0x4739 = 0x2710 10,000 4.5454 ms with 5.5 MHz Clock +// 0x11,0x60,0x29,0x39,0x32,0x66,0x11, +//0x5A75 eor 0x4739 = 0x1D4C 7,500 4.5454 ms with 5.5 MHz Clock +// 0x11,0x5A,0x75,0x39,0x32,0x66,0x11, +//0x54B1 eor 0x4739 = 0x1388 5,000 4.5454 ms with 5.5 MHz Clock +// 0x11,0x54,0xB1,0x39,0x32,0x66,0x11, +//0x4EFD eor 0x4739 = 0x09C4 2,500 0.909 ms with 5.5 MHz Clock +// 0x11,0x4E,0xFD,0x39,0x32,0x66,0x11, +#define T8_BOOTLOADER_DUMP {\ 0x77,0xD1,0x77,0x7D,0x1B,0x09,0x77,\ 0xD1,0x77,0x7D,0x1B,0x7D,0x77,0x1D,\ 0x39,0x1C,0x05,0x00,0x39,0x78,0x0B,\ @@ -4373,7 +4392,7 @@ 0x39,0x97,0x8D,0x6D,0x05,0x51,0x39,\ 0x32,0x75,0x45,0x47,0xC1,0x39,0x3A,\ 0x77,0x45,0x47,0x38,0x39,0x3A,0x46,\ - 0x11,0x77,0xED,0x39,0x32,0x66,0x11,\ + 0x11,0x60,0x29,0x39,0x32,0x66,0x11,\ 0x47,0x79,0x39,0x3B,0x77,0x05,0x46,\ 0x29,0x39,0x38,0x59,0x51,0x47,0x29,\ 0x65,0x38,0x39,0x16,0x3F,0x38,0x3B,\
diff -r 682d96ff6d79 -r 1775b4b13232 t8can.cpp --- a/t8can.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/t8can.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -64,6 +64,15 @@ } } + can_reset_filters(); + can_add_filter(2, 0x645); //645h - CIM + can_add_filter(2, 0x7E0); //7E0h - + can_add_filter(2, 0x7E8); //7E8h - + can_add_filter(2, 0x311); //311h - + can_add_filter(2, 0x5E8); //5E8h - + //can_add_filter(2, 0x101); //101h - + + // main loop *cmd_buffer = '\0'; char ret; @@ -139,7 +148,7 @@ // ? TERM_OK : TERM_ERR; case 'a' : case 'A' : - if (t8_authenticate(0x01)) { + if (t8_authenticate(T8REQID, T8RESPID, 0x01)) { printf("Security Key Accepted\r\n"); return TERM_OK; } else { @@ -149,45 +158,21 @@ // return t7_authenticate() // ? TERM_OK : TERM_ERR; -// Erase the FLASH chips - case 'e': - case 'E': - return t8_erase() - ? TERM_OK : TERM_ERR; // DUMP the T8 ECU BIN file stored in the FLASH chips case 'D': - if (!t8_authenticate(0x00)) { - if (!t8_initialise()) { - printf("Trionic 7 Connection Failed\r\n"); - return TERM_ERR; - } - if (!t8_authenticate(0x00)) { - printf("Security Key Failed\r\n"); - return TERM_ERR; - } - } case 'd': return t8_dump() ? TERM_OK : TERM_ERR; // Send a FLASH update file to the T8 ECU case 'F': - if (!t8_authenticate(0x00)) { - if (!t8_initialise()) { - printf("Trionic 7 Connection Failed\r\n"); - return TERM_ERR; - } - if (!t8_authenticate(0x00)) { - printf("Security Key Failed\r\n"); - return TERM_ERR; - } - } - if (!t8_erase()) { - printf("Could not Erase FLASH!\r\n"); - return TERM_ERR; - } case 'f': return t8_flash() ? TERM_OK : TERM_ERR; +// Erase the FLASH chips + case 'r': + case 'R': + return t8_recover() + ? TERM_OK : TERM_ERR; // Try to connect to CAN I-BUS case 'I' : printf("Trying to open CAN I-Bus (47619 Bit/s)...\r\n"); @@ -255,7 +240,8 @@ printf("Trionic 8 Command Menu\r\n"); printf("======================\r\n"); printf("D - DUMP the T8 ECU FLASH to a file 'ORIGINAL.BIN'\r\n"); - printf("F - FLASH the update file 'MODIFIED.HEX' to the T8\r\n"); + printf("F - FLASH the update file 'MODIFIED.BIN' to the T8\r\n"); + printf("R - Recover your T8 ECU FLASH with 'MODIFIED.BIN' file\r\n"); printf("\r\n"); printf("I - Try to open CAN I-Bus (47619 Bit/s)\r\n"); printf("P - Try to open CAN P-Bus (500 kBit/s)\r\n"); @@ -279,7 +265,8 @@ printf("Trionic 8 Command Menu\r\n"); printf("======================\r\n"); printf("D - DUMP the T8 ECU FLASH to a file 'ORIGINAL.BIN'\r\n"); - printf("F - FLASH the update file 'MODIFIED.HEX' to the T8\r\n"); + printf("F - FLASH the update file 'MODIFIED.BIN' to the T8\r\n"); + printf("R - Recover your T8 ECU FLASH with 'MODIFIED.BIN' file\r\n"); printf("\r\n"); printf("I - Try to open CAN I-Bus (47619 Bit/s)\r\n"); printf("P - Try to open CAN P-Bus (500 kBit/s)\r\n");
diff -r 682d96ff6d79 -r 1775b4b13232 t8utils.cpp --- a/t8utils.cpp Wed Sep 11 11:55:51 2013 +0000 +++ b/t8utils.cpp Sat Apr 25 17:07:08 2015 +0000 @@ -38,7 +38,7 @@ bool t8_show_VIN() { - uint16_t i; + uint32_t i; char T8TxFlo[] = T8FLOCTL; char T8TxMsg[] = T8REQVIN; char T8RxMsg[8]; @@ -87,7 +87,7 @@ char T8RxMsg[8]; char k = 0; -// GMLANTesterPresentT8(); +// GMLANTesterPresent(T8REQID, T8RESPID); // wait_ms(2000); // // printf("Requesting Security Access\r\n"); @@ -97,10 +97,10 @@ // } // printf("Security Access Granted\r\n"); // -// GMLANTesterPresentT8(); +// GMLANTesterPresent(T8REQID, T8RESPID); // wait_ms(2000); // -// GMLANTesterPresentT8(); +// GMLANTesterPresent(T8REQID, T8RESPID); // wait_ms(2000); // if (!can_send_timeout (T8TSTRID, SetVin10, 8, T8MESSAGETIMEOUT)) { @@ -132,7 +132,7 @@ for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] ); printf("\r\n"); return TRUE; -// GMLANTesterPresentT8(); +// GMLANTesterPresent(T8REQID, T8RESPID); // wait_ms(2000); // } @@ -147,13 +147,25 @@ // return: bool TRUE if there was a message, FALSE if no message. // -bool t8_authenticate(char level) +bool t8_authenticate(uint32_t ReqID, uint32_t RespID, char level) { - uint16_t seed, key; - if (!GMLANSecurityAccessRequest(level, seed)) { + uint16_t i, seed, key; +// if (!GMLANSecurityAccessRequest(ReqID, RespID, level, seed)) { +// printf("Unable to request SEED value for security access\r\n"); +// return FALSE; +// } + + for (i=0; i < 20; i++) { + if (GMLANSecurityAccessRequest(ReqID, RespID, level, seed)) + break; + wait(1); + GMLANTesterPresent(ReqID, RespID); + } + if (i == 20) { printf("Unable to request SEED value for security access\r\n"); return FALSE; } + if ( seed == 0x0000 ) { printf("T8 ECU is already unlocked\r\n"); return TRUE; @@ -175,16 +187,17 @@ key = (key >> 8) | (key << 8); key -= 0x3FC7; */ - if (!GMLANSecurityAccessSendKey(level, key)) { + wait_ms(1); + if (!GMLANSecurityAccessSendKey(ReqID, RespID, level, key)) { printf("Unable to send KEY value for security access\r\n"); return FALSE; } printf("Key Accepted\r\n"); + wait_ms(500); // was 5 return TRUE; } - // // t8_dump // @@ -197,7 +210,7 @@ bool t8_dump() { - uint16_t i = 0, k = 0; + uint32_t i = 0, k = 0; char T8TxMsg[8]; char T8RxMsg[8]; @@ -206,28 +219,19 @@ printf("Creating FLASH dump file...\r\n"); // - GMLANTesterPresentT8(); -// - if (!GMLANprogrammingSetupProcess()) + if (!GMLANprogrammingSetupProcess(T8REQID, T8RESPID)) return FALSE; // - wait_ms(500); printf("Requesting Security Access\r\n"); - if (!t8_authenticate(0x01)) { + if (!t8_authenticate(T8REQID, T8RESPID, 0x01)) { printf("Unable to get Security Access\r\n"); return FALSE; } printf("Security Access Granted\r\n"); - wait_ms(500); - GMLANTesterPresentT8(); // - char BootLoader[] = T8Bootloader; - if(!GMLANprogrammingUtilityFileProcess(BootLoader)) + if(!GMLANprogrammingUtilityFileProcess(T8REQID, T8RESPID, T8BootloaderRead)) return FALSE; // - uint32_t StartAddress = 0x0; - uint16_t txpnt = 0; - char iFrameNumber = 0x21; // printf("Downloading FLASH BIN file...\r\n"); printf("Creating FLASH dump file...\r\n"); @@ -238,7 +242,34 @@ } printf(" 0.00 %% complete.\r"); TesterPresent.start(); - while (StartAddress < 0x100000) { // 0x100000 + +// It is possible to save some time by only reading the program code and CAL data +// This is just a rough calculation, and slight overestimate of the number of blocks of data needed to send the BIN file + T8TxMsg[0] = 0x06; + T8TxMsg[1] = 0x21; + T8TxMsg[2] = 0x80; // Blocksize + T8TxMsg[3] = 0x00; // This address (0x020140) points to the Header at the end of the BIN + T8TxMsg[4] = 0x02; + T8TxMsg[5] = 0x01; + T8TxMsg[6] = 0x40; + T8TxMsg[7] = 0xaa; + if (!can_send_timeout (T8TSTRID, T8TxMsg, 7, T8MESSAGETIMEOUT)) { + printf("Unable to download FLASH\r\n"); + return FALSE; + } + if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT)) + return FALSE; + uint32_t EndAddress = (T8RxMsg[5] << 16) | (T8RxMsg[6] << 8) | T8RxMsg[7]; + EndAddress += 0x200; // Add some bytes for the Footer itself and to account for division rounded down later + char T8TxFlo[] = T8FLOCTL; + can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT); + for (i = 0; i < 0x12; i++) { + if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT)) + return FALSE; + } + printf("Reading your BIN file adjusted for footer = 0x%06X Bytes\r\n", EndAddress ); + + for ( uint32_t StartAddress = 0x0; StartAddress < EndAddress; StartAddress +=0x80 ) { // 0x100000 T8TxMsg[0] = 0x06; T8TxMsg[1] = 0x21; T8TxMsg[2] = 0x80; // Blocksize @@ -258,26 +289,22 @@ return FALSE; #ifdef DEBUG printf("first %#.3f\r\n",timer.read()); - for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] ); - printf("\r\n"); #endif - txpnt = 0; + uint32_t txpnt = 0; for (k = 4; k < 8; k++ ) file_buffer[txpnt++] = T8RxMsg[k]; uint8_t DataFrames = 0x12; - iFrameNumber = 0x21; + char iFrameNumber = 0x21; char T8TxFlo[] = T8FLOCTL; + can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT); #ifdef DEBUG printf("flowCtrl %#.3f\r\n",timer.read()); #endif - can_send_timeout (T8TSTRID, T8TxFlo, 8, T8MESSAGETIMEOUT); for (i = 0; i < DataFrames; i++) { if (!can_wait_timeout(T8ECU_ID, T8RxMsg, 8, T8MESSAGETIMEOUT)) return FALSE; #ifdef DEBUG printf("Consec %#.3f\r\n",timer.read()); - for (k = 0; k < 8; k++ ) printf("0x%02X ", T8RxMsg[k] ); - printf("\r\n"); #endif iFrameNumber++; for (k = 1; k < 8; k++ ) file_buffer[txpnt++] = T8RxMsg[k]; @@ -288,12 +315,22 @@ printf ("Error writing to the FLASH BIN file.\r\n"); return TERM_ERR; } - StartAddress +=0x80; - printf("%6.2f\r", (100.0*(float)StartAddress)/(float)(0x100000) ); + printf("%6.2f\r", (100.0*(float)StartAddress)/(float)(EndAddress) ); if (TesterPresent.read_ms() > 2000) { - GMLANTesterPresentT8(); + GMLANTesterPresent(T8REQID, T8RESPID); TesterPresent.reset(); - ACTIVITYLEDON; + } + } + + for (uint32_t i = 0; i < 0x80; i++) + file_buffer[i] = 0xFF; + while ( ftell(fp) < 0x100000 ) { +// for ( uint32_t StartAddress = EndAddress; StartAddress < 0x100000; StartAddress +=0x80 ) { + fwrite((file_buffer), 1, 0x80, fp); + if (ferror (fp)) { + fclose (fp); + printf ("Error writing to the FLASH BIN file.\r\n"); + return TERM_ERR; } } @@ -304,69 +341,44 @@ return TRUE; } -bool t8_erase() -{ - printf("Erasing T8 ECU FLASH...\r\n"); - printf("SUCCESS: The FLASH has been erased.\r\n"); - return TRUE; -} - -bool t8_flash_raw() -{ - timer.reset(); - timer.start(); - printf("Checking the FLASH BIN file...\r\n"); - timer.stop(); - printf("SUCCESS! Programming the FLASH took %#.1f seconds.\r\n",timer.read()); - return TRUE; -} - bool t8_flash() { - uint16_t i = 0, j = 0, k = 0; + uint32_t i = 0, j = 0, k = 0; timer.reset(); timer.start(); printf("FLASHing T8 BIN file...\r\n"); // - GMLANTesterPresentT8(); -// - if (!GMLANprogrammingSetupProcess()) + if (!GMLANprogrammingSetupProcess(T8REQID, T8RESPID)) return FALSE; // - wait_ms(500); printf("Requesting Security Access\r\n"); - if (!t8_authenticate(0x01)) { + if (!t8_authenticate(T8REQID, T8RESPID, 0x01)) { printf("Unable to get Security Access\r\n"); return FALSE; } printf("Security Access Granted\r\n"); - wait_ms(500); - GMLANTesterPresentT8(); // - char BootLoader[] = T8BootloaderProg; - if(!GMLANprogrammingUtilityFileProcess(BootLoader)) +// const uint8_t BootLoader[] = T8BootloaderProg; +// if(!GMLANprogrammingUtilityFileProcess(T8REQID, T8RESPID, BootLoader)) + if(!GMLANprogrammingUtilityFileProcess(T8REQID, T8RESPID, T8BootLoaderWrite)) return FALSE; // - - // All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance) -// bool GMLANprogrammingUtilityFileProcess(char UtilityFile[]) { -// uint16_t i = 0, j = 0, k = 0; uint32_t StartAddress = 0x020000; - uint16_t txpnt = 0; + uint32_t txpnt = 0; char iFrameNumber = 0x21; char GMLANMsg[8]; char data2Send[0xE0]; // - // fopen modified.hex here, check it is OK and work out how much data I need to send + // fopen modified.bin here, check it is OK and work out how much data I need to send // need lots of fcloses though printf("Checking the FLASH BIN file...\r\n"); - FILE *fp = fopen("/local/modified.hex", "r"); // Open "modified.hex" on the local file system for reading + FILE *fp = fopen("/local/modified.bin", "r"); // Open "modified.bin" on the local file system for reading if (!fp) { - printf("Error: I could not find the BIN file MODIFIED.HEX\r\n");; + printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");; return TERM_ERR; } // obtain file size - it should match the size of the FLASH chips: @@ -376,7 +388,10 @@ // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU uint32_t stack_long = 0; - if (!fread(&stack_long,4,1,fp)) return TERM_ERR; + if (!fread(&stack_long,4,1,fp)) { + fclose(fp); + return TERM_ERR; + } stack_long = (stack_long >> 24) | ((stack_long << 8) & 0x00FF0000) | ((stack_long >> 8) & 0x0000FF00) | (stack_long << 24); // if (file_size != T8FLASHSIZE || stack_long != T8POINTER) { @@ -389,7 +404,10 @@ // This is just a rough calculation, and slight overestimate of the number of blocks of data needed to send the BIN file uint32_t blocks2Send; fseek(fp,0x020140,SEEK_SET); - if (!fread(&blocks2Send,4,1,fp)) return TERM_ERR; + if (!fread(&blocks2Send,4,1,fp)) { + fclose(fp); + return TERM_ERR; + } blocks2Send = (blocks2Send >> 24) | ((blocks2Send << 8) & 0x00FF0000) | ((blocks2Send >> 8) & 0x0000FF00) | (blocks2Send << 24); printf("Start address of BIN file's Footer area = 0x%06X\r\n", blocks2Send ); blocks2Send += 0x200; // Add some bytes for the Footer itself and to account for division rounded down later @@ -401,45 +419,31 @@ fseek (fp , 0x020000 , SEEK_SET); // Erase the FLASH printf("Waiting for FLASH to be Erased\r\n"); - if (!GMLANRequestDownload(GMLANRequestDownloadModeEncrypted)) { + if (!GMLANRequestDownload(T8REQID, T8RESPID, GMLANRequestDownloadModeEncrypted)) { + fclose(fp); printf("Unable to erase the FLASH chip!\r\n"); return FALSE; } // Now send the BIN file + GMLANTesterPresent(T8REQID, T8RESPID); TesterPresent.start(); printf("Sending FLASH BIN file\r\n"); printf(" 0.00 %% complete.\r"); for (i=0; i<blocks2Send; i++) { // get a block of 0xE0 bytes in an array called data2Send - for ( j = 0; j < 0xE0; j++ ) { - //data[k] = *(bin + bin_count++); - if (!fread(&data2Send[j],1,1,fp)) { - fclose(fp); - printf("Error reading the BIN file MODIFIED.HEX\r\n"); - return FALSE; - } - // encrypt data2Send array by XORing with 6 different in a ring (modulo function) - switch ( ((0xE0*i)+j) %6) { - case 1: - data2Send[j] ^= 0x68; - break; - case 2: - data2Send[j] ^= 0x77; - break; - case 3: - data2Send[j] ^= 0x6D; - break; - case 4: - data2Send[j] ^= 0x47; - break; - default: // remainder 0 and 5 both XOR with 0x39 - data2Send[j] ^= 0x39; - } + if (!fread(data2Send,0xE0,1,fp)) { + fclose(fp); + printf("\r\nError reading the BIN file MODIFIED.BIN\r\n"); + return FALSE; } + // encrypt data2Send array by XORing with 6 different values in a ring (modulo function) + char key[6] = { 0x39, 0x68, 0x77, 0x6D, 0x47, 0x39 }; + for ( j = 0; j < 0xE0; j++ ) + data2Send[j] ^= key[(((0xE0*i)+j) % 6)]; // Send the block of data - if (!GMLANDataTransferFirstFrame(0xE6, GMLANDOWNLOAD, StartAddress)) { + if (!GMLANDataTransferFirstFrame(T8REQID, T8RESPID, 0xE6, GMLANDOWNLOAD, StartAddress)) { fclose(fp); - printf("Unable to start BIN File Upload\r\n"); + printf("\r\nUnable to start BIN File Upload\r\n"); return FALSE; } // Send 0x20 messages of 0x07 bytes each (0x20 * 0x07 = 0xE0) @@ -449,50 +453,21 @@ GMLANMsg[0] = iFrameNumber; for (k=1; k<8; k++) GMLANMsg[k] = data2Send[txpnt++]; -#ifdef DEBUG - for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if (!can_send_timeout(T8RequestId, GMLANMsg, 8, GMLANPTCT)) { + if (!can_send_timeout(T8REQID, GMLANMsg, 8, GMLANPTCT)) { fclose(fp); - printf("Unable to send BIN File\r\n"); + printf("\r\nUnable to send BIN File\r\n"); return FALSE; } ++iFrameNumber &= 0x2F; -// wait_ms(1); - wait_us(250); - } - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCT)) { - fclose(fp); - printf("I did not receive a block acknowledge message\r\n"); - return FALSE; + 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??? ) } - while (GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 && GMLANMsg[3] == 0x78) { - printf("I'm waiting for a Block to be programmed into FLASH\r\n"); - if (!can_wait_timeout(T8ResponseId, GMLANMsg, 8, GMLANPTCTENHANCED)) { - printf("I did not receive a block acknowledge message after enhanced timeout\r\n"); - fclose(fp); - return FALSE; - } - } -#ifdef DEBUG - for (k = 0; k < 8; k++ ) printf("0x%02X ", GMLANMsg[k] ); - printf("\r\n"); -#endif - if ( GMLANMsg[0] == 0x03 && GMLANMsg[1] == 0x7F && GMLANMsg[2] == 0x36 ) { - GMLANShowReturnCode(GMLANMsg[3]); - fclose(fp); - return FALSE; - } - if (GMLANMsg[0] != 0x01 && GMLANMsg[1] != 0x76) { - printf("EXITING due to an unexpected CAN message"); + if (!GMLANDataTransferBlockAcknowledge(T8RESPID)) { fclose(fp); return FALSE; } if (TesterPresent.read_ms() > 2000) { - GMLANTesterPresentT8(); + GMLANTesterPresent(T8REQID, T8RESPID); TesterPresent.reset(); - ACTIVITYLEDON; } StartAddress += 0xE0; printf("%6.2f\r", (100.0*(float)i)/(float)(blocks2Send) ); @@ -500,14 +475,158 @@ // FLASHing complete printf("%6.2f\r\n", (float)100 ); // End programming session and return to normal mode - if (!GMLANReturnToNormalMode()) { + if (!GMLANReturnToNormalMode(T8REQID, T8RESPID)) { fclose(fp); printf("UH-OH! T8 ECU did not Return To Normal Mode!!\r\n"); return FALSE; } - wait_ms(1000); timer.stop(); printf("SUCCESS! FLASHing the BIN file took %#.1f seconds.\r\n",timer.read()); fclose(fp); return TRUE; } + +bool t8_recover() +{ + uint32_t i = 0, j = 0, k = 0; + + timer.reset(); + timer.start(); + printf("Recovering your T8 ECU ...\r\n"); +// + if (!GMLANprogrammingSetupProcess(T8USDTREQID, T8UUDTRESPID)) + return FALSE; +// + printf("Requesting Security Access\r\n"); + if (!t8_authenticate(T8USDTREQID, T8UUDTRESPID, 0x01)) { + printf("Unable to get Security Access\r\n"); + return FALSE; + } + printf("Security Access Granted\r\n"); +// +// const uint8_t BootLoader[] = T8BootloaderProg; +// if(!GMLANprogrammingUtilityFileProcess(T8USDTREQID, T8UUDTRESPID, BootLoader)) + if(!GMLANprogrammingUtilityFileProcess(T8USDTREQID, T8UUDTRESPID, T8BootLoaderWrite)) + return FALSE; +// + + +// All steps needed to transfer and start a bootloader ('Utility File' in GMLAN parlance) + uint32_t StartAddress = 0x020000; + uint32_t txpnt = 0; + char iFrameNumber = 0x21; + char GMLANMsg[8]; + char data2Send[0xE0]; +// + // fopen modified.bin here, check it is OK and work out how much data I need to send + // need lots of fcloses though + printf("Checking the FLASH BIN file...\r\n"); + FILE *fp = fopen("/local/modified.bin", "r"); // Open "modified.bin" on the local file system for reading + if (!fp) { + printf("Error: I could not find the BIN file MODIFIED.BIN\r\n");; + return TERM_ERR; + } + // obtain file size - it should match the size of the FLASH chips: + fseek (fp , 0 , SEEK_END); + uint32_t file_size = ftell (fp); + rewind (fp); + + // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU + uint32_t stack_long = 0; + if (!fread(&stack_long,4,1,fp)) { + fclose(fp); + return TERM_ERR; + } + stack_long = (stack_long >> 24) | ((stack_long << 8) & 0x00FF0000) | ((stack_long >> 8) & 0x0000FF00) | (stack_long << 24); +// + if (file_size != T8FLASHSIZE || stack_long != T8POINTER) { + fclose(fp); + printf("The BIN file does not appear to be for a T8 ECU :-(\r\n"); + printf("BIN file size: %#010x, FLASH chip size: %#010x, Pointer: %#010x.\r\n", file_size, T7FLASHSIZE, stack_long); + return TERM_ERR; + } +// It is possible to save some time by only sending the program code and CAL data +// This is just a rough calculation, and slight overestimate of the number of blocks of data needed to send the BIN file + uint32_t blocks2Send; + fseek(fp,0x020140,SEEK_SET); + if (!fread(&blocks2Send,4,1,fp)) { + fclose(fp); + return TERM_ERR; + } + blocks2Send = (blocks2Send >> 24) | ((blocks2Send << 8) & 0x00FF0000) | ((blocks2Send >> 8) & 0x0000FF00) | (blocks2Send << 24); + printf("Start address of BIN file's Footer area = 0x%06X\r\n", blocks2Send ); + blocks2Send += 0x200; // Add some bytes for the Footer itself and to account for division rounded down later + blocks2Send -= 0x020000; // Remove 0x020000 because we don't send the bootblock and adaptation blocks + printf("Amount of data to send BIN file adjusted for footer = 0x%06X Bytes\r\n", blocks2Send ); + blocks2Send /= 0xE0; + printf("Number of Blocks of 0xE0 Bytes needed to send BIN file = 0x%04X\r\n", blocks2Send ); +// Move BIN file pointer to start of data + fseek (fp , 0x020000 , SEEK_SET); +// Erase the FLASH + printf("Waiting for FLASH to be Erased\r\n"); + if (!GMLANRequestDownload(T8REQID, T8RESPID, GMLANRequestDownloadModeEncrypted)) { + fclose(fp); + printf("Unable to erase the FLASH chip!\r\n"); + return FALSE; + } +// Now send the BIN file + GMLANTesterPresent(T8REQID, T8RESPID); + TesterPresent.start(); + printf("Sending FLASH BIN file\r\n"); + printf(" 0.00 %% complete.\r"); + for (i=0; i<blocks2Send; i++) { + // get a block of 0xE0 bytes in an array called data2Send + if (!fread(data2Send,0xE0,1,fp)) { + fclose(fp); + printf("\r\nError reading the BIN file MODIFIED.BIN\r\n"); + return FALSE; + } + // encrypt data2Send array by XORing with 6 different values in a ring (modulo function) + char key[6] = { 0x39, 0x68, 0x77, 0x6D, 0x47, 0x39 }; + for ( j = 0; j < 0xE0; j++ ) + data2Send[j] ^= key[(((0xE0*i)+j) % 6)]; + // Send the block of data + if (!GMLANDataTransferFirstFrame(T8REQID, T8RESPID, 0xE6, GMLANDOWNLOAD, StartAddress)) { + fclose(fp); + printf("\r\nUnable to start BIN File Upload\r\n"); + return FALSE; + } + // Send 0x20 messages of 0x07 bytes each (0x20 * 0x07 = 0xE0) + txpnt = 0; + iFrameNumber = 0x21; + for (j=0; j < 0x20; j++) { + GMLANMsg[0] = iFrameNumber; + for (k=1; k<8; k++) + GMLANMsg[k] = data2Send[txpnt++]; + if (!can_send_timeout(T8REQID, GMLANMsg, 8, GMLANPTCT)) { + fclose(fp); + printf("\r\nUnable to send BIN File\r\n"); + return FALSE; + } + ++iFrameNumber &= 0x2F; + wait_us(1000); // was 250 use 1000 or wait_ms(1) to be ultrasafe + } + if (!GMLANDataTransferBlockAcknowledge(T8RESPID)) { + fclose(fp); + return FALSE; + } + if (TesterPresent.read_ms() > 2000) { + GMLANTesterPresent(T8REQID, T8RESPID); + TesterPresent.reset(); + } + StartAddress += 0xE0; + printf("%6.2f\r", (100.0*(float)i)/(float)(blocks2Send) ); + } +// FLASHing complete + printf("%6.2f\r\n", (float)100 ); +// End programming session and return to normal mode + if (!GMLANReturnToNormalMode(T8REQID, T8RESPID)) { + fclose(fp); + printf("UH-OH! T8 ECU did not Return To Normal Mode!!\r\n"); + return FALSE; + } + timer.stop(); + fclose(fp); + printf("SUCCESS: Your T8 ECU has been recovered.\r\n"); + return TRUE; +}
diff -r 682d96ff6d79 -r 1775b4b13232 t8utils.h --- a/t8utils.h Wed Sep 11 11:55:51 2013 +0000 +++ b/t8utils.h Sat Apr 25 17:07:08 2015 +0000 @@ -11,7 +11,7 @@ #include "common.h" #include "canutils.h" -#include "t8bootloaders.h" +//#include "t8bootloaders.h" #include "gmlan.h" @@ -45,11 +45,10 @@ extern bool t8_initialise(); extern bool t8_show_VIN(); extern bool t8_write_VIN(); -extern bool t8_authenticate(char level); +extern bool t8_authenticate(uint32_t ReqID, uint32_t RespID, char level); extern bool t8_dump(); extern bool t8_flash(); -extern bool t8_flash_raw(); -extern bool t8_erase(); +extern bool t8_recover(); #endif \ No newline at end of file