+ LOG_WARNING("using fast async flash loader. This is currently supported");
+ LOG_WARNING("only with ST-Link and CMSIS-DAP. If you have issues, add");
+ LOG_WARNING("\"set WORKAREASIZE 0\" before sourcing nrf51.cfg to disable it");
+
+ retval = target_write_buffer(target, write_algorithm->address,
+ sizeof(nrf51_flash_write_code),
+ nrf51_flash_write_code);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* memory buffer */
+ while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
+ buffer_size /= 2;
+ buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */
+ if (buffer_size <= 256) {
+ /* free working area, write algorithm already allocated */
+ target_free_working_area(target, write_algorithm);
+
+ LOG_WARNING("No large enough working area available, can't do block memory writes");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ }
+
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARM_MODE_THREAD;
+
+ init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* byte count */
+ init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer start */
+ init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* buffer end */
+ init_reg_param(®_params[3], "r3", 32, PARAM_IN_OUT); /* target 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);
+
+ retval = target_run_flash_async_algorithm(target, buffer, bytes/4, 4,
+ 0, NULL,
+ 4, reg_params,
+ source->address, source->size,
+ write_algorithm->address, 0,
+ &armv7m_info);
+
+ target_free_working_area(target, source);
+ target_free_working_area(target, write_algorithm);
+
+ destroy_reg_param(®_params[0]);
+ destroy_reg_param(®_params[1]);
+ destroy_reg_param(®_params[2]);
+ destroy_reg_param(®_params[3]);
+
+ return retval;