samd: Simplified samd_flash_write further by always using manual writes.

Tested on all three devices as listed at the top of samd.c
This commit is contained in:
Richard Meadows 2015-03-17 22:49:01 +00:00 committed by Gareth McMullin
parent 0bf7778759
commit 1366c32f89
1 changed files with 15 additions and 23 deletions

View File

@ -526,16 +526,19 @@ static int samd_flash_write(struct target_s *target, uint32_t dest,
uint32_t first_page = dest & ~(SAMD_PAGE_SIZE - 1); uint32_t first_page = dest & ~(SAMD_PAGE_SIZE - 1);
/* The start address of the last page involved in the write */ /* The start address of the last page involved in the write */
uint32_t last_page = (dest + len - 1) & ~(SAMD_PAGE_SIZE - 1); uint32_t last_page = (dest + len - 1) & ~(SAMD_PAGE_SIZE - 1);
uint32_t end_of_this_page; uint32_t next_page;
uint32_t length;
for (uint32_t page = first_page; page <= last_page; page += SAMD_PAGE_SIZE) { for (uint32_t page = first_page; page <= last_page; page += SAMD_PAGE_SIZE) {
end_of_this_page = page + (SAMD_PAGE_SIZE - 4); next_page = page + SAMD_PAGE_SIZE;
length = MINIMUM(end + 4, next_page) - addr;
if (addr > page || (page == last_page && end < end_of_this_page)) { /* Write within a single page. This may be part or all of the page */
/* Partial, manual page write */ target_mem_write(target, addr, &data[i], length);
target_mem_write(target, addr, &data[i], addr += length; i += (length >> 2);
MINIMUM(end, end_of_this_page));
/* If MANW=0 (default) we may have triggered an automatic
* write. Ignore this */
/* Unlock */ /* Unlock */
samd_unlock_current_address(target); samd_unlock_current_address(target);
@ -543,17 +546,6 @@ static int samd_flash_write(struct target_s *target, uint32_t dest,
/* Issue the write page command */ /* Issue the write page command */
target_mem_write32(target, SAMD_NVMC_CTRLA, target_mem_write32(target, SAMD_NVMC_CTRLA,
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEPAGE); SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEPAGE);
} else {
/* Write first word to set address */
target_mem_write32(target, addr, data[i]);
addr += 4; i++;
/* Unlock */
samd_unlock_current_address(target);
target_mem_write(target, addr, &data[i],
MINIMUM(end, end_of_this_page));
}
/* Poll for NVM Ready */ /* Poll for NVM Ready */
while ((target_mem_read32(target, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0) while ((target_mem_read32(target, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)