Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

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);