summaryrefslogtreecommitdiff
path: root/board/atmel
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2007-04-19 10:10:11 +0200
committerHaavard Skinnemoen <hskinnemoen@atmel.com>2008-02-05 12:14:27 +0100
commit61151cccb660cdb06a07fb283de6089913d7bde0 (patch)
tree3b40500415bbb4203dc9316f01aef1a000e58c08 /board/atmel
parentb2e1d5b64469f10dfcce27f7b0afd935684a8e11 (diff)
ATSTK1000: Fix potential flash programming bug
The (now obsolete) atngw100 flash programming code was having problems programming the onboard at49bv642 chip. The atstk1000 flash programming code may have the same bug, so import fix for this problem from the AVR32 Linux BSP. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Diffstat (limited to 'board/atmel')
-rw-r--r--board/atmel/atstk1000/flash.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/board/atmel/atstk1000/flash.c b/board/atmel/atstk1000/flash.c
index 93d790f17..40478258e 100644
--- a/board/atmel/atstk1000/flash.c
+++ b/board/atmel/atstk1000/flash.c
@@ -159,7 +159,7 @@ int __flashprog write_buff(flash_info_t *info, uchar *src,
{
unsigned long flags;
uint16_t *base, *p, *s, *end;
- uint16_t word, status;
+ uint16_t word, status, status1;
int ret = ERR_OK;
if (addr < info->start[0]
@@ -194,20 +194,33 @@ int __flashprog write_buff(flash_info_t *info, uchar *src,
sync_write_buffer();
/* Wait for completion */
+ status1 = readw(p);
do {
/* TODO: Timeout */
- status = readw(p);
- } while ((status != word) && !(status & 0x28));
+ status = status1;
+ status1 = readw(p);
+ } while (((status ^ status1) & 0x40) /* toggled */
+ && !(status1 & 0x28)); /* error bits */
- writew(0xf0, base);
- readw(base);
-
- if (status != word) {
- printf("Flash write error at address 0x%p: 0x%02x\n",
- p, status);
+ /*
+ * We'll need to check once again for toggle bit
+ * because the toggle bit may stop toggling as I/O5
+ * changes to "1" (ref at49bv642.pdf p9)
+ */
+ status1 = readw(p);
+ status = readw(p);
+ if ((status ^ status1) & 0x40) {
+ printf("Flash write error at address 0x%p: "
+ "0x%02x != 0x%02x\n",
+ p, status,word);
ret = ERR_PROG_ERROR;
+ writew(0xf0, base);
+ readw(base);
break;
}
+
+ writew(0xf0, base);
+ readw(base);
}
if (flags)