nrf51: Fix incorrect flash writing sequence

nRF51 doesn't have any sort of flash page cache so we need to write
all of the data on the word-by-word basis and poll for "Flash Ready"
bit each time.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Change-Id: I8caffbf69ebf9a69915724704ddbe270d1bb8d92
Reviewed-on: http://openocd.zylin.com/2050
Tested-by: jenkins
Reviewed-by: Paul Fertser <fercerpav@gmail.com>
This commit is contained in:
Andrey Smirnov 2014-03-15 10:40:23 -07:00 committed by Paul Fertser
parent b9cb2027b3
commit f7ffd142ee
1 changed files with 24 additions and 8 deletions

View File

@ -600,10 +600,30 @@ static int nrf51_erase_page(struct nrf51_info *chip, struct flash_sector *sector
return res;
}
static int nrf51_ll_flash_write(struct nrf51_info *chip, uint32_t offset, const uint8_t *buffer, uint32_t buffer_size)
{
int res;
assert(buffer_size % 4 == 0);
for (; buffer_size > 0; buffer_size -= 4) {
res = target_write_memory(chip->target, offset, 4, 1, buffer);
if (res != ERROR_OK)
return res;
res = nrf51_wait_for_nvmc(chip);
if (res != ERROR_OK)
return res;
offset += 4;
buffer += 4;
}
return ERROR_OK;
}
static int nrf51_write_page(struct flash_bank *bank, uint32_t offset, const uint8_t *buffer)
{
assert(offset % 4 == 0);
int res = ERROR_FAIL;
struct nrf51_info *chip = bank->driver_priv;
struct flash_sector *sector = nrf51_find_sector_by_address(bank, offset);
@ -627,8 +647,8 @@ static int nrf51_write_page(struct flash_bank *bank, uint32_t offset, const uint
goto error;
sector->is_erased = 0;
res = target_write_memory(bank->target, offset, 4,
chip->code_page_size / 4, buffer);
res = nrf51_ll_flash_write(chip, offset, buffer, chip->code_page_size);
if (res != ERROR_OK)
goto set_read_only;
@ -768,11 +788,7 @@ static int nrf51_uicr_flash_write(struct flash_bank *bank,
memcpy(&uicr[offset], buffer, count);
res = target_write_memory(bank->target,
NRF51_UICR_BASE,
4,
NRF51_UICR_SIZE / 4,
uicr);
res = nrf51_ll_flash_write(chip, NRF51_UICR_BASE, uicr, NRF51_UICR_SIZE);
if (res != ERROR_OK) {
nrf51_nvmc_read_only(chip);
return res;