Sophie Dexter
/
Just4Trionic
Just4Trionic - CAN and BDM FLASH programmer for Saab cars
Diff: bdmcpu32.cpp
- Revision:
- 2:bf3a2b29259a
- Parent:
- 1:d5452e398b76
- Child:
- 4:682d96ff6d79
--- a/bdmcpu32.cpp Tue Sep 14 21:02:04 2010 +0000 +++ b/bdmcpu32.cpp Tue Dec 14 21:50:35 2010 +0000 @@ -73,6 +73,7 @@ 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_fast(uint16_t value, uint8_t num_bits); void bdm_clear(); //----------------------------------------------------------------------------- @@ -613,7 +614,7 @@ if (!bdm_command(BDM_READ + BDM_BYTESIZE)) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } return TERM_OK; @@ -636,7 +637,7 @@ if (bdm_response > BDM_CMDCMPLTE) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } return TERM_OK; @@ -659,7 +660,7 @@ if (bdm_response > BDM_CMDCMPLTE) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } return TERM_OK; @@ -675,12 +676,12 @@ uint8_t memwrite_byte_cmd(const uint32_t* addr) { if (!IN_BDM) return TERM_ERR; - + // write command code if (!bdm_command(BDM_WRITE + BDM_BYTESIZE)) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } return TERM_OK; @@ -703,7 +704,7 @@ if (bdm_response > BDM_CMDCMPLTE) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } return TERM_OK; @@ -726,7 +727,7 @@ if (bdm_response > BDM_CMDCMPLTE) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } return TERM_OK; @@ -747,7 +748,7 @@ if (!IN_BDM) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } // receive the response byte return (bdm_get ((uint32_t*)result, BDM_BYTESIZE, BDM_READ + BDM_BYTESIZE)) ? TERM_OK : TERM_ERR; @@ -768,7 +769,7 @@ if (!IN_BDM) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } // receive the response byte return (bdm_get((uint32_t*)result, BDM_BYTESIZE, BDM_WRITE + BDM_BYTESIZE)) ? TERM_OK : TERM_ERR; @@ -789,7 +790,7 @@ if (!IN_BDM) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } // receive the response byte return (bdm_get((uint32_t*)result, BDM_BYTESIZE, BDM_NOP)) ? TERM_OK : TERM_ERR; @@ -810,7 +811,7 @@ if (!IN_BDM) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } // write the value if (!bdm_put((uint32_t*)&value, BDM_BYTESIZE)) return TERM_ERR; @@ -833,7 +834,7 @@ if (!IN_BDM) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } // write the value if (!bdm_put((uint32_t*)&value, BDM_BYTESIZE)) return TERM_ERR; @@ -856,7 +857,7 @@ if (!IN_BDM) return TERM_ERR; // write the optional address if (addr) { - if(!bdm_address(addr)) return TERM_ERR; + if (!bdm_address(addr)) return TERM_ERR; } // write the value if (!bdm_put((uint32_t*)&value, BDM_BYTESIZE)) return TERM_ERR; @@ -870,30 +871,21 @@ Writes 2 words to the same address The BDM commands are overlapped to make things a bit faster A BDM_NOP command is then sent to end the sequence of overlapping commands - + @param addr address value1, 2 values to write @return status flag */ uint8_t memwrite_word_write_word(const uint32_t* addr, const uint16_t value1, const uint16_t value2) { - - if (!IN_BDM) return TERM_ERR; - - // write command code - if (!bdm_command(BDM_WRITE + BDM_WORDSIZE)) return TERM_ERR; - // write the address - if (!bdm_address(addr)) return TERM_ERR; - // write the first value - if (!bdm_put((uint32_t*)&value1, BDM_WORDSIZE)) return TERM_ERR; - // wait until MCU responds and overlap the next write command - if (!bdm_ready(BDM_WRITE + BDM_WORDSIZE)) return TERM_ERR; - // write the address (same address for second word) - if (!bdm_address(addr)) return TERM_ERR; - // write the second value - if (!bdm_put((uint32_t*)&value2, BDM_WORDSIZE)) return TERM_ERR; - // wait until MCU responds - return (bdm_ready(BDM_NOP)) ? TERM_OK : TERM_ERR; + 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 } //----------------------------------------------------------------------------- @@ -910,21 +902,13 @@ */ uint8_t memwrite_word_read_word(uint16_t* result, const uint32_t* addr, const uint16_t value) { - - if (!IN_BDM) return TERM_ERR; - - // write command code - if (!bdm_command(BDM_WRITE + BDM_WORDSIZE)) return TERM_ERR; - // write the address - if (!bdm_address(addr)) return TERM_ERR; - // write the value - if (!bdm_put((uint32_t*)&value, BDM_WORDSIZE)) return TERM_ERR; - // wait until MCU responds and overlap the next read command - if (!bdm_ready(BDM_READ + BDM_WORDSIZE)) return TERM_ERR; - // write the address (same address for reading the result) - if (!bdm_address(addr)) return TERM_ERR; - // receive the response word - return (bdm_get((uint32_t*)result, BDM_WORDSIZE, BDM_NOP)) ? TERM_OK : TERM_ERR; + 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 } //----------------------------------------------------------------------------- @@ -1169,19 +1153,19 @@ bool bdm_command (uint16_t cmd) { // write command code - bdm_clk(cmd, CMD_BIT_COUNT); + bdm_clk_fast(cmd, CMD_BIT_COUNT); return (bdm_response > BDM_NOTREADY) ? false : true; } bool bdm_address (const uint32_t* addr) { // write an address // first word - bdm_clk((uint16_t)((*addr) >> 16), CMD_BIT_COUNT); + bdm_clk_fast((uint16_t)((*addr) >> 16), CMD_BIT_COUNT); if (bdm_response > BDM_NOTREADY) { return false; } // second word - bdm_clk((uint16_t)(*addr), CMD_BIT_COUNT); + bdm_clk_fast((uint16_t)(*addr), CMD_BIT_COUNT); return (bdm_response > BDM_NOTREADY) ? false : true; } @@ -1194,7 +1178,7 @@ // wait while MCU prepares the response wait_cnt = ERR_COUNT; do { - bdm_clk(next_cmd, CMD_BIT_COUNT); + bdm_clk_fast(next_cmd, CMD_BIT_COUNT); } while (bdm_response == BDM_NOTREADY && --wait_cnt > 0); // save the result @@ -1212,12 +1196,12 @@ bool bdm_put (const uint32_t* value, uint8_t size) { // write the value if (size & BDM_LONGSIZE) { - bdm_clk((uint16_t)((*value) >> 16), CMD_BIT_COUNT); + bdm_clk_fast((uint16_t)((*value) >> 16), CMD_BIT_COUNT); if (bdm_response > BDM_NOTREADY) { return false; } } - bdm_clk((uint16_t)(*value), CMD_BIT_COUNT); + bdm_clk_fast((uint16_t)(*value), CMD_BIT_COUNT); return (bdm_response > BDM_NOTREADY) ? false : true; } @@ -1226,7 +1210,7 @@ uint8_t wait_cnt = ERR_COUNT; do { // read response - bdm_clk(next_cmd, CMD_BIT_COUNT); + bdm_clk_fast(next_cmd, CMD_BIT_COUNT); } while (bdm_response == BDM_NOTREADY && --wait_cnt > 0); // check if command succeeded @@ -1242,42 +1226,77 @@ */ void bdm_clk(uint16_t value, uint8_t num_bits) { // PIN_BKPT.output(); -// PIN_DSI.output(); - LPC_GPIO2->FIODIR |= 0x00000004; + 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(); -// LPC_GPIO2->FIODIR &= 0xfffffffb; } //----------------------------------------------------------------------------- /** + Writes a word to target MCU via BDM line and gets the response. + This 'fast' version can be used once the 68332 has been 'prepped' + 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_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); + 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); + // falling edge on BKPT/DSCLK + LPC_GPIO2->FIOCLR = (1 << 4); +// for (uint8_t c = 1; c; c--); +// // 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)); + // rising edge on BKPT/DSCLK + LPC_GPIO2->FIOSET = (1 << 4); + 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() {