+ 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;
+}
+
+/* Check and erase flash sectors in specified range then start a low level page write.
+ start/end must be sector aligned.
+*/
+static int nrf51_write_pages(struct flash_bank *bank, uint32_t start, uint32_t end, const uint8_t *buffer)
+{
+ int res = ERROR_FAIL;
+ struct nrf51_info *chip = bank->driver_priv;
+ struct flash_sector *sector;
+ uint32_t offset;
+
+ assert(start % chip->code_page_size == 0);
+ assert(end % chip->code_page_size == 0);
+
+ /* Erase all sectors */
+ for (offset = start; offset < end; offset += chip->code_page_size) {
+ sector = nrf51_find_sector_by_address(bank, offset);
+ if (!sector) {
+ LOG_ERROR("Invalid sector @ 0x%08"PRIx32, offset);
+ return ERROR_FLASH_SECTOR_INVALID;
+ }
+
+ if (sector->is_protected) {
+ LOG_ERROR("Can't erase protected sector @ 0x%08"PRIx32, offset);