aboutsummaryrefslogtreecommitdiff
path: root/board/atmel
diff options
context:
space:
mode:
authorHaavard Skinnemoen2007-04-19 10:10:11 +0200
committerHaavard Skinnemoen2008-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 93d790f1731..40478258e7c 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)