stlinkv2: Treat STLINK_SWD_AP_FAULT after STLINK_ERROR_WAIT as STLINK_ERROR_WAIT

cortexm_initial_halt() repeats the DHCSR write with high values for TRNCNT in
CSW. This is needed to catch a STM32F7 mostly in WFI. While the repeated write
is running, STLINKV3 on a Nucleo-WL55 (V3J7M2B0S0) answers first with
STLINK_SWD_AP_WAIT and on more read if write command is still running with
STLINK_SWD_AP_FAULT. At some point when the last command is finished, normal
STLINK_ERROR_OK indicates finally successful read. Treat STLINK_SWD_AP_FAULT
after STLINK_ERROR_WAIT as STLINK_ERROR_WAIT in that case. STLINK_SWD_AP_FAULT
may still be issued on other invalid accesses and should still be treated as
error in the other possible cases. Fixes #1071.
This commit is contained in:
Uwe Bonnes 2022-06-26 01:29:51 +02:00 committed by Rachel Mant
parent b1a02d4f48
commit 1009329882
1 changed files with 14 additions and 3 deletions

View File

@ -211,6 +211,7 @@ static int stlink_usb_get_rw_status(bool verbose);
int debug_level = 0;
#define STLINK_ERROR_DP_FAULT -2
#define STLINK_ERROR_AP_FAULT -3
/**
Converts an STLINK status code held in the first byte of a response to
@ -273,7 +274,7 @@ static int stlink_usb_error_check(uint8_t *data, bool verbose)
Stlink.ap_error = true;
if (verbose)
DEBUG_WARN("STLINK_SWD_AP_FAULT\n");
return STLINK_ERROR_DP_FAULT;
return STLINK_ERROR_AP_FAULT;
case STLINK_SWD_AP_ERROR:
if (verbose)
DEBUG_WARN("STLINK_SWD_AP_ERROR\n");
@ -331,17 +332,27 @@ static int stlink_send_recv_retry(uint8_t *txbuf, size_t txsize,
uint8_t *rxbuf, size_t rxsize)
{
uint32_t start = platform_time_ms();
int res;
int res, first_res = STLINK_ERROR_OK;
usb_link_t *link = info.usb_link;
while(1) {
send_recv(link, txbuf, txsize, rxbuf, rxsize);
res = stlink_usb_error_check(rxbuf, false);
if (res == STLINK_ERROR_OK)
return res;
if ((res == STLINK_ERROR_AP_FAULT) && (first_res == STLINK_ERROR_WAIT)) {
/* STLINKV3 while AP is busy answers once with ERROR_WAIT, then
* with AP_FAULT and finally with ERROR_OK and the pending result.
* Interpret AP_FAULT as AP_WAIT in this case.
*/
Stlink.ap_error = false;
res = STLINK_ERROR_WAIT;
}
if (first_res == STLINK_ERROR_OK)
first_res = res;
uint32_t now = platform_time_ms();
if (((now - start) > cortexm_wait_timeout) ||
(res != STLINK_ERROR_WAIT)) {
DEBUG_WARN("write_retry failed. ");
DEBUG_WARN("send_recv_retry failed. ");
return res;
}
}