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:
parent
b1a02d4f48
commit
1009329882
|
@ -211,6 +211,7 @@ static int stlink_usb_get_rw_status(bool verbose);
|
||||||
int debug_level = 0;
|
int debug_level = 0;
|
||||||
|
|
||||||
#define STLINK_ERROR_DP_FAULT -2
|
#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
|
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;
|
Stlink.ap_error = true;
|
||||||
if (verbose)
|
if (verbose)
|
||||||
DEBUG_WARN("STLINK_SWD_AP_FAULT\n");
|
DEBUG_WARN("STLINK_SWD_AP_FAULT\n");
|
||||||
return STLINK_ERROR_DP_FAULT;
|
return STLINK_ERROR_AP_FAULT;
|
||||||
case STLINK_SWD_AP_ERROR:
|
case STLINK_SWD_AP_ERROR:
|
||||||
if (verbose)
|
if (verbose)
|
||||||
DEBUG_WARN("STLINK_SWD_AP_ERROR\n");
|
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)
|
uint8_t *rxbuf, size_t rxsize)
|
||||||
{
|
{
|
||||||
uint32_t start = platform_time_ms();
|
uint32_t start = platform_time_ms();
|
||||||
int res;
|
int res, first_res = STLINK_ERROR_OK;
|
||||||
usb_link_t *link = info.usb_link;
|
usb_link_t *link = info.usb_link;
|
||||||
while(1) {
|
while(1) {
|
||||||
send_recv(link, txbuf, txsize, rxbuf, rxsize);
|
send_recv(link, txbuf, txsize, rxbuf, rxsize);
|
||||||
res = stlink_usb_error_check(rxbuf, false);
|
res = stlink_usb_error_check(rxbuf, false);
|
||||||
if (res == STLINK_ERROR_OK)
|
if (res == STLINK_ERROR_OK)
|
||||||
return res;
|
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();
|
uint32_t now = platform_time_ms();
|
||||||
if (((now - start) > cortexm_wait_timeout) ||
|
if (((now - start) > cortexm_wait_timeout) ||
|
||||||
(res != STLINK_ERROR_WAIT)) {
|
(res != STLINK_ERROR_WAIT)) {
|
||||||
DEBUG_WARN("write_retry failed. ");
|
DEBUG_WARN("send_recv_retry failed. ");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue