From 56a7cbbf51f5c9ebbfe17d1cc30ed807572af3cc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 11 Mar 2013 00:01:52 -0700 Subject: [PATCH] altos: Add program flash function And get it loaded to RAM so it can execute correctly. Nothing calls it yet... Signed-off-by: Keith Packard --- src/stm-flash/Makefile | 1 + src/stm/altos-loader.ld | 31 +++++++----- src/stm/ao_flash_stm.c | 103 ++++++++++++++++++++++++++++++++++++++++ src/stm/ao_flash_stm.h | 24 ++++++++++ src/stm/stm32l.h | 3 ++ 5 files changed, 151 insertions(+), 11 deletions(-) create mode 100644 src/stm/ao_flash_stm.c create mode 100644 src/stm/ao_flash_stm.h diff --git a/src/stm-flash/Makefile b/src/stm-flash/Makefile index fbc6603d..3c7b4966 100644 --- a/src/stm-flash/Makefile +++ b/src/stm-flash/Makefile @@ -24,6 +24,7 @@ ALTOS_SRC = \ ao_mutex.c \ ao_usb_stm.c \ ao_stdio.c \ + ao_flash_stm.c \ ao_cmd.c PRODUCT=StmFlash-v0.0 diff --git a/src/stm/altos-loader.ld b/src/stm/altos-loader.ld index 2d71b4ee..50a425c7 100644 --- a/src/stm/altos-loader.ld +++ b/src/stm/altos-loader.ld @@ -16,8 +16,8 @@ */ MEMORY { - rom (rx) : ORIGIN = 0x08000000, LENGTH = 8K - ram (!w) : ORIGIN = 0x20000000, LENGTH = 16K + rom : ORIGIN = 0x08000000, LENGTH = 8K + ram : ORIGIN = 0x20000000, LENGTH = 16K } INCLUDE registers.ld @@ -29,7 +29,7 @@ SECTIONS { * Rom contents */ - .text ORIGIN(rom) : { + .text : { __text_start__ = .; *(.interrupt) /* Interrupt vectors */ @@ -38,26 +38,35 @@ SECTIONS { ao_romconfig.o(.romconfig*) ao_product.o(.romconfig*) - *(.text*) /* Executable code */ - *(.rodata*) /* Constants */ + *(.text) /* Executable code */ + *(.rodata) /* Constants */ } > rom .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) - __text_end__ = .; } > rom + __text_end__ = .; + + /* Functions placed in RAM (required for flashing) */ + .textram : { + __text_ram_start = .; + __data_start__ = .; + *(.text.ram) + . = ALIGN(4); + } >ram AT>rom + __text_ram_end = .; /* Data -- relocated to RAM, but written to ROM */ - .data ORIGIN(ram) : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { - __data_start__ = .; + .data : { *(.data) /* initialized data */ - __data_end__ = .; - __bss_start__ = .; - } >ram + . = ALIGN (4); + } >ram AT>rom + __data_end__ = .; .bss : { + __bss_start__ = .; *(.bss) *(COMMON) __bss_end__ = .; diff --git a/src/stm/ao_flash_stm.c b/src/stm/ao_flash_stm.c new file mode 100644 index 00000000..b3ef6a62 --- /dev/null +++ b/src/stm/ao_flash_stm.c @@ -0,0 +1,103 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include + +static uint8_t +ao_flash_pecr_is_locked(void) +{ + return (stm_flash.pecr & (1 << STM_FLASH_PECR_PELOCK)) != 0; +} + +static uint8_t +ao_flash_pgr_is_locked(void) +{ + return (stm_flash.pecr & (1 << STM_FLASH_PECR_PRGLOCK)) != 0; +} + +static void +ao_flash_pecr_unlock(void) +{ + if (!ao_flash_pecr_is_locked()) + return; + + /* Unlock Data EEPROM and FLASH_PECR register */ + stm_flash.pekeyr = STM_FLASH_PEKEYR_PEKEY1; + stm_flash.pekeyr = STM_FLASH_PEKEYR_PEKEY2; +} + +static void +ao_flash_pgr_unlock(void) +{ + if (!ao_flash_pgr_is_locked()) + return; + + /* Unlock program memory */ + stm_flash.prgkeyr = STM_FLASH_PRGKEYR_PRGKEY1; + stm_flash.prgkeyr = STM_FLASH_PRGKEYR_PRGKEY2; +} + +static void +ao_flash_wait_bsy(void) +{ + while (stm_flash.sr & (1 << STM_FLASH_SR_BSY)) + ; +} + +static 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(); + + *page = 0x00000000; +} + +static void __attribute__ ((section(".text.ram"), 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); + while (stm_flash.sr & (1 << STM_FLASH_SR_BSY)) + ; + + for (i = 0; i < 32; i++) + *dst++ = *src++; +} + +void +ao_flash_page(uint32_t *page, uint32_t *src) +{ + uint8_t h; + + ao_flash_erase_page(page); + for (h = 0; h < 2; h++) { + ao_flash_pecr_unlock(); + ao_flash_pgr_unlock(); + _ao_flash_half_page(page, src); + page += 32; + src += 32; + } +} diff --git a/src/stm/ao_flash_stm.h b/src/stm/ao_flash_stm.h new file mode 100644 index 00000000..b4067d8d --- /dev/null +++ b/src/stm/ao_flash_stm.h @@ -0,0 +1,24 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_FLASH_STM_H_ +#define _AO_FLASH_STM_H_ + +void +ao_flash_page(uint32_t *page, uint32_t *src); + +#endif /* _AO_FLASH_STM_H_ */ diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 5c0748a6..63bde0f8 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -435,6 +435,9 @@ extern struct stm_flash stm_flash; #define STM_FLASH_PEKEYR_PEKEY1 0x89ABCDEF #define STM_FLASH_PEKEYR_PEKEY2 0x02030405 +#define STM_FLASH_PRGKEYR_PRGKEY1 0x8C9DAEBF +#define STM_FLASH_PRGKEYR_PRGKEY2 0x13141516 + struct stm_rcc { vuint32_t cr; vuint32_t icscr; -- 2.30.2