diff options
author | Michael Hope <mlhx@google.com> | 2020-05-29 22:30:44 +0200 |
---|---|---|
committer | Tomas Vanek <vanekt@fbl.cz> | 2020-07-07 05:18:14 +0100 |
commit | a2e6982a1816a0229bd5644156f3025a0e8cb6ce (patch) | |
tree | e7759b777e5d9cef520561d5e4aa0d2ed2916664 | |
parent | 7c88e76a76588fa0e3ab645adfc46e8baff6a3e4 (diff) | |
download | openocd-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.c | 22 |
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) |