+
+ struct reg_param reg_params[5];
+
+ init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
+ init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* count (halfword-16bit) */
+ init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* buffer start */
+ init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* buffer end */
+ init_reg_param(®_params[4], "r4", 32, PARAM_IN_OUT); /* target address */
+
+ buf_set_u32(reg_params[0].value, 0, 32, stm32x_info->register_base);
+ buf_set_u32(reg_params[1].value, 0, 32, hwords_count);
+ buf_set_u32(reg_params[2].value, 0, 32, source->address);
+ buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
+ buf_set_u32(reg_params[4].value, 0, 32, address);
+
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARM_MODE_THREAD;
+
+ retval = target_run_flash_async_algorithm(target, buffer, hwords_count, 2,
+ 0, NULL,
+ ARRAY_SIZE(reg_params), reg_params,
+ source->address, source->size,
+ write_algorithm->address, 0,
+ &armv7m_info);
+
+ if (retval == ERROR_FLASH_OPERATION_FAILED) {
+ /* Actually we just need to check for programming errors
+ * stm32x_wait_status_busy also reports error and clears status bits.
+ *
+ * Target algo returns flash status in r0 only if properly finished.
+ * It is safer to re-read status register.
+ */
+ int retval2 = stm32x_wait_status_busy(bank, 5);
+ if (retval2 != ERROR_OK)
+ retval = retval2;
+
+ LOG_ERROR("flash write failed just before address 0x%"PRIx32,
+ buf_get_u32(reg_params[4].value, 0, 32));