This is an automated email from Gerrit. "Dan Stahlke <d...@stahlke.org>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7391
-- gerrit commit 3894c5c3f9896f513029b78a224f98ddd173e3f6 Author: Dan Stahlke <d...@stahlke.org> Date: Sun Dec 4 18:12:16 2022 -0800 at91samd: wait for nvm ready Flashing a SAMD21J17D was failing during NVM erase. The samd21 datasheet specifies that one cause of error conditions is executing an NVM command while the previous command is still running. The solution is to wait for INTFLAG.READY after a command is issued. SAMD21J17A was not exhibiting this problem. Perhaps the later silicon revision has slower NVM erase times. Signed-off-by: Dan Stahlke <d...@stahlke.org> Change-Id: I19745dae4d3fc6e3a7611dcac628e067cb41e0f0 diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c index f213444d1f..23b1eacb0a 100644 --- a/src/flash/nor/at91samd.c +++ b/src/flash/nor/at91samd.c @@ -12,6 +12,7 @@ #include "imp.h" #include "helper/binarybuffer.h" +#include <helper/time_support.h> #include <jtag/jtag.h> #include <target/cortex_m.h> @@ -31,7 +32,7 @@ #define SAMD_NVMCTRL_CTRLA 0x00 /* NVM control A register */ #define SAMD_NVMCTRL_CTRLB 0x04 /* NVM control B register */ #define SAMD_NVMCTRL_PARAM 0x08 /* NVM parameters register */ -#define SAMD_NVMCTRL_INTFLAG 0x18 /* NVM Interrupt Flag Status & Clear */ +#define SAMD_NVMCTRL_INTFLAG 0x14 /* NVM Interrupt Flag Status & Clear */ #define SAMD_NVMCTRL_STATUS 0x18 /* NVM status register */ #define SAMD_NVMCTRL_ADDR 0x1C /* NVM address register */ #define SAMD_NVMCTRL_LOCK 0x20 /* NVM Lock section register */ @@ -497,7 +498,27 @@ static int samd_probe(struct flash_bank *bank) static int samd_check_error(struct target *target) { int ret, ret2; + uint8_t intflag; uint16_t status; + int timeout_ms = 1000; + int64_t ts_start = timeval_ms(); + + do { + ret = target_read_u8(target, + SAMD_NVMCTRL + SAMD_NVMCTRL_INTFLAG, &intflag); + if (ret != ERROR_OK) { + LOG_ERROR("Can't read NVM intflag"); + return ret; + } + if(intflag & 1) // READY + break; + keep_alive(); + } while (timeval_ms() - ts_start < timeout_ms); + + if (!(intflag & 1)) { + LOG_ERROR("SAMD: NVM programming timed out"); + ret = ERROR_FLASH_OPERATION_FAILED; + } ret = target_read_u16(target, SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, &status); --