Sophie Dexter
/
Just4Trionic
Just4Trionic - CAN and BDM FLASH programmer for Saab cars
Embed:
(wiki syntax)
Show/hide line numbers
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 //-----------------------------------------------------------------------------
Generated on Fri Jul 15 2022 00:43:05 by 1.7.2