altos/stm32f1: For some reason the DBG registers aren't always available
[fw/altos] / src / stm32f1 / ao_flash_stm.c
index 0e873d774ec6dbcaf6de5cb6440cd0fd27a913fa..1e35545cffa5783c3478c6286473546edf55fe55 100644 (file)
@@ -69,19 +69,18 @@ _ao_flash_erase_page(uint32_t *page)
 static uint32_t
 stm_flash_page_size(void)
 {
-       uint16_t        dev_id = stm_dev_id();
+       uint16_t        f_size = stm_flash_data.f_size;
 
-       switch (dev_id) {
-       case 0x440:     /* stm32f05x */
-       case 0x444:     /* stm32f03x */
-       case 0x445:     /* stm32f04x */
+       if (f_size <= 128) {
+               /* low-density and medium-density devices */
                return 1024;
-       case 0x442:     /* stm32f09x */
-       case 0x448:     /* stm32f07x */
+       } else {
+               /*
+                * high-density devices, XL-density devices and
+                * Connectivity devices
+                */
                return 2048;
        }
-       ao_panic(AO_PANIC_FLASH);
-       return 0;
 }
 
 void
@@ -104,13 +103,13 @@ ao_flash_erase_page(uint32_t *page)
 }
 
 static void __attribute__ ((section(".sdata2.flash"), noinline))
-_ao_flash_page(uint16_t *dst, uint16_t *src)
+_ao_flash_page(uint16_t *dst, uint16_t *src, unsigned int shorts)
 {
        uint8_t         i;
 
        stm_flash.cr |= (1 << STM_FLASH_CR_PG);
 
-       for (i = 0; i < 128; i++) {
+       for (i = 0; i < shorts; i++) {
                *dst++ = *src++;
                ao_flash_wait_bsy();
        }
@@ -126,7 +125,24 @@ ao_flash_page(uint32_t *page, uint32_t *src)
        ao_arch_block_interrupts();
        ao_flash_unlock();
 
-       _ao_flash_page((uint16_t *) page, (uint16_t *) src);
+       _ao_flash_page((uint16_t *) page, (uint16_t *) src, 128);
+
+       ao_flash_lock();
+       ao_arch_release_interrupts();
+}
+
+/* Stores less than a full page while still smashing the full page */
+void
+ao_flash_bytes(void *page, void *src, size_t size)
+{
+       unsigned int shorts = (unsigned int) ((size + 1) >> 1);
+
+       ao_flash_erase_page(page);
+
+       ao_arch_block_interrupts();
+       ao_flash_unlock();
+
+       _ao_flash_page((uint16_t *) page, (uint16_t *) src, shorts);
 
        ao_flash_lock();
        ao_arch_release_interrupts();