Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

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() {