nrf5: Refresh the watchdog while flashing

If watchdog is enabled, there's no way we can disable it while the flashing firmware
is running. (Halt disables it, but software reset doesn't.) So let's have the flashing
firmware refresh the watchdog regularly, in case it has been enabled by previously
running software. Failure to do so could lead to a watchdog reset in the middle of
the chip bieng programmed.

Change-Id: I79d41593948aae0080480e891552e1c2ee3ccbd0
Signed-off-by: Aurélien Martin <martaurel@gmail.com>
Reviewed-on: http://openocd.zylin.com/5266
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
This commit is contained in:
Aurélien Martin 2019-07-22 23:13:29 +02:00 committed by Tomas Vanek
parent 65d8fdf0d1
commit 3c8aa12859
3 changed files with 18 additions and 4 deletions

View File

@ -27,12 +27,15 @@
* r1 = buffer start
* r2 = buffer end
* r3 = target address
* r6 = watchdog refresh value
* r7 = watchdog refresh register address
*/
.thumb_func
.global _start
_start:
wait_fifo:
str r6, [r7, #0]
ldr r5, [r1, #0]
cmp r5, #0
beq.n exit

View File

@ -1,3 +1,4 @@
/* Autogenerated with ../../../../src/helper/bin2char.sh */
0x0d,0x68,0x00,0x2d,0x0b,0xd0,0x4c,0x68,0xac,0x42,0xf9,0xd0,0x20,0xcc,0x20,0xc3,
0x94,0x42,0x01,0xd3,0x0c,0x46,0x08,0x34,0x4c,0x60,0x04,0x38,0xf0,0xd1,0x00,0xbe,
0x3e,0x60,0x0d,0x68,0x00,0x2d,0x0b,0xd0,0x4c,0x68,0xac,0x42,0xf8,0xd0,0x20,0xcc,
0x20,0xc3,0x94,0x42,0x01,0xd3,0x0c,0x46,0x08,0x34,0x4c,0x60,0x04,0x38,0xef,0xd1,
0x00,0xbe,

View File

@ -28,6 +28,10 @@
#include <helper/types.h>
#include <helper/time_support.h>
/* Both those values are constant across the current spectrum ofr nRF5 devices */
#define WATCHDOG_REFRESH_REGISTER 0x40010600
#define WATCHDOG_REFRESH_VALUE 0x6e524635
enum {
NRF5_FLASH_BASE = 0x00000000,
};
@ -907,7 +911,7 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const u
uint32_t buffer_size = 8192;
struct working_area *write_algorithm;
struct working_area *source;
struct reg_param reg_params[4];
struct reg_param reg_params[6];
struct armv7m_algorithm armv7m_info;
int retval = ERROR_OK;
@ -965,15 +969,19 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const u
init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* buffer start */
init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer end */
init_reg_param(&reg_params[3], "r3", 32, PARAM_IN_OUT); /* target address */
init_reg_param(&reg_params[4], "r6", 32, PARAM_OUT); /* watchdog refresh value */
init_reg_param(&reg_params[5], "r7", 32, PARAM_OUT); /* watchdog refresh register address */
buf_set_u32(reg_params[0].value, 0, 32, bytes);
buf_set_u32(reg_params[1].value, 0, 32, source->address);
buf_set_u32(reg_params[2].value, 0, 32, source->address + source->size);
buf_set_u32(reg_params[3].value, 0, 32, address);
buf_set_u32(reg_params[4].value, 0, 32, WATCHDOG_REFRESH_VALUE);
buf_set_u32(reg_params[5].value, 0, 32, WATCHDOG_REFRESH_REGISTER);
retval = target_run_flash_async_algorithm(target, buffer, bytes/4, 4,
0, NULL,
4, reg_params,
ARRAY_SIZE(reg_params), reg_params,
source->address, source->size,
write_algorithm->address, 0,
&armv7m_info);
@ -985,6 +993,8 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const u
destroy_reg_param(&reg_params[1]);
destroy_reg_param(&reg_params[2]);
destroy_reg_param(&reg_params[3]);
destroy_reg_param(&reg_params[4]);
destroy_reg_param(&reg_params[5]);
return retval;
}