@@ -34,7 +34,7 @@ | |||
* arm-none-eabi-gcc -c cortex-m0.S | |||
* | |||
* To disassemble: | |||
* arm-none-eabi-objdump -o cortex-m0.o | |||
* arm-none-eabi-objdump -d cortex-m0.o | |||
* | |||
* Thanks to Jens Bauer for providing advice on some of the tweaks. | |||
*/ | |||
@@ -69,4 +69,12 @@ no_wrap: | |||
subs r0, #4 /* decrement byte count */ | |||
bne wait_fifo /* loop if not done */ | |||
exit: | |||
ldr r5, NRF_NVMC_READY | |||
wait_ready: | |||
ldr r4, [r5, #0] | |||
cmp r4, #1 | |||
bne wait_ready | |||
bkpt #0 | |||
.align 2 | |||
NRF_NVMC_READY: | |||
.word 0x4001e400 |
@@ -788,7 +788,12 @@ static const uint8_t nrf51_flash_write_code[] = { | |||
0x04, 0x38, /* subs r0, #4 */ | |||
0xf0, 0xd1, /* bne.n 0 <wait_fifo> */ | |||
/* <exit>: */ | |||
0x00, 0xbe /* bkpt 0x0000 */ | |||
0x02, 0x4d, | |||
0x2c, 0x68, | |||
0x01, 0x2c, | |||
0xfc, 0xd1, | |||
0x00, 0xbe, | |||
0x00, 0xe4, 0x01, 0x40 | |||
}; | |||
@@ -400,7 +400,7 @@ static int stlink_usb_error_check(void *handle) | |||
return ERROR_FAIL; | |||
default: | |||
LOG_DEBUG("unknown/unexpected STLINK status code 0x%x", h->databuf[0]); | |||
return ERROR_FAIL; | |||
return ERROR_WAIT;//FAIL; | |||
} | |||
} | |||
@@ -1077,12 +1077,15 @@ static int stlink_usb_run(void *handle) | |||
assert(handle != NULL); | |||
printf("stlink_usb_run\n"); | |||
if (h->jtag_api == STLINK_JTAG_API_V2) { | |||
res = stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_DEBUGEN); | |||
printf("wrote DCB_DHCSR = DBGKEY|C_DEBUGEN\n"); | |||
return res; | |||
} | |||
printf("run core\n"); | |||
stlink_usb_init_buffer(handle, h->rx_ep, 2); | |||
h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; | |||
@@ -378,6 +378,7 @@ int armv7m_start_algorithm(struct target *target, | |||
for (int i = 0; i < num_mem_params; i++) { | |||
/* TODO: Write only out params */ | |||
printf("writing mem param %d\n", i); | |||
retval = target_write_buffer(target, mem_params[i].address, | |||
mem_params[i].size, | |||
mem_params[i].value); | |||
@@ -386,6 +387,8 @@ int armv7m_start_algorithm(struct target *target, | |||
} | |||
for (int i = 0; i < num_reg_params; i++) { | |||
printf("writing reg param %d\n", i); | |||
struct reg *reg = | |||
register_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, 0); | |||
/* uint32_t regvalue; */ | |||
@@ -403,6 +406,9 @@ int armv7m_start_algorithm(struct target *target, | |||
/* regvalue = buf_get_u32(reg_params[i].value, 0, 32); */ | |||
armv7m_set_core_reg(reg, reg_params[i].value); | |||
/* Check it */ | |||
} | |||
if (armv7m_algorithm_info->core_mode != ARM_MODE_ANY && | |||
@@ -424,6 +430,7 @@ int armv7m_start_algorithm(struct target *target, | |||
/* save previous core mode */ | |||
armv7m_algorithm_info->core_mode = core_mode; | |||
printf("resuming to entry point %08x\n", entry_point); | |||
retval = target_resume(target, 0, entry_point, 1, 1); | |||
return retval; | |||
@@ -689,6 +689,7 @@ void cortex_m_enable_breakpoints(struct target *target) | |||
static int cortex_m_resume(struct target *target, int current, | |||
uint32_t address, int handle_breakpoints, int debug_execution) | |||
{ | |||
printf("cortex_m resume\n"); | |||
struct armv7m_common *armv7m = target_to_armv7m(target); | |||
struct breakpoint *breakpoint = NULL; | |||
uint32_t resume_pc; | |||
@@ -596,6 +596,7 @@ static int adapter_resume(struct target *target, int current, | |||
struct breakpoint *breakpoint = NULL; | |||
struct reg *pc; | |||
printf("adapter resume\n"); | |||
LOG_DEBUG("%s %d 0x%08" PRIx32 " %d %d", __func__, current, address, | |||
handle_breakpoints, debug_execution); | |||
@@ -629,12 +630,16 @@ static int adapter_resume(struct target *target, int current, | |||
if (res != ERROR_OK) | |||
return res; | |||
printf("---restoring context---\n"); | |||
armv7m_restore_context(target); | |||
printf("---restoring context done---\n"); | |||
/* restore savedDCRDR */ | |||
printf("---restoring saved dcrdr---\n"); | |||
res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR); | |||
if (res != ERROR_OK) | |||
return res; | |||
printf("---restoring saved dcrdr done---\n"); | |||
/* registers are now invalid */ | |||
register_cache_invalidate(armv7m->arm.core_cache); | |||
@@ -658,7 +663,9 @@ static int adapter_resume(struct target *target, int current, | |||
} | |||
} | |||
printf("--- run? ---\n"); | |||
res = adapter->layout->api->run(adapter->handle); | |||
printf("--- run returned ---\n"); | |||
if (res != ERROR_OK) | |||
return res; | |||
@@ -897,6 +897,9 @@ int target_run_flash_async_algorithm(struct target *target, | |||
uint32_t fifo_start_addr = buffer_start + 8; | |||
uint32_t fifo_end_addr = buffer_start + buffer_size; | |||
printf("fifo start is %08x\n", fifo_start_addr); | |||
printf("fifo end is %08x\n", fifo_end_addr); | |||
uint32_t wp = fifo_start_addr; | |||
uint32_t rp = fifo_start_addr; | |||
@@ -924,7 +927,14 @@ int target_run_flash_async_algorithm(struct target *target, | |||
while (count > 0) { | |||
retval = target_read_u32(target, rp_addr, &rp); | |||
uint32_t tmp; | |||
target_read_u32(target, wp_addr, &tmp); | |||
printf("RAM wp=%08x\n", tmp); | |||
target_read_u32(target, rp_addr, &tmp); | |||
printf("RAM rp=%08x\n", tmp); | |||
retval = target_read_u32(target, rp_addr, &rp); | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("failed to get read pointer"); | |||
break; | |||
@@ -948,14 +958,22 @@ int target_run_flash_async_algorithm(struct target *target, | |||
* crossing the wrap around. Make sure to not fill it completely, | |||
* because that would make wp == rp and that's the empty condition. */ | |||
uint32_t thisrun_bytes; | |||
if (rp > wp) | |||
if (rp > wp) { | |||
printf("wp ----> rp-4 ... end\n"); | |||
thisrun_bytes = rp - wp - block_size; | |||
else if (rp > fifo_start_addr) | |||
} | |||
else if (rp > fifo_start_addr) { | |||
printf("rp ... wp ----> end\n"); | |||
thisrun_bytes = fifo_end_addr - wp; | |||
else | |||
} | |||
else { | |||
printf("rp ... wp ----> end-4\n"); | |||
thisrun_bytes = fifo_end_addr - wp - block_size; | |||
} | |||
printf("we can write %d bytes\n", thisrun_bytes); | |||
if (thisrun_bytes == 0) { | |||
/* Throttle polling a bit if transfer is (much) faster than flash | |||
* programming. The exact delay shouldn't matter as long as it's | |||
* less than buffer size / flash speed. This is very unlikely to | |||
@@ -964,7 +982,7 @@ int target_run_flash_async_algorithm(struct target *target, | |||
/* to stop an infinite loop on some targets check and increment a timeout | |||
* this issue was observed on a stellaris using the new ICDI interface */ | |||
if (timeout++ >= 500) { | |||
if (timeout++ >= 50) { | |||
LOG_ERROR("timeout waiting for algorithm, a target reset is recommended"); | |||
return ERROR_FLASH_OPERATION_FAILED; | |||
} | |||
@@ -977,6 +995,7 @@ int target_run_flash_async_algorithm(struct target *target, | |||
/* Limit to the amount of data we actually want to write */ | |||
if (thisrun_bytes > count * block_size) | |||
thisrun_bytes = count * block_size; | |||
printf("we'll write %d bytes\n", thisrun_bytes); | |||
/* Write data to fifo */ | |||
retval = target_write_buffer(target, wp, thisrun_bytes, buffer); | |||
@@ -987,8 +1006,10 @@ int target_run_flash_async_algorithm(struct target *target, | |||
buffer += thisrun_bytes; | |||
count -= thisrun_bytes / block_size; | |||
wp += thisrun_bytes; | |||
printf("wp was %08x... \n", wp); | |||
if (wp >= fifo_end_addr) | |||
wp = fifo_start_addr; | |||
printf("... now %08x\n", wp); | |||
/* Store updated write pointer to target */ | |||
retval = target_write_u32(target, wp_addr, wp); | |||