Sophie Dexter
/
Just4Trionic
Just4Trionic - CAN and BDM FLASH programmer for Saab cars
Diff: bdmcpu32.cpp
- Revision:
- 5:1775b4b13232
- Parent:
- 4:682d96ff6d79
--- 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);