aboutsummaryrefslogtreecommitdiff
path: root/src/sam3x.c
diff options
context:
space:
mode:
authorGareth McMullin2012-06-23 21:13:08 +1200
committerGareth McMullin2012-06-23 21:13:08 +1200
commitcb19164f2fa577997388963e3db32ec138b4f642 (patch)
tree8c42f753f3ee069e13184af5c16ed167e1dbe989 /src/sam3x.c
parentc09cbe8719493f8a9220fa2ac4a224eb67f520f2 (diff)
Added flash erase function for Atmel SAM3X.
Diffstat (limited to 'src/sam3x.c')
-rw-r--r--src/sam3x.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/sam3x.c b/src/sam3x.c
index 316dec6..de3d5f3 100644
--- a/src/sam3x.c
+++ b/src/sam3x.c
@@ -163,12 +163,28 @@ sam3x_flash_bank(struct target_s *target, uint32_t addr, uint32_t *offset)
static int sam3x_flash_erase(struct target_s *target, uint32_t addr, int len)
{
- /* FIXME: This device can't do sector erase. What do we do here?
- * Sector erase is done as part of write cycle in sam3x_flash_write()
+ uint32_t offset;
+ uint8_t bank = sam3x_flash_bank(target, addr, &offset);
+ unsigned chunk = offset / PAGE_SIZE;
+ uint8_t buf[PAGE_SIZE];
+
+ /* This device doesn't really have a page erase function.
+ * This Erase/Write page is the best we have, so we write with all
+ * ones. This does waste time, but what can we do?
*/
- (void)target;
- (void)addr;
- (void)len;
+
+ memset(buf, 0xff, sizeof(buf));
+ /* Only do this once, since it doesn't change. */
+ target_mem_write_words(target, addr, (void*)buf, PAGE_SIZE);
+
+ while (len) {
+ if(sam3x_flash_cmd(target, bank, EEFC_FCR_FCMD_EWP, chunk))
+ return -1;
+
+ len -= PAGE_SIZE;
+ addr += PAGE_SIZE;
+ chunk++;
+ }
return 0;
}
@@ -178,7 +194,7 @@ static int sam3x_flash_write(struct target_s *target, uint32_t dest,
{
uint32_t offset;
uint8_t bank = sam3x_flash_bank(target, dest, &offset);
- uint32_t buf[PAGE_SIZE];
+ uint8_t buf[PAGE_SIZE];
unsigned first_chunk = offset / PAGE_SIZE;
unsigned last_chunk = (offset + len - 1) / PAGE_SIZE;
offset %= PAGE_SIZE;
@@ -211,8 +227,8 @@ static int sam3x_flash_write(struct target_s *target, uint32_t dest,
src += PAGE_SIZE;
}
- target_mem_write_words(target, dest, buf, PAGE_SIZE);
- if(sam3x_flash_cmd(target, bank, EEFC_FCR_FCMD_EWP, chunk))
+ target_mem_write_words(target, dest, (void*)buf, PAGE_SIZE);
+ if(sam3x_flash_cmd(target, bank, EEFC_FCR_FCMD_WP, chunk))
return -1;
}