altos/telefireone-v1.0: Track ao_led_init API change
[fw/altos] / src / stm / ao_flash_stm.c
index b3ef6a6273ac1bf8f88da1542965c002baf0bc70..38618bbe53165f64138c0a3a39fa81c2740cbf20 100644 (file)
@@ -3,7 +3,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -16,7 +17,7 @@
  */
 
 #include <ao.h>
-#include <ao_flash_stm.h>
+#include <ao_flash.h>
 
 static uint8_t
 ao_flash_pecr_is_locked(void)
@@ -39,6 +40,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 +53,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 +70,45 @@ ao_flash_wait_bsy(void)
                ;
 }
 
-static void
+static void __attribute__ ((section(".ramtext"),noinline))
+_ao_flash_erase_page(uint32_t *page)
+{
+       stm_flash.pecr |= (1 << STM_FLASH_PECR_ERASE) | (1 << STM_FLASH_PECR_PROG);
+
+       *page = 0x00000000;
+
+       ao_flash_wait_bsy();
+}
+
+void
 ao_flash_erase_page(uint32_t *page)
 {
+       ao_arch_block_interrupts();
        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();
+       ao_arch_release_interrupts();
 }
 
-static void __attribute__ ((section(".text.ram"), noinline))
-       _ao_flash_half_page(uint32_t *dst, uint32_t *src)
+static void __attribute__ ((section(".ramtext"), noinline))
+_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);
+
+       ao_flash_wait_bsy();
+
+       for (i = 0; i < 32; i++) {
+               *dst++ = *src++;
+       }
+
        while (stm_flash.sr & (1 << STM_FLASH_SR_BSY))
                ;
-       
-       for (i = 0; i < 32; i++)
-               *dst++ = *src++;
 }
 
 void
@@ -93,11 +117,15 @@ ao_flash_page(uint32_t *page, uint32_t *src)
        uint8_t         h;
 
        ao_flash_erase_page(page);
+
+       ao_arch_block_interrupts();
+       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();
+       ao_arch_release_interrupts();
 }