aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Hope <mlhx@google.com>2020-05-29 22:30:44 +0200
committerTomas Vanek <vanekt@fbl.cz>2020-07-07 05:18:14 +0100
commita2e6982a1816a0229bd5644156f3025a0e8cb6ce (patch)
treee7759b777e5d9cef520561d5e4aa0d2ed2916664
parent7c88e76a76588fa0e3ab645adfc46e8baff6a3e4 (diff)
downloadopenocd-jz4730-a2e6982a1816a0229bd5644156f3025a0e8cb6ce.tar.gz
flash/nor/atsame5: Fix a timeout when erasing
According to the datasheet, erasing a block can take up to 200 ms. When using a Segger J-Link with a 2 MHz clock the current loop finishes after < 50 ms, ignores the timeout, and then fails when erasing the next block. Switch to a time based check, add an explicit yield, and report an error on timeout. Change-Id: I8255401d1e59f427a08d2cccb8a66143dcdbb324 Signed-off-by: Michael Hope <mlhx@google.com> Reviewed-on: http://openocd.zylin.com/5706 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
-rw-r--r--src/flash/nor/atsame5.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/flash/nor/atsame5.c b/src/flash/nor/atsame5.c
index eac7847dc..baa86acd0 100644
--- a/src/flash/nor/atsame5.c
+++ b/src/flash/nor/atsame5.c
@@ -27,6 +27,7 @@
#include "imp.h"
#include "helper/binarybuffer.h"
+#include <helper/time_support.h>
#include <target/cortex_m.h>
/* A note to prefixing.
@@ -338,19 +339,28 @@ static int same5_probe(struct flash_bank *bank)
static int same5_wait_and_check_error(struct target *target)
{
int ret, ret2;
- int rep_cnt = 100;
+ /* Table 54-40 lists the maximum erase block time as 200 ms.
+ * Include some margin.
+ */
+ int timeout_ms = 200 * 5;
+ int64_t ts_start = timeval_ms();
uint16_t intflag;
do {
ret = target_read_u16(target,
SAMD_NVMCTRL + SAME5_NVMCTRL_INTFLAG, &intflag);
- if (ret == ERROR_OK && intflag & SAME5_NVMCTRL_INTFLAG_DONE)
+ if (ret != ERROR_OK) {
+ LOG_ERROR("SAM: error reading the NVMCTRL_INTFLAG register");
+ return ret;
+ }
+ if (intflag & SAME5_NVMCTRL_INTFLAG_DONE)
break;
- } while (--rep_cnt);
+ keep_alive();
+ } while (timeval_ms() - ts_start < timeout_ms);
- if (ret != ERROR_OK) {
- LOG_ERROR("Can't read NVM INTFLAG");
- return ret;
+ if (!(intflag & SAME5_NVMCTRL_INTFLAG_DONE)) {
+ LOG_ERROR("SAM: NVM programming timed out");
+ ret = ERROR_FLASH_OPERATION_FAILED;
}
#if 0
if (intflag & SAME5_NVMCTRL_INTFLAG_ECCSE)