Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
swd_host_ca.c
00001 /** 00002 * @file swd_host.c 00003 * @brief Implementation of swd_host.h 00004 * 00005 * DAPLink Interface Firmware 00006 * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved 00007 * Copyright 2019, Cypress Semiconductor Corporation 00008 * or a subsidiary of Cypress Semiconductor Corporation. 00009 * SPDX-License-Identifier: Apache-2.0 00010 * 00011 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00012 * not use this file except in compliance with the License. 00013 * You may obtain a copy of the License at 00014 * 00015 * http://www.apache.org/licenses/LICENSE-2.0 00016 * 00017 * Unless required by applicable law or agreed to in writing, software 00018 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00019 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 * See the License for the specific language governing permissions and 00021 * limitations under the License. 00022 */ 00023 00024 #ifdef TARGET_MCU_CORTEX_A 00025 00026 #include "cmsis_os2.h" 00027 #include "target_config.h" 00028 #include "swd_host.h" 00029 #include "debug_ca.h" 00030 #include "DAP_config.h" 00031 #include "DAP.h" 00032 #include "target_family.h" 00033 00034 // Default NVIC and Core debug base addresses 00035 // TODO: Read these addresses from ROM. 00036 #define NVIC_Addr (0xe000e000) 00037 #define DBG_Addr (0xe000edf0) 00038 00039 // AP CSW register, base value 00040 #define CSW_VALUE (0x80000000 | CSW_RESERVED | CSW_MSTRDBG | CSW_HPROT | CSW_DBGSTAT | CSW_PADDRINC) 00041 00042 // SWD register access 00043 #define SWD_REG_AP (1) 00044 #define SWD_REG_DP (0) 00045 #define SWD_REG_R (1<<1) 00046 #define SWD_REG_W (0<<1) 00047 #define SWD_REG_ADR(a) (a & 0x0c) 00048 00049 #define CMD_MRC (0xEE100E15) /* 1110 1110 0001 0000 RRRR 1110 0001 0101 */ 00050 #define CMD_MCR (0xEE000E15) /* 1110 1110 0000 0000 RRRR 1110 0001 0101 */ 00051 #define CMD_MSR (0xE12CF000) /* 1110 0001 0010 1100 1111 0000 0000 RRRR */ 00052 #define CMD_MRS (0xE14F0000) /* 1110 0001 0100 1111 RRRR 0000 0000 0000 */ 00053 #define CMD_MOV (0xE1A00000) /* 1110 0001 1010 0000 DDDD 0000 0000 RRRR */ /* D = distination */ 00054 00055 #define DBGDSCR_HALTED (0x00000001) 00056 00057 #define SELECT_MEM (0x00000000) /* setting of SELECT access memmory */ 00058 #define SELECT_DBG (0x01000000) /* setting of SELECT access Debug Register */ 00059 00060 #define MAX_SWD_RETRY 10 00061 #define MAX_TIMEOUT 100000 // Timeout for syscalls on target 00062 00063 00064 typedef struct { 00065 uint32_t select; 00066 uint32_t csw; 00067 } DAP_STATE; 00068 00069 typedef struct { 00070 uint32_t r[16]; 00071 uint32_t xpsr; 00072 } DEBUG_STATE; 00073 00074 static DAP_STATE dap_state; 00075 static uint32_t soft_reset = SYSRESETREQ; 00076 static uint32_t select_state = SELECT_MEM; 00077 static volatile uint32_t swd_init_debug_flag = 0; 00078 00079 /* Add static functions */ 00080 static uint8_t swd_restart_req(void); 00081 static uint8_t swd_enable_debug(void); 00082 00083 void swd_set_reset_connect(SWD_CONNECT_TYPE type) 00084 { 00085 } 00086 00087 void int2array(uint8_t *res, uint32_t data, uint8_t len) 00088 { 00089 uint8_t i = 0; 00090 00091 for (i = 0; i < len; i++) { 00092 res[i] = (data >> 8 * i) & 0xff; 00093 } 00094 } 00095 00096 uint8_t swd_transfer_retry(uint32_t req, uint32_t *data) 00097 { 00098 uint8_t i, ack; 00099 00100 for (i = 0; i < MAX_SWD_RETRY; i++) { 00101 ack = SWD_Transfer(req, data); 00102 00103 // if ack != WAIT 00104 if (ack != DAP_TRANSFER_WAIT) { 00105 return ack; 00106 } 00107 } 00108 00109 return ack; 00110 } 00111 00112 void swd_set_soft_reset(uint32_t soft_reset_type) 00113 { 00114 soft_reset = soft_reset_type; 00115 } 00116 00117 uint8_t swd_init(void) 00118 { 00119 //TODO - DAP_Setup puts GPIO pins in a hi-z state which can 00120 // cause problems on re-init. This needs to be investigated 00121 // and fixed. 00122 DAP_Setup(); 00123 PORT_SWD_SETUP(); 00124 return 1; 00125 } 00126 00127 uint8_t swd_off(void) 00128 { 00129 PORT_OFF(); 00130 return 1; 00131 } 00132 00133 // Read debug port register. 00134 uint8_t swd_read_dp(uint8_t adr, uint32_t *val) 00135 { 00136 uint32_t tmp_in; 00137 uint8_t tmp_out[4]; 00138 uint8_t ack; 00139 uint32_t tmp; 00140 tmp_in = SWD_REG_DP | SWD_REG_R | SWD_REG_ADR(adr); 00141 ack = swd_transfer_retry(tmp_in, (uint32_t *)tmp_out); 00142 *val = 0; 00143 tmp = tmp_out[3]; 00144 *val |= (tmp << 24); 00145 tmp = tmp_out[2]; 00146 *val |= (tmp << 16); 00147 tmp = tmp_out[1]; 00148 *val |= (tmp << 8); 00149 tmp = tmp_out[0]; 00150 *val |= (tmp << 0); 00151 return (ack == 0x01); 00152 } 00153 00154 // Write debug port register 00155 uint8_t swd_write_dp(uint8_t adr, uint32_t val) 00156 { 00157 uint32_t req; 00158 uint8_t data[4]; 00159 uint8_t ack; 00160 00161 switch (adr) { 00162 case DP_SELECT: 00163 if (dap_state.select == val) { 00164 return 1; 00165 } 00166 00167 dap_state.select = val; 00168 break; 00169 00170 default: 00171 break; 00172 } 00173 00174 req = SWD_REG_DP | SWD_REG_W | SWD_REG_ADR(adr); 00175 int2array(data, val, 4); 00176 ack = swd_transfer_retry(req, (uint32_t *)data); 00177 return (ack == 0x01); 00178 } 00179 00180 // Read access port register. 00181 uint8_t swd_read_ap(uint32_t adr, uint32_t *val) 00182 { 00183 uint8_t tmp_in, ack; 00184 uint8_t tmp_out[4]; 00185 uint32_t tmp; 00186 uint32_t apsel = adr & 0xff000000; 00187 uint32_t bank_sel = adr & APBANKSEL; 00188 00189 if (!swd_write_dp(DP_SELECT, apsel | bank_sel)) { 00190 return 0; 00191 } 00192 00193 tmp_in = SWD_REG_AP | SWD_REG_R | SWD_REG_ADR(adr); 00194 // first dummy read 00195 swd_transfer_retry(tmp_in, (uint32_t *)tmp_out); 00196 ack = swd_transfer_retry(tmp_in, (uint32_t *)tmp_out); 00197 *val = 0; 00198 tmp = tmp_out[3]; 00199 *val |= (tmp << 24); 00200 tmp = tmp_out[2]; 00201 *val |= (tmp << 16); 00202 tmp = tmp_out[1]; 00203 *val |= (tmp << 8); 00204 tmp = tmp_out[0]; 00205 *val |= (tmp << 0); 00206 return (ack == 0x01); 00207 } 00208 00209 // Write access port register 00210 uint8_t swd_write_ap(uint32_t adr, uint32_t val) 00211 { 00212 uint8_t data[4]; 00213 uint8_t req, ack; 00214 uint32_t apsel = adr & 0xff000000; 00215 uint32_t bank_sel = adr & APBANKSEL; 00216 00217 if (!swd_write_dp(DP_SELECT, apsel | bank_sel)) { 00218 return 0; 00219 } 00220 00221 switch (adr) { 00222 case AP_CSW: 00223 if (dap_state.csw == val) { 00224 return 1; 00225 } 00226 00227 dap_state.csw = val; 00228 break; 00229 00230 default: 00231 break; 00232 } 00233 00234 req = SWD_REG_AP | SWD_REG_W | SWD_REG_ADR(adr); 00235 int2array(data, val, 4); 00236 00237 if (swd_transfer_retry(req, (uint32_t *)data) != 0x01) { 00238 return 0; 00239 } 00240 00241 req = SWD_REG_DP | SWD_REG_R | SWD_REG_ADR(DP_RDBUFF); 00242 ack = swd_transfer_retry(req, NULL); 00243 return (ack == 0x01); 00244 } 00245 00246 uint8_t swd_ca_select_state(uint32_t addr) { 00247 uint8_t tmp_in[4]; 00248 uint32_t work_select_state; 00249 00250 if ((DEBUG_REGSITER_BASE <= addr) && (addr <= DBGCID3)) { 00251 work_select_state = SELECT_DBG; 00252 } else { 00253 work_select_state = SELECT_MEM; 00254 } 00255 if (select_state != work_select_state) { 00256 // SELECT 00257 select_state = work_select_state; 00258 int2array(tmp_in, select_state, 4); 00259 if (swd_transfer_retry(0x08, (uint32_t *)tmp_in) != 0x01) { 00260 return 0; 00261 } 00262 } 00263 return 1; 00264 } 00265 00266 00267 // Write 32-bit word aligned values to target memory using address auto-increment. 00268 // size is in bytes. 00269 static uint8_t swd_write_block(uint32_t address, uint8_t *data, uint32_t size) 00270 { 00271 uint8_t tmp_in[4], req; 00272 uint32_t size_in_words; 00273 uint32_t i, ack = 0x01; 00274 uint32_t *work_write_data; 00275 00276 if (size == 0) { 00277 return 0; 00278 } 00279 00280 size_in_words = size / 4; 00281 00282 // CSW register 00283 if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32)) { 00284 return 0; 00285 } 00286 00287 if (swd_ca_select_state(address) == 0) { 00288 return 0; 00289 } 00290 00291 // TAR write 00292 req = SWD_REG_AP | SWD_REG_W | (1 << 2); 00293 int2array(tmp_in, address, 4); 00294 00295 if (swd_transfer_retry(req, (uint32_t *)tmp_in) != 0x01) { 00296 return 0; 00297 } 00298 00299 // DRW write 00300 req = SWD_REG_AP | SWD_REG_W | (3 << 2); 00301 work_write_data = (uint32_t *)data; 00302 for (i = 0; i < size_in_words; i++) { 00303 int2array(tmp_in, *work_write_data, 4); 00304 ack = swd_transfer_retry(req, (uint32_t *)tmp_in); 00305 if (ack != 0x01) { 00306 return 0; 00307 } 00308 work_write_data++; 00309 } 00310 return (ack == 0x01); 00311 } 00312 00313 // Read target memory. 00314 static uint8_t swd_read_data(uint32_t addr, uint32_t *val) 00315 { 00316 uint8_t tmp_in[4]; 00317 uint8_t tmp_out[4]; 00318 uint8_t req, ack; 00319 uint32_t tmp; 00320 00321 if (swd_ca_select_state(addr) == 0) { 00322 return 0; 00323 } 00324 00325 // put addr in TAR register 00326 int2array(tmp_in, addr, 4); 00327 req = SWD_REG_AP | SWD_REG_W | (1 << 2); 00328 00329 if (swd_transfer_retry(req, (uint32_t *)tmp_in) != 0x01) { 00330 return 0; 00331 } 00332 00333 // read data 00334 req = SWD_REG_AP | SWD_REG_R | (3 << 2); 00335 00336 if (swd_transfer_retry(req, (uint32_t *)tmp_out) != 0x01) { 00337 return 0; 00338 } 00339 00340 // dummy read 00341 req = SWD_REG_DP | SWD_REG_R | SWD_REG_ADR(DP_RDBUFF); 00342 ack = swd_transfer_retry(req, (uint32_t *)tmp_out); 00343 *val = 0; 00344 tmp = tmp_out[3]; 00345 *val |= (tmp << 24); 00346 tmp = tmp_out[2]; 00347 *val |= (tmp << 16); 00348 tmp = tmp_out[1]; 00349 *val |= (tmp << 8); 00350 tmp = tmp_out[0]; 00351 *val |= (tmp << 0); 00352 return (ack == 0x01); 00353 } 00354 00355 // Write target memory. 00356 static uint8_t swd_write_data(uint32_t address, uint32_t data) 00357 { 00358 uint8_t tmp_in[4]; 00359 uint8_t req, ack; 00360 00361 if (swd_ca_select_state(address) == 0) { 00362 return 0; 00363 } 00364 00365 // put addr in TAR register 00366 int2array(tmp_in, address, 4); 00367 req = SWD_REG_AP | SWD_REG_W | (1 << 2); 00368 00369 if (swd_transfer_retry(req, (uint32_t *)tmp_in) != 0x01) { 00370 return 0; 00371 } 00372 00373 // write data 00374 int2array(tmp_in, data, 4); 00375 req = SWD_REG_AP | SWD_REG_W | (3 << 2); 00376 ack = swd_transfer_retry(req, (uint32_t *)tmp_in); 00377 00378 return (ack == 0x01) ? 1 : 0; 00379 } 00380 00381 // Read 32-bit word from target memory. 00382 uint8_t swd_read_word(uint32_t addr, uint32_t *val) 00383 { 00384 if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32)) { 00385 return 0; 00386 } 00387 00388 if (!swd_read_data(addr, val)) { 00389 return 0; 00390 } 00391 00392 return 1; 00393 } 00394 00395 // Write 32-bit word to target memory. 00396 uint8_t swd_write_word(uint32_t addr, uint32_t val) 00397 { 00398 if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32)) { 00399 return 0; 00400 } 00401 00402 if (!swd_write_data(addr, val)) { 00403 return 0; 00404 } 00405 00406 return 1; 00407 } 00408 00409 // Read unaligned data from target memory. 00410 // size is in bytes. 00411 uint8_t swd_read_memory(uint32_t address, uint8_t *data, uint32_t size) 00412 { 00413 uint32_t read_size; 00414 uint32_t* read_data; 00415 00416 read_size = (size / 4); 00417 read_data = (uint32_t*)data; 00418 /* Write bytes until end */ 00419 while ((read_size > 0)) { 00420 if (!swd_read_data(address, read_data)) { 00421 return 0; 00422 } 00423 address+=4; 00424 read_data++; 00425 read_size--; 00426 } 00427 00428 return 1; 00429 } 00430 00431 // Write unaligned data to target memory. 00432 // size is in bytes. 00433 uint8_t swd_write_memory(uint32_t address, uint8_t *data, uint32_t size) 00434 { 00435 uint32_t n; 00436 00437 while (size > 3) { 00438 // Limit to auto increment page size 00439 n = TARGET_AUTO_INCREMENT_PAGE_SIZE - (address & (TARGET_AUTO_INCREMENT_PAGE_SIZE - 1)); 00440 if (size < n) { 00441 n = size & 0xFFFFFFFC; // Only count complete words remaining 00442 } 00443 00444 if (!swd_write_block(address, data, n)) { 00445 return 0; 00446 } 00447 00448 address += n; 00449 data += n; 00450 size -= n; 00451 } 00452 /* Auto increment is end */ 00453 /* Return the CSW reg value to SIZE8 */ 00454 if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE8)) { 00455 return 0; 00456 } 00457 00458 return 1; 00459 } 00460 00461 // Execute system call. 00462 static uint8_t swd_write_debug_state(DEBUG_STATE *state) 00463 { 00464 uint32_t i, status; 00465 00466 if (!swd_write_dp(DP_SELECT, 0)) { 00467 return 0; 00468 } 00469 00470 // R0, R1, R2, R3 00471 for (i = 0; i < 4; i++) { 00472 if (!swd_write_core_register(i, state->r[i])) { 00473 return 0; 00474 } 00475 } 00476 00477 // R9 00478 if (!swd_write_core_register(9, state->r[9])) { 00479 return 0; 00480 } 00481 00482 // R13, R14 00483 for (i = 13; i < 15; i++) { 00484 if (!swd_write_core_register(i, state->r[i])) { 00485 return 0; 00486 } 00487 } 00488 00489 // xPSR 00490 /* xPSR write */ 00491 /* write PSR (write r6) */ 00492 if (!swd_write_core_register(6, state->xpsr)) { 00493 return 0; 00494 } 00495 /* MSR (PSR <- r6) */ 00496 if (!swd_write_word(DBGITR, CMD_MSR | (6))) { 00497 return 0; 00498 } 00499 00500 /* R15(PC) */ 00501 /* MRC R7 */ 00502 if (!swd_write_core_register(7, state->r[15])) { 00503 return 0; 00504 } 00505 /* MOV R15, R7 */ 00506 if (!swd_write_word(DBGITR, CMD_MOV | (15 << 12) | (7))) { 00507 return 0; 00508 } 00509 if (!swd_restart_req()) { 00510 return 0; 00511 } 00512 00513 // check status 00514 if (!swd_read_dp(DP_CTRL_STAT, &status)) { 00515 return 0; 00516 } 00517 00518 if (status & (STICKYERR | WDATAERR)) { 00519 return 0; 00520 } 00521 00522 return 1; 00523 } 00524 00525 static uint8_t swd_restart_req(void) { 00526 uint32_t val, i, timeout = MAX_TIMEOUT; 00527 /* Clear ITRen */ 00528 if (!swd_read_word(DBGDSCR, &val)) { 00529 return 0; 00530 } 00531 val = val & ~0x00002000; 00532 if (!swd_write_word(DBGDSCR, val)) { 00533 return 0; 00534 } 00535 for (i = 0; i < timeout; i++) { 00536 /* read DBGDSCR */ 00537 if (!swd_read_word(DBGDSCR, &val)) { 00538 return 0; 00539 } 00540 /* wait Clear UND_I, ADABORT_I, SDABORT_I[bit:8-6] and InstrCompl_I[bit24] set to 1 */ 00541 if ((val & 0x010001C0) == 0x01000000) { 00542 break; 00543 } else if (i == (timeout -1)) { 00544 return 0; 00545 } 00546 } 00547 /* DBGDRCR Restart req */ 00548 if (!swd_write_word(DBGDRCR, 0x00000002 )) { 00549 return 0; 00550 } 00551 for (i = 0; i < timeout; i++) { 00552 /* read DBGDSCR */ 00553 if (!swd_read_word(DBGDSCR, &val)) { 00554 return 0; 00555 } 00556 if ((val & 0x00000002) == 0x00000002) { 00557 /* restarted */ 00558 return 1; 00559 } 00560 } 00561 return 0; 00562 } 00563 00564 static uint8_t swd_enable_debug(void) { 00565 uint32_t val; 00566 if (!swd_read_word(DBGDSCR, &val)) { 00567 return 0; 00568 } 00569 /* DBGDSCR ITRen = 1(ARM instruction enable) */ 00570 /* and ExtDCCmode = 01(stall mode) */ 00571 val = val | 0x00106000; 00572 if (!swd_write_word(DBGDSCR, val)) { 00573 return 0; 00574 } 00575 return 1; 00576 } 00577 00578 uint8_t swd_read_core_register(uint32_t n, uint32_t *val) 00579 { 00580 if (!swd_write_word(DBGITR, CMD_MCR | (n << 12))) { 00581 return 0; 00582 } 00583 00584 if (!swd_read_word(DBGDTRTX, val)){ 00585 return 0; 00586 } 00587 00588 return 1; 00589 } 00590 00591 uint8_t swd_write_core_register(uint32_t n, uint32_t val) 00592 { 00593 if (!swd_write_word(DBGDTRRX, val)){ 00594 return 0; 00595 } 00596 00597 /* Write MRC */ 00598 if (!swd_write_word(DBGITR, (CMD_MRC | (n << 12)))) { 00599 return 0; 00600 } 00601 00602 return 1; 00603 } 00604 00605 static uint8_t swd_wait_until_halted(void) 00606 { 00607 uint32_t val, i, timeout = MAX_TIMEOUT; 00608 for (i = 0; i < timeout; i++) { 00609 /* read DBGDSCR */ 00610 if (!swd_read_word(DBGDSCR, &val)) { 00611 return 0; 00612 } 00613 00614 if ((val & DBGDSCR_HALTED) == DBGDSCR_HALTED) { 00615 return 1; 00616 } 00617 osDelay(1); 00618 } 00619 00620 return 0; 00621 } 00622 00623 uint8_t swd_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, flash_algo_return_t return_type) 00624 { 00625 DEBUG_STATE state = {{0}, 0}; 00626 // Call flash algorithm function on target and wait for result. 00627 state.r[0] = arg1; // R0: Argument 1 00628 state.r[1] = arg2; // R1: Argument 2 00629 state.r[2] = arg3; // R2: Argument 3 00630 state.r[3] = arg4; // R3: Argument 4 00631 state.r[9] = sysCallParam->static_base; // SB: Static Base 00632 state.r[13] = sysCallParam->stack_pointer; // SP: Stack Pointer 00633 state.r[14] = sysCallParam->breakpoint; // LR: Exit Point 00634 state.r[15] = entry; // PC: Entry Point 00635 state.xpsr = 0x00000000; // xPSR: T = 1, ISR = 0 00636 00637 if (!swd_write_debug_state(&state)) { 00638 return 0; 00639 } 00640 00641 if (!swd_wait_until_halted()) { 00642 return 0; 00643 } 00644 00645 if (!swd_enable_debug()) { 00646 return 0; 00647 } 00648 00649 if (!swd_read_core_register(0, &state.r[0])) { 00650 return 0; 00651 } 00652 00653 if ( return_type == FLASHALGO_RETURN_POINTER ) { 00654 // Flash verify functions return pointer to byte following the buffer if successful. 00655 if (state.r[0] != (arg1 + arg2)) { 00656 return 0; 00657 } 00658 } 00659 else { 00660 // Flash functions return 0 if successful. 00661 if (state.r[0] != 0) { 00662 return 0; 00663 } 00664 } 00665 00666 return 1; 00667 } 00668 00669 // SWD Reset 00670 static uint8_t swd_reset(void) 00671 { 00672 uint8_t tmp_in[8]; 00673 uint8_t i = 0; 00674 00675 for (i = 0; i < 8; i++) { 00676 tmp_in[i] = 0xff; 00677 } 00678 00679 SWJ_Sequence(51, tmp_in); 00680 return 1; 00681 } 00682 00683 // SWD Switch 00684 static uint8_t swd_switch(uint16_t val) 00685 { 00686 uint8_t tmp_in[2]; 00687 tmp_in[0] = val & 0xff; 00688 tmp_in[1] = (val >> 8) & 0xff; 00689 SWJ_Sequence(16, tmp_in); 00690 return 1; 00691 } 00692 00693 // SWD Read ID 00694 static uint8_t swd_read_idcode(uint32_t *id) 00695 { 00696 uint8_t tmp_in[1]; 00697 uint8_t tmp_out[4]; 00698 tmp_in[0] = 0x00; 00699 SWJ_Sequence(8, tmp_in); 00700 00701 if (swd_read_dp(0, (uint32_t *)tmp_out) != 0x01) { 00702 return 0; 00703 } 00704 00705 *id = (tmp_out[3] << 24) | (tmp_out[2] << 16) | (tmp_out[1] << 8) | tmp_out[0]; 00706 return 1; 00707 } 00708 00709 00710 uint8_t JTAG2SWD() 00711 { 00712 uint32_t tmp = 0; 00713 00714 if (!swd_reset()) { 00715 return 0; 00716 } 00717 00718 if (!swd_switch(0xE79E)) { 00719 return 0; 00720 } 00721 00722 if (!swd_reset()) { 00723 return 0; 00724 } 00725 00726 if (!swd_read_idcode(&tmp)) { 00727 return 0; 00728 } 00729 00730 return 1; 00731 } 00732 00733 uint8_t swd_init_debug(void) 00734 { 00735 uint32_t tmp = 0; 00736 00737 if (swd_init_debug_flag != 0) { 00738 return 1; 00739 } 00740 swd_init_debug_flag = 1; 00741 00742 // init dap state with fake values 00743 dap_state.select = 0xffffffff; 00744 dap_state.csw = 0xffffffff; 00745 swd_init(); 00746 // call a target dependant function 00747 // this function can do several stuff before really 00748 // initing the debug 00749 if (g_target_family && g_target_family->target_before_init_debug ) { 00750 g_target_family->target_before_init_debug (); 00751 } 00752 00753 if (!JTAG2SWD()) { 00754 return 0; 00755 } 00756 00757 if (!swd_write_dp(DP_ABORT, STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR)) { 00758 return 0; 00759 } 00760 00761 // Ensure CTRL/STAT register selected in DPBANKSEL 00762 if (!swd_write_dp(DP_SELECT, 0)) { 00763 return 0; 00764 } 00765 00766 // Power up 00767 if (!swd_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ)) { 00768 return 0; 00769 } 00770 00771 do { 00772 if (!swd_read_dp(DP_CTRL_STAT, &tmp)) { 00773 return 0; 00774 } 00775 } while ((tmp & (CDBGPWRUPACK | CSYSPWRUPACK)) != (CDBGPWRUPACK | CSYSPWRUPACK)); 00776 00777 if (!swd_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ | TRNNORMAL | MASKLANE)) { 00778 return 0; 00779 } 00780 00781 // call a target dependant function: 00782 // some target can enter in a lock state 00783 // this function can unlock these targets 00784 if (g_target_family && g_target_family->target_unlock_sequence ) { 00785 g_target_family->target_unlock_sequence (); 00786 } 00787 00788 if (!swd_write_dp(DP_SELECT, 0)) { 00789 return 0; 00790 } 00791 00792 return 1; 00793 } 00794 00795 uint8_t swd_uninit_debug(void) 00796 { 00797 return 1; 00798 } 00799 00800 uint8_t swd_set_target_state_hw(target_state_t state) 00801 { 00802 uint32_t val; 00803 swd_init(); 00804 00805 switch (state) { 00806 case RESET_HOLD: 00807 swd_set_target_reset(1); 00808 break; 00809 00810 case RESET_RUN: 00811 swd_set_target_reset(1); 00812 osDelay(2); 00813 swd_set_target_reset(0); 00814 osDelay(2); 00815 swd_off(); 00816 break; 00817 00818 case RESET_PROGRAM: 00819 swd_set_target_reset(1); 00820 osDelay(2); 00821 swd_set_target_reset(0); 00822 osDelay(2); 00823 00824 if (!swd_init_debug()) { 00825 return 0; 00826 } 00827 00828 if (!swd_enable_debug()) { 00829 return 0; 00830 } 00831 /* DBGDRCR halt req*/ 00832 val = 0x00000001; 00833 if (!swd_write_word(DBGDRCR, val )) { 00834 return 0; 00835 } 00836 osDelay(2); 00837 if (!swd_wait_until_halted()) { 00838 return 0; 00839 } 00840 00841 break; 00842 00843 case NO_DEBUG: 00844 if (!swd_write_word(DBG_HCSR, DBGKEY)) { 00845 return 0; 00846 } 00847 00848 break; 00849 00850 case DEBUG: 00851 if (!JTAG2SWD()) { 00852 return 0; 00853 } 00854 00855 if (!swd_write_dp(DP_ABORT, STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR)) { 00856 return 0; 00857 } 00858 00859 // Ensure CTRL/STAT register selected in DPBANKSEL 00860 if (!swd_write_dp(DP_SELECT, 0)) { 00861 return 0; 00862 } 00863 00864 // Power up 00865 if (!swd_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ)) { 00866 return 0; 00867 } 00868 00869 // Enable debug 00870 if (!swd_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN)) { 00871 return 0; 00872 } 00873 00874 break; 00875 00876 default: 00877 return 0; 00878 } 00879 00880 return 1; 00881 } 00882 00883 uint8_t swd_set_target_state_sw(target_state_t state) 00884 { 00885 uint32_t val; 00886 swd_init(); 00887 switch (state) { 00888 case RESET_HOLD: 00889 swd_set_target_reset(1); 00890 break; 00891 00892 case RESET_RUN: 00893 swd_set_target_reset(1); 00894 osDelay(2); 00895 swd_set_target_reset(0); 00896 osDelay(2); 00897 swd_off(); 00898 break; 00899 00900 case RESET_PROGRAM: 00901 if (!swd_init_debug()) { 00902 return 0; 00903 } 00904 00905 // Enable debug and halt the core (DHCSR <- 0xA05F0003) 00906 if (!swd_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN | C_HALT)) { 00907 return 0; 00908 } 00909 00910 // Wait until core is halted 00911 do { 00912 if (!swd_read_word(DBG_HCSR, &val)) { 00913 return 0; 00914 } 00915 } while ((val & S_HALT) == 0); 00916 00917 // Enable halt on reset 00918 if (!swd_write_word(DBG_EMCR, VC_CORERESET)) { 00919 return 0; 00920 } 00921 00922 // Perform a soft reset 00923 if (!swd_write_word(NVIC_AIRCR, VECTKEY | soft_reset)) { 00924 return 0; 00925 } 00926 00927 break; 00928 00929 case NO_DEBUG: 00930 if (!swd_write_word(DBG_HCSR, DBGKEY)) { 00931 return 0; 00932 } 00933 00934 break; 00935 00936 case DEBUG: 00937 if (!JTAG2SWD()) { 00938 return 0; 00939 } 00940 00941 if (!swd_write_dp(DP_ABORT, STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR)) { 00942 return 0; 00943 } 00944 00945 // Ensure CTRL/STAT register selected in DPBANKSEL 00946 if (!swd_write_dp(DP_SELECT, 0)) { 00947 return 0; 00948 } 00949 00950 // Power up 00951 if (!swd_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ)) { 00952 return 0; 00953 } 00954 00955 // Enable debug 00956 if (!swd_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN)) { 00957 return 0; 00958 } 00959 00960 break; 00961 00962 default: 00963 return 0; 00964 } 00965 00966 return 1; 00967 } 00968 00969 #endif
Generated on Tue Jul 12 2022 15:37:24 by
1.7.2