Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bdmcpu32.cpp Source File

bdmcpu32.cpp

00001 /*******************************************************************************
00002 
00003 bdmcpu32.cpp
00004 (c) 2010 by Sophie Dexter
00005 
00006 Generic BDM functions for Just4Trionic by Just4pLeisure
00007 
00008 A derivative work based on:
00009 //-----------------------------------------------------------------------------
00010 //    CAN/BDM adapter firmware
00011 //    (C) Janis Silins, 2010
00012 //    $id$
00013 //-----------------------------------------------------------------------------
00014 
00015 ********************************************************************************
00016 
00017 WARNING: Use at your own risk, sadly this software comes with no guarantees.
00018 This software is provided 'free' and in good faith, but the author does not
00019 accept liability for any damage arising from its use.
00020 
00021 *******************************************************************************/
00022 
00023 #include "bdmcpu32.h"
00024 
00025 // constants
00026 #define MCU_SETTLE_TIME     10        ///< delay to let MCU switch modes, ms
00027 #define CMD_BIT_COUNT       17        ///< command size, bits
00028 
00029 // BDM commands
00030 #define BDM_NOP             0x0000    ///< no-op
00031 #define BDM_GO              0x0c00    ///< resume execution
00032 #define BDM_WRITE           0x1800    ///< write memory
00033 #define BDM_READ            0x1900    ///< read memory 
00034 #define BDM_WSREG           0x2480    ///< write system register
00035 #define BDM_RSREG           0x2580    ///< read system register
00036 #define BDM_RDREG           0x2180    ///< read A/D register
00037 #define BDM_WRREG           0x2080    ///< write A/D register
00038 #define BDM_DUMP            0x1d00    ///< dump memory
00039 #define BDM_FILL            0x1c00    ///< fill memory
00040 #define BDM_CALL            0x0800    ///< function call
00041 #define BDM_RST             0x0400    ///< reset
00042 
00043 // system registers
00044 #define SREG_RPC            0x0
00045 #define SREG_PCC            0x1
00046 #define SREG_SR             0xb
00047 #define SREG_USP            0xc
00048 #define SREG_SSP            0xd
00049 #define SREG_SFC            0xe
00050 #define SREG_DFC            0xf
00051 #define SREG_ATEMP          0x8
00052 #define SREG_FAR            0x9
00053 #define SREG_VBR            0xa
00054 
00055 // BDM responses
00056 #define BDM_CMDCMPLTE       0x0000ffff    ///< command complete
00057 #define BDM_NOTREADY        0x00010000    ///< response not ready
00058 #define BDM_BERR            0x00010001    ///< error
00059 #define BDM_ILLEGAL         0x0001ffff    ///< illegal command
00060 
00061 // BDM data sizes
00062 #define BDM_BYTESIZE        0x00        ///< byte
00063 #define BDM_WORDSIZE        0x40        ///< word (2 bytes)
00064 #define BDM_LONGSIZE        0x80        ///< long word (4 bytes)
00065 
00066 // Bit-Banding memory region constants and macros
00067 #define RAM_BASE 0x20000000
00068 #define RAM_BB_BASE 0x22000000
00069 #define PERIHERALS_BASE 0x40000000
00070 #define PERIHERALS_BB_BASE 0x42000000
00071 #define LPC1768_AHB_BANK_0  0x2007C000
00072 #define LPC1768_AHB_BANK_1  0x20080000
00073 #define LPC1768_AHB_BANK_SIZE 0x00004000
00074 #define LPC1768_PERIPH_BANK 0x2009C000
00075 #define LPC1768_PERIPH_SIZE 0x00004000
00076 
00077 #define varBit(Variable,BitNumber) (*(uint32_t *) (RAM_BB_BASE | (((uint32_t)&Variable - RAM_BASE) << 5) | ((BitNumber) << 2)))
00078 #define periphBit(Peripheral,BitNumber) (*(uint32_t *) (PERIHERALS_BB_BASE | (((uint32_t)&Peripheral - PERIHERALS_BASE) << 5) | ((BitNumber) << 2)))
00079 #define bitAlias(Variable,BitNumber) (*(uint32_t *) (RAM_BB_BASE | (((uint32_t)&Variable - RAM_BASE) << 5) | ((BitNumber) << 2)))
00080 
00081 // static variables
00082 __attribute__((section("AHBSRAM0"))) static uint32_t bdm_response = 0;      ///< result of BDM read/write operation
00083 
00084 // private functions
00085 bool bdm_read(uint32_t* result, uint16_t cmd, const uint32_t* addr);
00086 //bool bdm_read_overlap(uint32_t* result, uint16_t cmd, const uint32_t* addr, uint16_t next_cmd);
00087 //bool bdm_read_continue(uint32_t* result, const uint32_t* addr, uint16_t next_cmd);
00088 bool bdm_write(const uint32_t* addr, uint16_t cmd, const uint32_t* value);
00089 //bool bdm_write_overlap(const uint32_t* addr, uint16_t cmd, const uint32_t* value, uint16_t next_cmd);
00090 //
00091 //void bdm_clk(uint16_t value, uint8_t num_bits);
00092 void bdm_clk_slow(uint16_t value, uint8_t num_bits);
00093 void bdm_clk_fast(uint16_t value, uint8_t num_bits);
00094 void bdm_clk_turbo(uint16_t value, uint8_t num_bits);
00095 void bdm_clk_nitrous(uint16_t value, uint8_t num_bits);
00096 void (*bdm_clk)(uint16_t value, uint8_t num_bits) = bdm_clk_slow;
00097 //
00098 void bdm_clear();
00099 
00100 //-----------------------------------------------------------------------------
00101 /**
00102     Stops target MCU and puts into background debug mode (BDM).
00103 
00104     @return                        status flag
00105 */
00106 uint8_t stop_chip()
00107 {
00108     // not connected
00109     if (!IS_CONNECTED) {
00110         return TERM_ERR;
00111     }
00112 
00113     // pull BKPT low to enter background mode (the pin must remain in output mode,
00114     // otherwise the target will pull it high and we'll lose the first DSO bit)
00115     PIN_BKPT.write(0);
00116     // set BPKT pin as output
00117     PIN_BKPT.output();
00118 
00119     // wait for target MCU to settle
00120     //wait_ms(MCU_SETTLE_TIME);
00121     timeout.reset();
00122     timeout.start();
00123     while (!IN_BDM & (timeout.read_ms() < MCU_SETTLE_TIME))
00124     timeout.stop();
00125 
00126     // check if succeeded
00127     if (!IN_BDM) {
00128         // set BKPT back as input and fail
00129         PIN_BKPT.input();
00130         return TERM_ERR;
00131     }
00132 
00133     return TERM_OK;
00134 }
00135 
00136 //-----------------------------------------------------------------------------
00137 /**
00138     Forces hardware reset on target MCU and lets it run.
00139 
00140     @return                        status flag
00141 */
00142 uint8_t reset_chip()
00143 {
00144     // not connected
00145     if (!IS_CONNECTED) {
00146         return TERM_ERR;
00147     }
00148 
00149     // BKPT pin as input
00150     PIN_BKPT.input();
00151     // push RESET low
00152     PIN_RESET.write(0);
00153     // RESET pins as output
00154     PIN_RESET.output();
00155     // wait for MCU to settle
00156     wait_ms(MCU_SETTLE_TIME);
00157     // rising edge on RESET line
00158     PIN_RESET.write(1);
00159     // wait for MCU to settle
00160     wait_ms(MCU_SETTLE_TIME);
00161 
00162     // set RESET as an input again
00163     PIN_RESET.input();
00164 
00165     // check if succeeded
00166     return IS_RUNNING ? TERM_OK : TERM_ERR;
00167 }
00168 
00169 //-----------------------------------------------------------------------------
00170 /**
00171     Starts target MCU from the specified address. If address is 0, execution
00172     begins at the current address in program counter.
00173 
00174     @param            addr        start address
00175 
00176     @return                        status flag
00177 */
00178 uint8_t run_chip(const uint32_t* addr)
00179 {
00180     // check state
00181     if (!IN_BDM) {
00182         return TERM_ERR;
00183     }
00184 
00185     // set program counter
00186     if ((*addr > 0) && sysreg_write(SREG_RPC, addr) != TERM_OK) {
00187         return TERM_ERR;
00188     }
00189     // resume MCU
00190     bdm_clk(BDM_GO, CMD_BIT_COUNT);
00191 
00192     // set BKPT back as input
00193 //    PIN_BKPT.input();
00194 
00195     return TERM_OK;
00196     // wait for target MCU to settle
00197     timeout.reset();
00198     timeout.start();
00199 //    while (!IS_RUNNING & (timeout.read_ms() < MCU_SETTLE_TIME))
00200     while (IN_BDM & (timeout.read_ms() < MCU_SETTLE_TIME))
00201     timeout.stop();
00202 
00203 //    return IS_RUNNING ? TERM_OK : TERM_ERR;
00204     return !IN_BDM ? TERM_OK : TERM_ERR;
00205 }
00206 
00207 //-----------------------------------------------------------------------------
00208 /**
00209     Resets target MCU and stops execution on first instruction fetch.
00210 
00211     @return                        status flag
00212 */
00213 uint8_t restart_chip()
00214 {
00215     // not connected
00216     if (!IS_CONNECTED) {
00217         return TERM_ERR;
00218     }
00219 
00220     // pull BKPT low to enter background mode (the pin must remain an output,
00221     // otherwise the target will pull it high and we'll lose the first DSO bit)
00222     PIN_BKPT.write(0);
00223     // push RESET low
00224     PIN_RESET.write(0);
00225     // RESET, BKPT pins as outputs
00226     PIN_BKPT.output();
00227     PIN_RESET.output();
00228     // wait for target MCU to settle
00229     wait_ms(10*MCU_SETTLE_TIME);
00230     // rising edge on RESET line
00231     PIN_RESET.write(1);
00232     // wait for target MCU to settle
00233     wait_ms(10*MCU_SETTLE_TIME);
00234     // set RESET back as an input
00235     PIN_RESET.input();
00236 
00237     // check if succeeded
00238     if (!IN_BDM) {
00239         // set BKPT back as input and fail
00240         PIN_BKPT.input();
00241         return TERM_ERR;
00242     }
00243 
00244     return TERM_OK;
00245 }
00246 
00247 //-----------------------------------------------------------------------------
00248 /**
00249     Sends GO command word to target MCU, then triggers breakpoint on first
00250     instruction fetch.
00251 
00252     @return                        status flag
00253 */
00254 uint8_t step_chip()
00255 {
00256     // not connected
00257     if (!IS_CONNECTED) {
00258         return TERM_ERR;
00259     }
00260 
00261     // resume MCU
00262     bdm_clk(BDM_GO, CMD_BIT_COUNT);
00263 
00264     // pull BKPT low to enter background mode (the pin must remain an output,
00265     // otherwise the target pulls it high and we lose the first DSO bit)
00266     PIN_BKPT.write(0);
00267     // set BPKT pin as output
00268     PIN_BKPT.output();
00269 
00270     // wait for target MCU to settle
00271 //    delay_ms(MCU_SETTLE_TIME);
00272     wait_ms(MCU_SETTLE_TIME);
00273 
00274     // check if succeeded
00275     if (!IN_BDM) {
00276         // set BKPT back as input and fail
00277         PIN_BKPT.input();
00278         return TERM_ERR;
00279     }
00280 
00281     return TERM_OK;
00282 }
00283 
00284 //-----------------------------------------------------------------------------
00285 /**
00286     Pulls BKPT pin low.
00287 */
00288 uint8_t bkpt_low()
00289 {
00290     PIN_BKPT.write(0);
00291     PIN_BKPT.output();
00292 
00293     return TERM_OK;
00294 }
00295 
00296 //-----------------------------------------------------------------------------
00297 /**
00298     Pulls BKPT pin high.
00299 */
00300 uint8_t bkpt_high()
00301 {
00302     PIN_BKPT.write(1);
00303     PIN_BKPT.output();
00304 
00305     return TERM_OK;
00306 }
00307 
00308 //-----------------------------------------------------------------------------
00309 /**
00310     Pulls RESET pin low.
00311 */
00312 uint8_t reset_low()
00313 {
00314     PIN_RESET.write(0);
00315     PIN_RESET.output();
00316 
00317     return TERM_OK;
00318 }
00319 
00320 //-----------------------------------------------------------------------------
00321 /**
00322     Pulls RESET pin high.
00323 */
00324 uint8_t reset_high()
00325 {
00326     PIN_RESET.write(1);
00327     PIN_RESET.output();
00328 
00329     return TERM_OK;
00330 }
00331 
00332 //-----------------------------------------------------------------------------
00333 /**
00334     Pulls BERR pin low.
00335 */
00336 uint8_t berr_low()
00337 {
00338     PIN_BERR.write(0);
00339     PIN_BERR.output();
00340 
00341     return TERM_OK;
00342 }
00343 
00344 //-----------------------------------------------------------------------------
00345 /**
00346     Pulls BERR pin high.
00347 */
00348 uint8_t berr_high()
00349 {
00350     PIN_BERR.write(1);
00351     PIN_BERR.output();
00352 
00353     return TERM_OK;
00354 }
00355 
00356 //-----------------------------------------------------------------------------
00357 /**
00358     Makes BERR pin an input.
00359 */
00360 uint8_t berr_input()
00361 {
00362     PIN_BERR.write(1);
00363 
00364     return TERM_OK;
00365 }
00366 
00367 //-----------------------------------------------------------------------------
00368 /**
00369     Returns byte from the specified memory location; MCU must be in
00370     background mode.
00371 
00372     @param        result            value (out)
00373     @param        addr            source address
00374 
00375     @return                        status flag
00376 */
00377 uint8_t memread_byte(uint8_t* result, const uint32_t* addr)
00378 {
00379     // check state
00380     if (!IN_BDM) {
00381         return TERM_ERR;
00382     }
00383 
00384     // read byte
00385     if (!bdm_read((uint32_t*)result, BDM_READ, addr)) {
00386         // clear the interface and fail
00387         bdm_clear();
00388         return TERM_ERR;
00389     }
00390 
00391     return TERM_OK;
00392 }
00393 
00394 //-----------------------------------------------------------------------------
00395 /**
00396     Returns word (2 bytes) from the specified memory location. Address must be
00397     word-aligned and MCU must be in background mode.
00398 
00399     @param        result            value (out)
00400     @param        addr            source address
00401 
00402     @return                        status flag
00403 */
00404 uint8_t memread_word(uint16_t* result, const uint32_t* addr)
00405 {
00406     // check state
00407     if (!IN_BDM) {
00408         return TERM_ERR;
00409     }
00410 
00411     // read word
00412     if (!bdm_read((uint32_t*)result, BDM_READ + BDM_WORDSIZE, addr)) {
00413         // clear the interface and fail
00414         bdm_clear();
00415         return TERM_ERR;
00416     }
00417 
00418     return TERM_OK;
00419 }
00420 
00421 //-----------------------------------------------------------------------------
00422 /**
00423     Returns long word (4 bytes) from the specified memory location. Address
00424     must be word-aligned and target MCU must be in background mode.
00425 
00426     @param            result            value
00427     @param            addr            source address
00428 
00429     @return                            status flag
00430 */
00431 uint8_t memread_long(uint32_t* result, const uint32_t* addr)
00432 {
00433     // check state
00434     if (!IN_BDM) {
00435         return TERM_ERR;
00436     }
00437 
00438     //  read long word
00439     if (!bdm_read(result, BDM_READ + BDM_LONGSIZE, addr)) {
00440         // clear the interface and fail
00441         bdm_clear();
00442         return TERM_ERR;
00443     }
00444 
00445     return TERM_OK;
00446 }
00447 
00448 //-----------------------------------------------------------------------------
00449 /**
00450     Dumps byte from the specified memory location; MCU must be in background
00451     mode. Any memread_*() function must be called beforehand to set the
00452     initial address.
00453 
00454     @param        value            result (out)
00455 
00456     @return                        status flag
00457 */
00458 uint8_t memdump_byte(uint8_t* result)
00459 {
00460     // check state
00461     if (!IN_BDM) {
00462         return TERM_ERR;
00463     }
00464 
00465     // dump byte
00466     if (!bdm_read((uint32_t*)result, BDM_DUMP, NULL)) {
00467         // clear the interface and fail
00468         bdm_clear();
00469         return TERM_ERR;
00470     }
00471 
00472     return TERM_OK;
00473 }
00474 
00475 //-----------------------------------------------------------------------------
00476 /**
00477     dumps word from the specified memory location; MCU must be in background
00478     mode. Any memread_*() function must be called beforehand to set the
00479     initial address.
00480 
00481     @param        value            result (out)
00482 
00483     @return                        status flag
00484 */
00485 uint8_t memdump_word(uint16_t* result)
00486 {
00487     // check state
00488     if (!IN_BDM) {
00489         return TERM_ERR;
00490     }
00491 
00492     // dump word
00493     if (!bdm_read((uint32_t*)result, BDM_DUMP + BDM_WORDSIZE, NULL)) {
00494         // clear the interface and fail
00495         bdm_clear();
00496         return TERM_ERR;
00497     }
00498 
00499     return TERM_OK;
00500 }
00501 
00502 //-----------------------------------------------------------------------------
00503 /**
00504     Dumps long word  from the specified memory location; MCU must be in
00505     background mode. Any memread_*() function must be called beforehand to set
00506     the initial address.
00507 
00508     @param        value            result (out)
00509 
00510     @return                        status flag
00511 */
00512 uint8_t memdump_long(uint32_t* result)
00513 {
00514     // check state
00515     if (!IN_BDM) {
00516         return TERM_ERR;
00517     }
00518 
00519     // dump long word
00520     if (!bdm_read(result, BDM_DUMP + BDM_LONGSIZE, NULL)) {
00521         // clear the interface and fail
00522         bdm_clear();
00523         return TERM_ERR;
00524     }
00525 
00526     return TERM_OK;
00527 }
00528 
00529 //-----------------------------------------------------------------------------
00530 /**
00531     Writes byte to the specified memory location; MCU must be in background
00532     mode.
00533 
00534     @param        addr            destination address
00535     @param        value            value
00536 
00537     @return                        status flag
00538 */
00539 uint8_t memwrite_byte(const uint32_t* addr, uint8_t value)
00540 {
00541     // check state
00542     if (!IN_BDM) {
00543         return TERM_ERR;
00544     }
00545 
00546     // write byte
00547     if (!bdm_write(addr, BDM_WRITE, (uint32_t*)&value)) {
00548         // clear the interface and fail
00549         bdm_clear();
00550         return TERM_ERR;
00551     }
00552 
00553     return TERM_OK;
00554 }
00555 
00556 //-----------------------------------------------------------------------------
00557 /**
00558     Writes word to the specified memory location. Address must be word-aligned
00559     and MCU must be in background mode.
00560 
00561     @param        addr            memory address
00562     @param        value            value
00563 
00564     @return                        status flag
00565 */
00566 uint8_t memwrite_word(const uint32_t* addr, uint16_t value)
00567 {
00568     // check state
00569     if (!IN_BDM) {
00570         return TERM_ERR;
00571     }
00572 
00573     // write word
00574     if (!bdm_write(addr, BDM_WRITE + BDM_WORDSIZE, (uint32_t*)&value)) {
00575         // clear the interface and fail
00576         bdm_clear();
00577         return TERM_ERR;
00578     }
00579 
00580     return TERM_OK;
00581 }
00582 
00583 //-----------------------------------------------------------------------------
00584 /**
00585     Writes long word to the specified memory location. Address must be
00586     word-aligned and target MCU must be in background mode.
00587 
00588     @param        addr            memory address
00589     @param        value            value
00590 
00591     @return                        status flag
00592 */
00593 uint8_t memwrite_long(const uint32_t* addr, const uint32_t* value)
00594 {
00595     // check state
00596     if (!IN_BDM) {
00597         return TERM_ERR;
00598     }
00599 
00600     // write long word
00601     if (!bdm_write(addr, BDM_WRITE + BDM_LONGSIZE, value)) {
00602         // clear the interface and fail
00603         bdm_clear();
00604         return TERM_ERR;
00605     }
00606 
00607     return TERM_OK;
00608 }
00609 
00610 //-----------------------------------------------------------------------------
00611 /**
00612     Writes byte to the current memory location; MCU must be in background
00613     mode. Any memwrite_*() function must be called beforehand to set the
00614     current address.
00615 
00616     @param        value            value
00617 
00618     @return                        status flag
00619 */
00620 uint8_t memfill_byte(uint8_t value)
00621 {
00622     // check state
00623     if (!IN_BDM) {
00624         return TERM_ERR;
00625     }
00626 
00627     // fill byte
00628     if (!bdm_write(NULL, BDM_FILL, (uint32_t*)&value)) {
00629         // clear the interface and fail
00630         bdm_clear();
00631         return TERM_ERR;
00632     }
00633 
00634     return TERM_OK;
00635 }
00636 
00637 //-----------------------------------------------------------------------------
00638 /**
00639     Writes word to the specified memory location; MCU must be in background
00640     mode. Any memwrite_*() function must be called beforehand to set the
00641     initial address.
00642 
00643     @param        value            value
00644 
00645     @return                        status flag
00646 */
00647 uint8_t memfill_word(uint16_t value)
00648 {
00649     // check state
00650     if (!IN_BDM) {
00651         return TERM_ERR;
00652     }
00653 
00654     // fill word
00655     if (!IN_BDM || !bdm_write(NULL, BDM_FILL + BDM_WORDSIZE, (uint32_t*)&value)) {
00656         // clear the interface and fail
00657         bdm_clear();
00658         return TERM_ERR;
00659     }
00660 
00661     return TERM_OK;
00662 }
00663 
00664 //-----------------------------------------------------------------------------
00665 /**
00666     Writes long word to the specified memory location; MCU must be in background
00667     mode. Any memwrite_*() function must be called beforehand to set the
00668     initial address.
00669 
00670     @param        value            value
00671 
00672     @return                        status flag
00673 */
00674 uint8_t memfill_long(const uint32_t* value)
00675 {
00676     // check state
00677     if (!IN_BDM) {
00678         return TERM_ERR;
00679     }
00680 
00681     // fill long word
00682     if (!bdm_write(NULL, BDM_FILL + BDM_LONGSIZE, value)) {
00683         // clear the interface and fail
00684         bdm_clear();
00685         return TERM_ERR;
00686     }
00687 
00688     return TERM_OK;
00689 }
00690 
00691 //-----------------------------------------------------------------------------
00692 /**
00693     Issues a read byte command to MCU.
00694 
00695     @param        addr        address (optional)
00696 
00697     @return                   status flag
00698 */
00699 uint8_t memread_byte_cmd(const uint32_t* addr)
00700 {
00701 
00702     if (!IN_BDM) return TERM_ERR;
00703 
00704     // write command code
00705     if (!bdm_command(BDM_READ + BDM_BYTESIZE)) return TERM_ERR;
00706     // write the optional address
00707     if (addr) {
00708         if (!bdm_address(addr)) return TERM_ERR;
00709     }
00710 
00711     return TERM_OK;
00712 }
00713 
00714 //-----------------------------------------------------------------------------
00715 /**
00716     Issues a read word command to MCU.
00717 
00718     @param        addr        address (optional)
00719 
00720     @return                   status flag
00721 */
00722 uint8_t memread_word_cmd(const uint32_t* addr)
00723 {
00724 
00725     if (!IN_BDM) return TERM_ERR;
00726 
00727     // write command code
00728     bdm_clk(BDM_READ + BDM_WORDSIZE, CMD_BIT_COUNT);
00729     if (bdm_response > BDM_CMDCMPLTE) return TERM_ERR;
00730     // write the optional address
00731     if (addr) {
00732         if (!bdm_address(addr)) return TERM_ERR;
00733     }
00734 
00735     return TERM_OK;
00736 }
00737 
00738 //-----------------------------------------------------------------------------
00739 /**
00740     Issues a read long command to MCU.
00741 
00742     @param        addr        address (optional)
00743 
00744     @return                   status flag
00745 */
00746 uint8_t memread_long_cmd(const uint32_t* addr)
00747 {
00748 
00749     if (!IN_BDM) return TERM_ERR;
00750 
00751     // write command code
00752     bdm_clk(BDM_READ + BDM_LONGSIZE, CMD_BIT_COUNT);
00753     if (bdm_response > BDM_CMDCMPLTE) return TERM_ERR;
00754     // write the optional address
00755     if (addr) {
00756         if (!bdm_address(addr)) return TERM_ERR;
00757     }
00758 
00759     return TERM_OK;
00760 }
00761 //-----------------------------------------------------------------------------
00762 /**
00763     Issues a write byte command to MCU.
00764 
00765     @param        addr        address (optional)
00766 
00767     @return                   status flag
00768 */
00769 uint8_t memwrite_byte_cmd(const uint32_t* addr)
00770 {
00771 
00772     if (!IN_BDM) return TERM_ERR;
00773 
00774     // write command code
00775     if (!bdm_command(BDM_WRITE + BDM_BYTESIZE)) return TERM_ERR;
00776     // write the optional address
00777     if (addr) {
00778         if (!bdm_address(addr)) return TERM_ERR;
00779     }
00780 
00781     return TERM_OK;
00782 }
00783 
00784 //-----------------------------------------------------------------------------
00785 /**
00786     Issues a write word command to MCU.
00787 
00788     @param        addr        address (optional)
00789 
00790     @return                   status flag
00791 */
00792 uint8_t memwrite_word_cmd(const uint32_t* addr)
00793 {
00794 
00795     if (!IN_BDM) return TERM_ERR;
00796 
00797     // write command code
00798     bdm_clk(BDM_WRITE + BDM_WORDSIZE, CMD_BIT_COUNT);
00799     if (bdm_response > BDM_CMDCMPLTE) return TERM_ERR;
00800     // write the optional address
00801     if (addr) {
00802         if (!bdm_address(addr)) return TERM_ERR;
00803     }
00804 
00805     return TERM_OK;
00806 }
00807 
00808 //-----------------------------------------------------------------------------
00809 /**
00810     Issues a write long command to MCU.
00811 
00812     @param        addr        address (optional)
00813 
00814     @return                   status flag
00815 */
00816 uint8_t memwrite_long_cmd(const uint32_t* addr)
00817 {
00818 
00819     if (!IN_BDM) return TERM_ERR;
00820 
00821     // write command code
00822     bdm_clk(BDM_WRITE + BDM_LONGSIZE, CMD_BIT_COUNT);
00823     if (bdm_response > BDM_CMDCMPLTE) return TERM_ERR;
00824     // write the optional address
00825     if (addr) {
00826         if (!bdm_address(addr)) return TERM_ERR;
00827     }
00828 
00829     return TERM_OK;
00830 }
00831 
00832 //-----------------------------------------------------------------------------
00833 /**
00834     Gets a byte from the MCU (follows a previously sent read or dump word cmd)
00835     Sends a READ_BYTE command so that commands overlap
00836 
00837     @param        result        read result (out)
00838                   addr          address (optional)
00839 
00840     @return                     status flag
00841 */
00842 uint8_t memread_read_byte(uint8_t* result, const uint32_t* addr)
00843 {
00844 
00845     if (!IN_BDM) return TERM_ERR;
00846     // write the optional address
00847     if (addr) {
00848         if (!bdm_address(addr)) return TERM_ERR;
00849     }
00850     // receive the response byte
00851     return (bdm_get ((uint32_t*)result, BDM_BYTESIZE, BDM_READ + BDM_BYTESIZE)) ? TERM_OK : TERM_ERR;
00852 }
00853 
00854 //-----------------------------------------------------------------------------
00855 /**
00856     Gets a byte from the MCU (follows a previously sent read or dump word cmd)
00857     Sends a WRITE_BYTE command so that commands overlap
00858 
00859     @param        result        read result (out)
00860                   addr          address (optional)
00861 
00862     @return                     status flag
00863 */
00864 uint8_t memread_write_byte(uint8_t* result, const uint32_t* addr)
00865 {
00866 
00867     if (!IN_BDM) return TERM_ERR;
00868     // write the optional address
00869     if (addr) {
00870         if (!bdm_address(addr)) return TERM_ERR;
00871     }
00872     // receive the response byte
00873     return (bdm_get((uint32_t*)result, BDM_BYTESIZE, BDM_WRITE + BDM_BYTESIZE)) ? TERM_OK : TERM_ERR;
00874 }
00875 
00876 //-----------------------------------------------------------------------------
00877 /**
00878     Gets a byte from the MCU (follows a previously sent read or dump word cmd)
00879     Sends a BDM_NOP command to end a sequence of overlapping commands
00880 
00881     @param        result        read result (out)
00882                   addr          address (optional)
00883 
00884     @return                     status flag
00885 */
00886 uint8_t memread_nop_byte(uint8_t* result, const uint32_t* addr)
00887 {
00888 
00889     if (!IN_BDM) return TERM_ERR;
00890     // write the optional address
00891     if (addr) {
00892         if (!bdm_address(addr)) return TERM_ERR;
00893     }
00894     // receive the response byte
00895     return (bdm_get((uint32_t*)result, BDM_BYTESIZE, BDM_NOP)) ? TERM_OK : TERM_ERR;
00896 }
00897 
00898 //-----------------------------------------------------------------------------
00899 /**
00900     Writes a byte to the MCU (follows a previously sent write or fill word cmd)
00901     Sends a WRITE_BYTE command so that commands overlap
00902 
00903     @param        addr          address (optional)
00904                   value         value to write
00905 
00906     @return                     status flag
00907 */
00908 uint8_t memwrite_write_byte(const uint32_t* addr, uint8_t value)
00909 {
00910 
00911     if (!IN_BDM) return TERM_ERR;
00912     // write the optional address
00913     if (addr) {
00914         if (!bdm_address(addr)) return TERM_ERR;
00915     }
00916     // write the value
00917     if (!bdm_put((uint32_t*)&value, BDM_BYTESIZE)) return TERM_ERR;
00918     // wait until MCU responds
00919     return (bdm_ready(BDM_WRITE + BDM_BYTESIZE)) ? TERM_OK : TERM_ERR;
00920 }
00921 
00922 //-----------------------------------------------------------------------------
00923 /**
00924     Writes a byte to the MCU (follows a previously sent write or fill word cmd)
00925     Sends a READ_BYTE command so that commands overlap
00926 
00927     @param        addr          address (optional)
00928                   value         value to write
00929 
00930     @return                     status flag
00931 */
00932 uint8_t memwrite_read_byte(const uint32_t* addr, uint8_t value)
00933 {
00934 
00935     if (!IN_BDM) return TERM_ERR;
00936     // write the optional address
00937     if (addr) {
00938         if (!bdm_address(addr)) return TERM_ERR;
00939     }
00940     // write the value
00941     if (!bdm_put((uint32_t*)&value, BDM_BYTESIZE)) return TERM_ERR;
00942     // wait until MCU responds
00943     return (bdm_ready(BDM_READ + BDM_BYTESIZE)) ? TERM_OK : TERM_ERR;
00944 }
00945 
00946 //-----------------------------------------------------------------------------
00947 /**
00948     Writes a byte to the MCU (follows a previously sent write or fill word cmd)
00949     Sends a BDM_NOP command to end a sequence of overlapping commands
00950 
00951     @param        addr          address (optional)
00952                   value         value to write
00953 
00954     @return                     status flag
00955 */
00956 uint8_t memwrite_nop_byte(const uint32_t* addr, uint8_t value)
00957 {
00958 
00959     if (!IN_BDM) return TERM_ERR;
00960     // write the optional address
00961     if (addr) {
00962         if (!bdm_address(addr)) return TERM_ERR;
00963     }
00964     // write the value
00965     if (!bdm_put((uint32_t*)&value, BDM_BYTESIZE)) return TERM_ERR;
00966     // wait until MCU responds
00967     return (bdm_ready(BDM_NOP)) ? TERM_OK : TERM_ERR;
00968 }
00969 
00970 
00971 //-----------------------------------------------------------------------------
00972 /**
00973     Writes 2 words to the same address
00974     The BDM commands are overlapped to make things a bit faster
00975     A BDM_NOP command is then sent to end the sequence of overlapping commands
00976 
00977     @param        addr          address
00978                   value1, 2     values to write
00979 
00980     @return                     status flag
00981 */
00982 uint8_t memwrite_word_write_word(const uint32_t* addr, const uint16_t value1, const uint16_t value2)
00983 {
00984     return (IN_BDM &&
00985             bdm_command(BDM_WRITE + BDM_WORDSIZE) &&        // write command code
00986             bdm_address(addr) &&                            // write the address
00987             bdm_put((uint32_t*)&value1, BDM_WORDSIZE) &&    // write the first value
00988             bdm_ready(BDM_WRITE + BDM_WORDSIZE) &&          // wait until MCU responds and overlap the next write command
00989             bdm_address(addr) &&                            // write the address (same address for second word)
00990             bdm_put((uint32_t*)&value2, BDM_WORDSIZE) &&    // write the second value
00991             bdm_ready(BDM_NOP)) ? TERM_OK : TERM_ERR;       // wait until MCU responds
00992 }
00993 
00994 //-----------------------------------------------------------------------------
00995 /**
00996     Writes a word then reads back a result from the same address
00997     The BDM commands are overlapped to make things a bit faster
00998     A BDM_NOP command is then sent to end the sequence of overlapping commands
00999 
01000     @param        result        read result (out)
01001                   addr          address
01002                   value         value to write
01003 
01004     @return                     status flag
01005 */
01006 
01007 uint8_t memwrite_word_read_word(uint16_t* result, const uint32_t* addr, const uint16_t value)
01008 {
01009     return (IN_BDM &&
01010             bdm_command(BDM_WRITE + BDM_WORDSIZE) &&        // write command code
01011             bdm_address(addr) &&                            // write the address
01012             bdm_put((uint32_t*)&value, BDM_WORDSIZE) &&     // write the value
01013             bdm_ready(BDM_READ + BDM_WORDSIZE) &&           // wait until MCU responds and overlap the next read command
01014             bdm_address(addr) &&                            // write the address (same address for reading the result)
01015             bdm_get((uint32_t*)result, BDM_WORDSIZE, BDM_NOP)) ? TERM_OK : TERM_ERR;    // receive the response word
01016 }
01017 
01018 //-----------------------------------------------------------------------------
01019 /**
01020     Gets a word from the MCU (follows a previously sent read or dump word cmd)
01021     Sends a DUMP_WORD command so that dump commands overlap
01022 
01023     @param        result        read result (out)
01024 
01025     @return                     status flag
01026 */
01027 uint8_t memget_word(uint16_t* result)
01028 {
01029 
01030     if (!IN_BDM) return TERM_ERR;
01031     // receive the response word
01032     return (bdm_get((uint32_t*)result, BDM_WORDSIZE, BDM_DUMP + BDM_WORDSIZE)) ? TERM_OK : TERM_ERR;
01033 }
01034 
01035 //-----------------------------------------------------------------------------
01036 /**
01037     Gets a long from the MCU (follows a previously sent read or dump long cmd)
01038     Sends a DUMP_LONG command so that dump commands overlap
01039 
01040     @param        result        read result (out)
01041 
01042     @return                     status flag
01043 */
01044 uint8_t memget_long(uint32_t* result)
01045 {
01046 
01047     if (!IN_BDM) return TERM_ERR;
01048     // receive the response words
01049     return (bdm_get(result, BDM_LONGSIZE, BDM_DUMP + BDM_LONGSIZE)) ? TERM_OK : TERM_ERR;
01050 }
01051 
01052 //-----------------------------------------------------------------------------
01053 /**
01054     Reads value from system register.
01055 
01056     @param        result            register value (out)
01057     @param        reg                register
01058 
01059     @return                        status flag
01060 */
01061 uint8_t sysreg_read(uint32_t* result, uint8_t reg)
01062 {
01063     // check state
01064     if (!IN_BDM) {
01065         return TERM_ERR;
01066     }
01067 
01068     // read register
01069     if (!bdm_read(result, BDM_RSREG + reg, NULL)) {
01070         // clear the interface and fail
01071         return TERM_ERR;
01072     }
01073 
01074     return TERM_OK;
01075 }
01076 
01077 //-----------------------------------------------------------------------------
01078 /**
01079     Writes value to system register.
01080 
01081     @param        reg                register
01082     @param        value            register value
01083 
01084     @return                        status flag
01085 */
01086 uint8_t sysreg_write(uint8_t reg, const uint32_t* value)
01087 {
01088     // check state
01089     if (!IN_BDM) {
01090         return TERM_ERR;
01091     }
01092 
01093     // write register
01094     if (!bdm_write(NULL, BDM_WSREG + reg, value)) {
01095         // clear the interface and fail
01096         bdm_clear();
01097         return TERM_ERR;
01098     }
01099 
01100     return TERM_OK;
01101 }
01102 
01103 //-----------------------------------------------------------------------------
01104 /**
01105     Reads value from A/D register.
01106 
01107     @param        result            register value (out)
01108     @param        reg                register
01109 
01110     @return                        status flag
01111 */
01112 uint8_t adreg_read(uint32_t* result, uint8_t reg)
01113 {
01114     // check state
01115     if (!IN_BDM) {
01116         return TERM_ERR;
01117     }
01118 
01119     // read register
01120     if (!bdm_read(result, BDM_RDREG + reg, NULL)) {
01121         // clear the interface and fail
01122         bdm_clear();
01123         return TERM_ERR;
01124     }
01125     return TERM_OK;
01126 }
01127 
01128 //-----------------------------------------------------------------------------
01129 /**
01130     Writes value to A/D register.
01131 
01132     @param        reg                register
01133     @param        value            register value
01134 
01135     @return                        status flag
01136 */
01137 uint8_t adreg_write(uint8_t reg, const uint32_t* value)
01138 {
01139     // check state
01140     if (!IN_BDM) {
01141         return TERM_ERR;
01142     }
01143 
01144     // write register
01145     if (!bdm_write(NULL, BDM_WRREG + reg, value)) {
01146         // clear the interface and fail
01147         bdm_clear();
01148         return TERM_ERR;
01149     }
01150 
01151     return TERM_OK;
01152 }
01153 
01154 //-----------------------------------------------------------------------------
01155 /**
01156     Issues a read command to MCU.
01157 
01158     @param        result        read result (out)
01159     @param        cmd            command sequence
01160     @param        addr        address (optional)
01161 
01162     @return                    succ / fail
01163 */
01164 bool bdm_read(uint32_t* result, uint16_t cmd, const uint32_t* addr)
01165 {
01166     *result = 0;
01167 
01168     // write command code
01169     bdm_clk(cmd, CMD_BIT_COUNT);
01170     if (bdm_response > BDM_CMDCMPLTE) {
01171         return false;
01172     }
01173 
01174     // write the optional address
01175     if (addr) {
01176         // first word
01177         bdm_clk((uint16_t)(*addr >> 16), CMD_BIT_COUNT);
01178         if (bdm_response > BDM_NOTREADY) {
01179             return false;
01180         }
01181         // second word
01182         bdm_clk((uint16_t)(*addr), CMD_BIT_COUNT);
01183         if (bdm_response > BDM_NOTREADY) {
01184             return false;
01185         }
01186     }
01187 
01188     // receive response words
01189     uint8_t wait_cnt;
01190     for (uint8_t curr_word = 0; curr_word < ((cmd & BDM_LONGSIZE) ? 2 : 1);
01191             ++curr_word) {
01192         // wait while MCU prepares the response
01193         wait_cnt = ERR_COUNT;
01194         do {
01195             bdm_clk(BDM_NOP, CMD_BIT_COUNT);
01196         } while (bdm_response == BDM_NOTREADY && --wait_cnt > 0);
01197 
01198         // save the result
01199         if (bdm_response < BDM_NOTREADY) {
01200             (*result) <<= 16;
01201             (*result) |= bdm_response;
01202         } else {
01203             // result was not received
01204             return false;
01205         }
01206     }
01207 
01208     return true;
01209 }
01210 
01211 //-----------------------------------------------------------------------------
01212 /**
01213     Issues a write command to MCU.
01214 
01215     @param        num_words        number of additional command words
01216     @param        cmd                command sequence
01217 
01218     @return                        succ / fail
01219 */
01220 bool bdm_write(const uint32_t* addr, uint16_t cmd, const uint32_t* value)
01221 {
01222     // write command code
01223     bdm_clk(cmd, CMD_BIT_COUNT);
01224     if (bdm_response > BDM_NOTREADY) {
01225         return false;
01226     }
01227 
01228     // write the optional address
01229     if (addr) {
01230         // first word
01231         bdm_clk((uint16_t)((*addr) >> 16), CMD_BIT_COUNT);
01232         if (bdm_response > BDM_NOTREADY) {
01233             return false;
01234         }
01235         // second word
01236         bdm_clk((uint16_t)(*addr), CMD_BIT_COUNT);
01237         if (bdm_response > BDM_NOTREADY) {
01238             return false;
01239         }
01240     }
01241 
01242     // write the value
01243     if (cmd & BDM_LONGSIZE) {
01244         bdm_clk((uint16_t)((*value) >> 16), CMD_BIT_COUNT);
01245         if (bdm_response > BDM_NOTREADY) {
01246             return false;
01247         }
01248     }
01249     bdm_clk((uint16_t)(*value), CMD_BIT_COUNT);
01250     if (bdm_response > BDM_NOTREADY) {
01251         return false;
01252     }
01253 
01254     // wait until MCU responds
01255     uint8_t wait_cnt = ERR_COUNT;
01256     do {
01257         // read response
01258         bdm_clk(BDM_NOP, CMD_BIT_COUNT);
01259     } while (bdm_response == BDM_NOTREADY && --wait_cnt > 0);
01260 
01261     // check if command succeeded
01262     return (bdm_response == BDM_CMDCMPLTE);
01263 }
01264 
01265 bool bdm_command (uint16_t cmd)
01266 {
01267     // write command code
01268     bdm_clk(cmd, CMD_BIT_COUNT);
01269     return (bdm_response > BDM_NOTREADY) ? false : true;
01270 }
01271 
01272 bool bdm_address (const uint32_t* addr)
01273 {
01274     // write an address
01275     // first word
01276     bdm_clk((uint16_t)((*addr) >> 16), CMD_BIT_COUNT);
01277     if (bdm_response > BDM_NOTREADY) {
01278         return false;
01279     }
01280     // second word
01281     bdm_clk((uint16_t)(*addr), CMD_BIT_COUNT);
01282     return (bdm_response > BDM_NOTREADY) ? false : true;
01283 }
01284 
01285 bool bdm_get (uint32_t* result, uint8_t size, uint16_t next_cmd)
01286 {
01287     // receive response words
01288     *result = 0;
01289     uint8_t wait_cnt;
01290     for (uint8_t curr_word = 0; curr_word < ((size & BDM_LONGSIZE) ? 2 : 1);
01291             ++curr_word) {
01292         // wait while MCU prepares the response
01293         wait_cnt = ERR_COUNT;
01294         do {
01295             bdm_clk(next_cmd, CMD_BIT_COUNT);
01296         } while (bdm_response == BDM_NOTREADY && --wait_cnt > 0);
01297 
01298         // save the result
01299         if (bdm_response < BDM_NOTREADY) {
01300             (*result) <<= 16;
01301             (*result) |= bdm_response;
01302         } else {
01303             // result was not received
01304             return false;
01305         }
01306     }
01307     return true;
01308 }
01309 
01310 bool bdm_put (const uint32_t* value, uint8_t size)
01311 {
01312     // write the value
01313     if (size & BDM_LONGSIZE) {
01314         bdm_clk((uint16_t)((*value) >> 16), CMD_BIT_COUNT);
01315         if (bdm_response > BDM_NOTREADY) {
01316             return false;
01317         }
01318     }
01319     bdm_clk((uint16_t)(*value), CMD_BIT_COUNT);
01320     return (bdm_response > BDM_NOTREADY) ? false : true;
01321 }
01322 
01323 bool bdm_ready (uint16_t next_cmd)
01324 {
01325     // wait until MCU responds
01326     uint8_t wait_cnt = ERR_COUNT;
01327     do {
01328         // read response
01329         bdm_clk(next_cmd, CMD_BIT_COUNT);
01330     } while (bdm_response == BDM_NOTREADY && --wait_cnt > 0);
01331 
01332     // check if command succeeded
01333     return (bdm_response == BDM_CMDCMPLTE);
01334 }
01335 
01336 
01337 //-----------------------------------------------------------------------------
01338 /**
01339     Sets the speed at which BDM data is trransferred.
01340 
01341     @param            mode            SLOW, FAST, TURBO, NITROUS
01342 */
01343 void bdm_clk_mode(bdm_speed mode)
01344 {
01345     switch (mode) {
01346         case NITROUS:
01347             bdm_clk = &bdm_clk_nitrous;
01348             break;
01349         case TURBO:
01350             bdm_clk = &bdm_clk_turbo;
01351             break;
01352         case FAST:
01353             bdm_clk = &bdm_clk_fast;
01354             break;
01355         case SLOW:
01356         default:
01357             bdm_clk = &bdm_clk_slow;
01358             break;
01359     }
01360     return;
01361 }
01362 
01363 //-----------------------------------------------------------------------------
01364 /**
01365     Writes a word to target MCU via BDM line and gets the response.
01366 
01367     @param            value            value to write
01368     @param            num_bits        value size, bits
01369 */
01370 /*
01371 void bdm_clk(uint16_t value, uint8_t num_bits)
01372 {
01373 //    PIN_BKPT.output();
01374     PIN_DSI.output();
01375     // clock the value via BDM
01376     bdm_response = ((uint32_t)value) << (32 - num_bits);
01377     while (num_bits--) {
01378         // falling edge on BKPT/DSCLK
01379         PIN_BKPT.write(0);
01380         // set DSI bit
01381         PIN_DSI.write(bdm_response & 0x80000000);
01382         bdm_response <<= 1;
01383         // read DSO bit
01384         bdm_response |= PIN_DSO.read();
01385         // short delay
01386 //        for (uint8_t c = 1; c; c--);
01387 //        wait_us(1);
01388         // rising edge on BKPT/DSCLK
01389         PIN_BKPT.write(1);
01390         // short delay
01391 //        for (uint8_t c = 1; c; c--);
01392 //        wait_us(1);
01393     }
01394     PIN_DSI.input();
01395 }
01396 */
01397 
01398 //-----------------------------------------------------------------------------
01399 /**
01400     Writes a word to target MCU via BDM line and gets the response.
01401 
01402     @param            value            value to write
01403     @param            num_bits        value size, bits
01404 */
01405 
01406 void bdm_clk_slow(uint16_t value, uint8_t num_bits) {
01407 //    PIN_BKPT.output();
01408     PIN_DSI.output();
01409     // clock the value via BDM
01410     bdm_response = ((uint32_t)value) << (32 - num_bits);
01411 //    bool dsi;
01412     while (num_bits--) {
01413 
01414         // falling edge on BKPT/DSCLK
01415         PIN_BKPT.write(0);
01416         // set DSI bit
01417         PIN_DSI.write(bdm_response & 0x80000000);
01418         bdm_response <<= 1;
01419         // read DSO bit
01420         bdm_response |= PIN_DSO.read();
01421         // short delay
01422 //        for (uint8_t c = 1; c; c--);
01423 //        wait_us(1);
01424         // rising edge on BKPT/DSCLK
01425         PIN_BKPT.write(1);
01426         // short delay
01427 //        for (uint8_t c = 1; c; c--);
01428 //        wait_us(1);
01429     }
01430     PIN_DSI.input();
01431 }
01432 //
01433 
01434 //-----------------------------------------------------------------------------
01435 /**
01436     Writes a word to target MCU via BDM line and gets the response.
01437     This 'fast' version can be used once the 68332 has been 'prepped'
01438     because the BDM interface can go twice as fast once the 68332
01439     clock is increased from 8 MHz to 16 MHz
01440 
01441     @param            value            value to write
01442     @param            num_bits        value size, bits
01443 */
01444 
01445 void bdm_clk_fast(uint16_t value, uint8_t num_bits)
01446 {
01447 
01448     //Make DSI an output
01449     LPC_GPIO2->FIODIR |= (1 << 2);
01450     // clock the value via BDM
01451     bdm_response = ((uint32_t)value) << (32 - num_bits);
01452     // Clock BDM Data in from DSO and out to DSI
01453     while (num_bits--) {
01454         // set DSI bit
01455         (bdm_response & 0x80000000) ? LPC_GPIO2->FIOSET = (1 << 2) : LPC_GPIO2->FIOCLR = (1 << 2);
01456         // falling edge on BKPT/DSCLK
01457         LPC_GPIO2->FIOCLR = (1 << 4);
01458         // read DSO bit
01459 //        (bdm_response <<= 1) |= (bool)((LPC_GPIO0->FIOPIN) & (1 << 11));  -- OLD CONNECTION to PIN 27
01460         (bdm_response <<= 1) |= (bool)((LPC_GPIO2->FIOPIN) & (1 << 1));
01461         // rising edge on BKPT/DSCLK
01462         LPC_GPIO2->FIOSET = (1 << 4);
01463         // introduce a delay to insure that BDM clock isn't too fast
01464         for (uint8_t c = 9; c; c--);    // was 5
01465     }
01466     //Make DSI an input
01467     LPC_GPIO2->FIODIR &= ~(1 << 2);
01468 }
01469 //-----------------------------------------------------------------------------
01470 
01471 /**
01472     Writes a word to target MCU via BDM line and gets the response.
01473     This 'turbo' version uses 'bit-banding' to read and write individual
01474     bits directly. This should be faster than the 'fast' version because
01475     the complex calculation to find the address of the BDM word 'bit-band'
01476     region is only done once per call rather than several, simpler,
01477     calculations and bit-shifts that the slow and fast functions do for
01478     each bit.
01479     
01480     The 68332 must have been 'prepped' before using the 'turbo' version
01481     because the BDM interface can go twice as fast once the 68332
01482     clock is increased from 8 MHz to 16 MHz
01483 
01484     @param            value            value to write
01485     @param            num_bits        value size, bits
01486 */
01487 
01488 void bdm_clk_turbo(uint16_t value, uint8_t num_bits)
01489 {
01490     //Make DSI an output
01491     LPC_GPIO2->FIODIR |= (1 << 2);
01492     bdm_response = (uint32_t)value;
01493     // calculate a pointer to the bitband alias region address of the most significant bit of the BDM word (NOTE num_bits-1) 
01494     uint32_t *bdm_response_bit_alias = &bitAlias(bdm_response,num_bits-1);
01495     // Clock BDM Data in from DSO and out to DSI
01496     while (num_bits--) {
01497         // set DSI bit (port 2, bit 2)
01498         bitAlias(LPC_GPIO2->FIOPIN,2) = *bdm_response_bit_alias;
01499         // falling edge on BKPT/DSCLK
01500         LPC_GPIO2->FIOCLR = (1 << 4);
01501         // read DSO bit (port 2, bit 1) ( -- OLD CONNECTION WAS to PIN 27 -- port 2, bit 11)
01502         *bdm_response_bit_alias = bitAlias(LPC_GPIO2->FIOPIN,1);
01503         // introduce a delay to insure that BDM clock isn't too fast
01504         for (uint8_t c = 2; c; c--);        // was 2
01505         // rising edge on BKPT/DSCLK
01506         LPC_GPIO2->FIOSET = (1 << 4);
01507         // point to the next bit (pointer will be decremented by sizeof pointer)
01508         bdm_response_bit_alias--;
01509         // introduce a delay to insure that BDM clock isn't too fast
01510         for (uint8_t c = 7; c; c--);        // was 2
01511     }
01512     //Make DSI an input
01513     LPC_GPIO2->FIODIR &= ~(1 << 2);
01514 }
01515 //-----------------------------------------------------------------------------
01516 
01517 /**
01518     Writes a word to target MCU via BDM line and gets the response.
01519     
01520     This 'nitrous' version uses is the same as the 'turbo' version but
01521     without minimal delays and will only work with the faster CPU in T8
01522     once the ECU has been 'prepped'
01523 
01524     @param            value            value to write
01525     @param            num_bits        value size, bits
01526 */
01527 
01528 void bdm_clk_nitrous(uint16_t value, uint8_t num_bits)
01529 {
01530     //Make DSI an output
01531     LPC_GPIO2->FIODIR |= (1 << 2);
01532     bdm_response = (uint32_t)value;
01533     // calculate a pointer to the bitband alias region address of the most significant bit of the BDM word (NOTE num_bits-1) 
01534     uint32_t *bdm_response_bit_alias = &bitAlias(bdm_response,num_bits-1);
01535     // Clock BDM Data in from DSO and out to DSI
01536     while (num_bits--) {
01537         // set DSI bit (port 2, bit 2)
01538         bitAlias(LPC_GPIO2->FIOPIN,2) = *bdm_response_bit_alias;
01539         // falling edge on BKPT/DSCLK
01540         LPC_GPIO2->FIOCLR = (1 << 4);
01541         // read DSO bit (port 2, bit 1) ( -- OLD CONNECTION WAS to PIN 27 -- port 2, bit 11)
01542         *bdm_response_bit_alias = bitAlias(LPC_GPIO2->FIOPIN,1);
01543         // introduce a delay to insure that BDM clock isn't too fast
01544         //for (uint8_t c = 2; c; c--);
01545         // rising edge on BKPT/DSCLK
01546         LPC_GPIO2->FIOSET = (1 << 4);
01547         // point to the next bit (pointer will be decremented by sizeof pointer)
01548         bdm_response_bit_alias--;
01549         // introduce a delay to insure that BDM clock isn't too fast
01550         for (uint8_t c = 1; c; c--);
01551     }
01552     //Make DSI an input
01553     LPC_GPIO2->FIODIR &= ~(1 << 2);
01554 }
01555 //-----------------------------------------------------------------------------
01556 
01557 /**
01558     Clears the BDM interface after errors.
01559 */
01560 void bdm_clear()
01561 {
01562     bdm_clk (BDM_NOP, CMD_BIT_COUNT);
01563     bdm_clk (BDM_NOP, CMD_BIT_COUNT);
01564     bdm_clk (BDM_NOP, CMD_BIT_COUNT);
01565     bdm_clk (BDM_NOP, CMD_BIT_COUNT);
01566 
01567     while (bdm_response > 0) {
01568         bdm_clk(0, 1);
01569     }
01570     while (bdm_response < 1) {
01571         bdm_clk(0, 1);
01572     }
01573     bdm_clk(0, 15);
01574 }
01575 
01576 //-----------------------------------------------------------------------------
01577 //    EOF
01578 //-----------------------------------------------------------------------------