summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-03-23 02:21:27 -0700
committerKeith Packard <keithp@keithp.com>2013-05-07 20:16:52 -0700
commitac6b4fca0970faa0a537a813242585693b839469 (patch)
treeb2efe4e120f3dded7411d505990964736bd3492a
parent35ef1f17e3efaa6d586ab7bb301f8133d52023b6 (diff)
altos: Fix STM flash programming
Wait for flash to go non-busy after writing or erasing a page and before jumping back out of the RAM code. Export a separate 'erase' operation for testing. Re-lock flash after every operation. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--src/stm/ao_flash_stm.c46
-rw-r--r--src/stm/ao_flash_stm.h3
2 files changed, 38 insertions, 11 deletions
diff --git a/src/stm/ao_flash_stm.c b/src/stm/ao_flash_stm.c
index b3ef6a62..b4d47024 100644
--- a/src/stm/ao_flash_stm.c
+++ b/src/stm/ao_flash_stm.c
@@ -39,6 +39,8 @@ ao_flash_pecr_unlock(void)
/* Unlock Data EEPROM and FLASH_PECR register */
stm_flash.pekeyr = STM_FLASH_PEKEYR_PEKEY1;
stm_flash.pekeyr = STM_FLASH_PEKEYR_PEKEY2;
+ if (ao_flash_pecr_is_locked())
+ ao_panic(AO_PANIC_FLASH);
}
static void
@@ -50,6 +52,14 @@ ao_flash_pgr_unlock(void)
/* Unlock program memory */
stm_flash.prgkeyr = STM_FLASH_PRGKEYR_PRGKEY1;
stm_flash.prgkeyr = STM_FLASH_PRGKEYR_PRGKEY2;
+ if (ao_flash_pgr_is_locked())
+ ao_panic(AO_PANIC_FLASH);
+}
+
+static void
+ao_flash_lock(void)
+{
+ stm_flash.pecr |= (1 << STM_FLASH_PECR_OPTLOCK) | (1 << STM_FLASH_PECR_PRGLOCK) | (1 << STM_FLASH_PECR_PELOCK);
}
static void
@@ -59,32 +69,45 @@ ao_flash_wait_bsy(void)
;
}
-static void
+static void __attribute__ ((section(".text.ram"),noinline))
+_ao_flash_erase_page(uint32_t *page)
+{
+ stm_flash.pecr |= (1 << STM_FLASH_PECR_ERASE) | (1 << STM_FLASH_PECR_PROG);
+
+ *page = 0x00000000;
+
+ while (stm_flash.sr & (1 << STM_FLASH_SR_BSY))
+ ;
+}
+
+void
ao_flash_erase_page(uint32_t *page)
{
ao_flash_pecr_unlock();
ao_flash_pgr_unlock();
- stm_flash.pecr |= (1 << STM_FLASH_PECR_ERASE);
- stm_flash.pecr |= (1 << STM_FLASH_PECR_PROG);
-
- ao_flash_wait_bsy();
+ _ao_flash_erase_page(page);
- *page = 0x00000000;
+ ao_flash_lock();
}
static void __attribute__ ((section(".text.ram"), noinline))
- _ao_flash_half_page(uint32_t *dst, uint32_t *src)
+_ao_flash_half_page(uint32_t *dst, uint32_t *src)
{
uint8_t i;
stm_flash.pecr |= (1 << STM_FLASH_PECR_FPRG);
stm_flash.pecr |= (1 << STM_FLASH_PECR_PROG);
+
while (stm_flash.sr & (1 << STM_FLASH_SR_BSY))
;
-
- for (i = 0; i < 32; i++)
+
+ for (i = 0; i < 32; i++) {
*dst++ = *src++;
+ }
+
+ while (stm_flash.sr & (1 << STM_FLASH_SR_BSY))
+ ;
}
void
@@ -93,11 +116,12 @@ ao_flash_page(uint32_t *page, uint32_t *src)
uint8_t h;
ao_flash_erase_page(page);
+ ao_flash_pecr_unlock();
+ ao_flash_pgr_unlock();
for (h = 0; h < 2; h++) {
- ao_flash_pecr_unlock();
- ao_flash_pgr_unlock();
_ao_flash_half_page(page, src);
page += 32;
src += 32;
}
+ ao_flash_lock();
}
diff --git a/src/stm/ao_flash_stm.h b/src/stm/ao_flash_stm.h
index b4067d8d..09ca5ac1 100644
--- a/src/stm/ao_flash_stm.h
+++ b/src/stm/ao_flash_stm.h
@@ -19,6 +19,9 @@
#define _AO_FLASH_STM_H_
void
+ao_flash_erase_page(uint32_t *page);
+
+void
ao_flash_page(uint32_t *page, uint32_t *src);
#endif /* _AO_FLASH_STM_H_ */