From a6887032b4d217bca5236ea15389218f10d69545 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Feb 2013 00:18:14 -0800 Subject: Add STM self-flashing loader This allows the real application to get loaded at 0x2000 and jumps to that at startup time if the boot pin is set appropriately Signed-off-by: Keith Packard --- src/stm-flash/Makefile | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/stm-flash/Makefile (limited to 'src/stm-flash/Makefile') diff --git a/src/stm-flash/Makefile b/src/stm-flash/Makefile new file mode 100644 index 00000000..fbc6603d --- /dev/null +++ b/src/stm-flash/Makefile @@ -0,0 +1,60 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_pins.h \ + ao_product.h + +# +# Common AltOS sources +# +ALTOS_SRC = \ + ao_interrupt.c \ + ao_product.c \ + ao_romconfig.c \ + ao_task.c \ + ao_timer.c \ + ao_mutex.c \ + ao_usb_stm.c \ + ao_stdio.c \ + ao_cmd.c + +PRODUCT=StmFlash-v0.0 +PRODUCT_DEF=-DSTM_FLASH +IDPRODUCT=0x000a + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) -g -Os + +PROG=stm-flash + +SRC=$(ALTOS_SRC) ao_stm_flash.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +LDFLAGS=-L../stm -Wl,-Taltos-loader.ld + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +$(OBJ): $(INC) + +distclean: clean + +clean: + rm -f *.o $(PROG) + rm -f ao_product.h + +install: + +uninstall: -- cgit v1.2.3 From 56a7cbbf51f5c9ebbfe17d1cc30ed807572af3cc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 11 Mar 2013 00:01:52 -0700 Subject: 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 (limited to 'src/stm-flash/Makefile') 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; -- cgit v1.2.3 From b1a43ce313c85cb7f8f16f7f0647d9d4320ba692 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 11 Mar 2013 13:21:04 -0700 Subject: altos: Clean up boot loader support Split out code into separate files. Add support for getting back to boot loader from application. Signed-off-by: Keith Packard --- src/stm-demo/Makefile | 1 + src/stm-demo/ao_demo.c | 9 +++++ src/stm-demo/ao_pins.h | 2 ++ src/stm-flash/Makefile | 2 ++ src/stm-flash/ao_pins.h | 5 ++- src/stm-flash/ao_stm_flash.c | 84 +------------------------------------------- src/stm/altos-application.ld | 17 +++++++-- src/stm/altos-loader.ld | 13 ++++++- src/stm/ao_boot.h | 11 +++++- src/stm/ao_boot_chain.c | 62 ++++++++++++++++++++++++++++++++ src/stm/ao_boot_pin.c | 43 +++++++++++++++++++++++ src/stm/ao_interrupt.c | 64 ++++----------------------------- 12 files changed, 166 insertions(+), 147 deletions(-) create mode 100644 src/stm/ao_boot_chain.c create mode 100644 src/stm/ao_boot_pin.c (limited to 'src/stm-flash/Makefile') diff --git a/src/stm-demo/Makefile b/src/stm-demo/Makefile index ab12f47b..e6cd55e4 100644 --- a/src/stm-demo/Makefile +++ b/src/stm-demo/Makefile @@ -17,6 +17,7 @@ INC = \ # ALTOS_SRC = \ ao_interrupt.c \ + ao_boot_chain.c \ ao_product.c \ ao_romconfig.c \ ao_cmd.c \ diff --git a/src/stm-demo/ao_demo.c b/src/stm-demo/ao_demo.c index 9ee0be03..ec572fdc 100644 --- a/src/stm-demo/ao_demo.c +++ b/src/stm-demo/ao_demo.c @@ -20,6 +20,7 @@ #include #include #include +#include struct ao_task demo_task; @@ -168,6 +169,13 @@ ao_event(void) } +static void +ao_boot_loader(void) +{ + flush(); + ao_boot_reboot((uint32_t *) 0); +} + __code struct ao_cmds ao_demo_cmds[] = { { ao_dma_test, "D\0DMA test" }, { ao_spi_write, "W\0SPI write" }, @@ -175,6 +183,7 @@ __code struct ao_cmds ao_demo_cmds[] = { { ao_i2c_write, "i\0I2C write" }, { ao_temp, "t\0Show temp" }, { ao_event, "e\0Monitor event queue" }, + { ao_boot_loader, "L\0Reboot to boot loader" }, { 0, NULL } }; diff --git a/src/stm-demo/ao_pins.h b/src/stm-demo/ao_pins.h index 07b4a19d..40e48a36 100644 --- a/src/stm-demo/ao_pins.h +++ b/src/stm-demo/ao_pins.h @@ -68,6 +68,8 @@ #define HAS_BEEP 0 #define PACKET_HAS_SLAVE 0 +#define AO_BOOT_CHAIN 1 + #define LOW_LEVEL_DEBUG 1 #define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOBEN diff --git a/src/stm-flash/Makefile b/src/stm-flash/Makefile index 3c7b4966..e4a2f321 100644 --- a/src/stm-flash/Makefile +++ b/src/stm-flash/Makefile @@ -17,6 +17,8 @@ INC = \ # ALTOS_SRC = \ ao_interrupt.c \ + ao_boot_chain.c \ + ao_boot_pin.c \ ao_product.c \ ao_romconfig.c \ ao_task.c \ diff --git a/src/stm-flash/ao_pins.h b/src/stm-flash/ao_pins.h index ca53d844..382ef353 100644 --- a/src/stm-flash/ao_pins.h +++ b/src/stm-flash/ao_pins.h @@ -65,10 +65,13 @@ #define HAS_TASK_INFO 0 #define HAS_VERSION 0 +#define AO_BOOT_CHAIN 1 +#define AO_BOOT_PIN 1 + #define AO_BOOT_APPLICATION_GPIO stm_gpioa #define AO_BOOT_APPLICATION_PIN 0 #define AO_BOOT_APPLICATION_VALUE 1 #define AO_BOOT_APPLICATION_MODE 0 -#define AO_BOOT_APPLICATION_BASE 0x2000 +#define AO_BOOT_APPLICATION_BASE ((uint32_t *) 0x2000) #endif /* _AO_PINS_H_ */ diff --git a/src/stm-flash/ao_stm_flash.c b/src/stm-flash/ao_stm_flash.c index e2d7ec65..2988a937 100644 --- a/src/stm-flash/ao_stm_flash.c +++ b/src/stm-flash/ao_stm_flash.c @@ -32,89 +32,8 @@ ao_application(void) ao_boot_reboot(AO_BOOT_APPLICATION_BASE); } -static uint32_t -ao_cmd_hex32(void) -{ - __pdata uint8_t r = ao_cmd_lex_error; - int8_t n; - uint32_t v = 0; - - ao_cmd_white(); - for(;;) { - n = ao_cmd_hexchar(ao_cmd_lex_c); - if (n < 0) - break; - v = (v << 4) | n; - r = ao_cmd_success; - ao_cmd_lex(); - } - if (r != ao_cmd_success) - ao_cmd_status = r; - return v; -} - -void -ao_block_erase(void) -{ - uint32_t addr = ao_cmd_hex32(); - uint32_t *p = (uint32_t *) addr; - - ao_flash_erase_page(p); -} - -void -ao_block_write(void) -{ - uint32_t addr = ao_cmd_hex32(); - uint32_t *p = (uint32_t *) addr; - union { - uint8_t data8[256]; - uint32_t data32[64]; - } u; - uint16_t i; - - if (addr < 0x08002000 || 0x08200000 <= addr) { - puts("Invalid address"); - return; - } - for (i = 0; i < 256; i++) - u.data8[i] = i; - ao_flash_page(p, u.data32); -} - -static void -puthex(uint8_t c) -{ - c &= 0xf; - if (c < 10) - c += '0'; - else - c += 'a' - 10; - putchar (c); -} - -void -ao_block_read(void) -{ - uint32_t addr = ao_cmd_hex32(); - uint8_t *p = (uint8_t *) addr; - uint16_t i; - uint8_t c; - - for (i = 0; i < 256; i++) { - c = *p++; - puthex(c); - puthex(c>>4); - if ((i & 0xf) == 0xf) - putchar('\n'); - } -} - __code struct ao_cmds ao_flash_cmds[] = { - { ao_application, "a\0Switch to application" }, - { ao_block_erase, "e \0Erase block." }, - { ao_block_write, "W \0Write block. 256 binary bytes follow newline" }, - { ao_block_read, "R \0Read block. Returns 256 bytes" }, + { ao_application, "A\0Switch to application" }, { 0, NULL }, }; @@ -132,7 +51,6 @@ main(void) // ao_exti_init(); ao_usb_init(); - ao_cmd_register(&ao_flash_cmds[0]); ao_cmd_register(&ao_flash_cmds[0]); ao_start_scheduler(); return 0; diff --git a/src/stm/altos-application.ld b/src/stm/altos-application.ld index 63a3be00..5110da84 100644 --- a/src/stm/altos-application.ld +++ b/src/stm/altos-application.ld @@ -48,16 +48,27 @@ SECTIONS { __text_end__ = .; } > rom + /* Boot data which must live at the start of ram so that + * the application and bootloader share the same addresses. + * This must be all uninitialized data + */ + .boot : { + __boot_start__ = .; + *(.boot) + . = ALIGN(4); + __boot_end__ = .; + } >ram + /* Data -- relocated to RAM, but written to ROM */ - .data ORIGIN(ram) : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { + .data : { __data_start__ = .; *(.data) /* initialized data */ __data_end__ = .; - __bss_start__ = .; - } >ram + } >ram AT>rom .bss : { + __bss_start__ = .; *(.bss) *(COMMON) __bss_end__ = .; diff --git a/src/stm/altos-loader.ld b/src/stm/altos-loader.ld index 50a425c7..2e36dce9 100644 --- a/src/stm/altos-loader.ld +++ b/src/stm/altos-loader.ld @@ -48,9 +48,20 @@ SECTIONS { } > rom __text_end__ = .; + /* Boot data which must live at the start of ram so that + * the application and bootloader share the same addresses. + * This must be all uninitialized data + */ + .boot : { + __boot_start__ = .; + *(.boot) + . = ALIGN(4); + __boot_end__ = .; + } >ram + /* Functions placed in RAM (required for flashing) */ .textram : { - __text_ram_start = .; + __text_ram_start__ = .; __data_start__ = .; *(.text.ram) . = ALIGN(4); diff --git a/src/stm/ao_boot.h b/src/stm/ao_boot.h index 863d8e05..3e8c50ba 100644 --- a/src/stm/ao_boot.h +++ b/src/stm/ao_boot.h @@ -19,6 +19,15 @@ #define _AO_BOOT_H_ void -ao_reboot_application(void); +ao_boot_chain(uint32_t *base); + +void +ao_boot_check_pin(void); + +void +ao_boot_check_chain(void); + +void +ao_boot_reboot(uint32_t *base); #endif /* _AO_BOOT_H_ */ diff --git a/src/stm/ao_boot_chain.c b/src/stm/ao_boot_chain.c new file mode 100644 index 00000000..9c63272b --- /dev/null +++ b/src/stm/ao_boot_chain.c @@ -0,0 +1,62 @@ +/* + * 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 + +void +ao_boot_chain(uint32_t *base) +{ + uint32_t sp; + uint32_t pc; + + sp = base[0]; + pc = base[1]; + asm ("mov sp, %0" : : "r" (sp)); + asm ("mov lr, %0" : : "r" (pc)); + asm ("bx lr"); +} + +#define AO_BOOT_SIGNAL 0x5a5aa5a5 +#define AO_BOOT_CHECK 0xc3c33c3c + +struct ao_boot { + uint32_t *base; + uint32_t signal; + uint32_t check; +}; + +static struct ao_boot __attribute__ ((section(".boot"))) ao_boot; + +void +ao_boot_check_chain(void) +{ + if (ao_boot.signal == AO_BOOT_SIGNAL && ao_boot.check == AO_BOOT_CHECK) { + ao_boot.signal = 0; + ao_boot.check = 0; + ao_boot_chain(ao_boot.base); + } +} + +void +ao_boot_reboot(uint32_t *base) +{ + ao_boot.base = base; + ao_boot.signal = AO_BOOT_SIGNAL; + ao_boot.check = AO_BOOT_CHECK; + ao_arch_reboot(); +} diff --git a/src/stm/ao_boot_pin.c b/src/stm/ao_boot_pin.c new file mode 100644 index 00000000..03b0214f --- /dev/null +++ b/src/stm/ao_boot_pin.c @@ -0,0 +1,43 @@ +/* + * 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 +#include + +void +ao_boot_check_pin(void) +{ + uint16_t v; + + /* Enable power interface clock */ + stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN); + + /* Enable the input pin */ + ao_enable_input(&AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, + AO_BOOT_APPLICATION_MODE); + + /* Read the value */ + v = stm_gpio_get(&AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN); + + /* Reset the chip to turn off the port and the power interface clock */ + ao_gpio_set_mode(&AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, 0); + ao_disable_port(&AO_BOOT_APPLICATION_GPIO); + stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_PWREN); + if (v == AO_BOOT_APPLICATION_VALUE) + ao_boot_chain(AO_BOOT_APPLICATION_BASE); +} diff --git a/src/stm/ao_interrupt.c b/src/stm/ao_interrupt.c index 9e756219..49156285 100644 --- a/src/stm/ao_interrupt.c +++ b/src/stm/ao_interrupt.c @@ -18,6 +18,7 @@ #include #include "stm32l.h" #include +#include extern void main(void); extern char __stack__; @@ -38,67 +39,14 @@ void stm_ignore_isr(void) const void *stm_interrupt_vector[]; -#define BOOT_FETCH(o) (*((uint32_t *) (AO_BOOT_APPLICATION_BASE + (o)))) - -#ifdef AO_BOOT_APPLICATION_PIN -#include - -#define AO_BOOT_APPLICATION 0x5a5aa5a5 -#define AO_BOOT_APPLICATION_CHECK 0xc3c33c3c - -static uint32_t ao_boot_application; -static uint32_t ao_boot_application_check; - -static void -ao_boot_chain(void) { - uint32_t sp; - uint32_t pc; - - sp = BOOT_FETCH(0); - pc = BOOT_FETCH(4); - asm ("mov sp, %0" : : "r" (sp)); - asm ("mov lr, %0" : : "r" (pc)); - asm ("bx lr"); -} - -void -ao_reboot_application(void) +void start(void) { - ao_boot_application = AO_BOOT_APPLICATION; - ao_boot_application_check = AO_BOOT_APPLICATION_CHECK; - ao_arch_reboot(); -} - +#ifdef AO_BOOT_CHAIN + ao_boot_check_chain(); #endif - -void start(void) { -#ifdef AO_BOOT_APPLICATION_PIN - uint16_t v; - - if (ao_boot_application == AO_BOOT_APPLICATION && - ao_boot_application_check == AO_BOOT_APPLICATION_CHECK) { - ao_boot_application = 0; - ao_boot_application_check = 0; - ao_boot_chain(); - } - /* Enable power interface clock */ - stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN); - - /* Enable the input pin */ - ao_enable_input(&AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, - AO_BOOT_APPLICATION_MODE); - - /* Read the value */ - v = stm_gpio_get(&AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN); - - /* Reset the chip to turn off the port and the power interface clock */ - ao_gpio_set_mode(&AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, 0); - ao_disable_port(&AO_BOOT_APPLICATION_GPIO); - stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_PWREN); - if (v == AO_BOOT_APPLICATION_VALUE) - ao_boot_chain(); +#ifdef AO_BOOT_PIN + ao_boot_check_pin(); #endif - /* Set interrupt vector table offset */ stm_nvic.vto = (uint32_t) &stm_interrupt_vector; memcpy(&__data_start__, &__text_end__, &__data_end__ - &__data_start__); -- cgit v1.2.3 From efc0898d824ebd0abe0b088ed9a8b40c34623ab7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 23 Mar 2013 02:15:35 -0700 Subject: altos: Fix up stm-flash output file name. Use discovery LED pins Include the AltOS version in the file name, just like any other AltOS program. Switch the LEDs to the discovery board as we're using that. Eventually, we'll stop using LEDs entirely. Signed-off-by: Keith Packard --- src/stm-flash/Makefile | 2 +- src/stm-flash/ao_pins.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/stm-flash/Makefile') diff --git a/src/stm-flash/Makefile b/src/stm-flash/Makefile index e4a2f321..46bc61af 100644 --- a/src/stm-flash/Makefile +++ b/src/stm-flash/Makefile @@ -35,7 +35,7 @@ IDPRODUCT=0x000a CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) -g -Os -PROG=stm-flash +PROG=stm-flash-$(VERSION).elf SRC=$(ALTOS_SRC) ao_stm_flash.c OBJ=$(SRC:.c=.o) diff --git a/src/stm-flash/ao_pins.h b/src/stm-flash/ao_pins.h index 382ef353..048fc828 100644 --- a/src/stm-flash/ao_pins.h +++ b/src/stm-flash/ao_pins.h @@ -51,9 +51,9 @@ #define PACKET_HAS_SLAVE 0 #define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOCEN -#define LED_PORT (&stm_gpioc) -#define LED_PIN_RED 8 -#define LED_PIN_GREEN 9 +#define LED_PORT (&stm_gpiob) +#define LED_PIN_RED 6 +#define LED_PIN_GREEN 7 #define AO_LED_RED (1 << LED_PIN_RED) #define AO_LED_GREEN (1 << LED_PIN_GREEN) -- cgit v1.2.3 From 6cd015b8b6b02bd8e0ce28f248426ae75c242b53 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Apr 2013 20:32:18 -0500 Subject: altos/stm: Shrink stm flash loader to < 4kB Saves 4kB of flash space for applications. Signed-off-by: Keith Packard --- src/stm-flash/Makefile | 7 +--- src/stm-flash/ao_pins.h | 3 ++ src/stm-flash/ao_stm_flash.c | 96 ++++++++++++++++++-------------------------- src/stm/altos-loader.ld | 16 +------- 4 files changed, 46 insertions(+), 76 deletions(-) (limited to 'src/stm-flash/Makefile') diff --git a/src/stm-flash/Makefile b/src/stm-flash/Makefile index 46bc61af..a4dd5ab8 100644 --- a/src/stm-flash/Makefile +++ b/src/stm-flash/Makefile @@ -20,14 +20,11 @@ ALTOS_SRC = \ ao_boot_chain.c \ ao_boot_pin.c \ ao_product.c \ - ao_romconfig.c \ - ao_task.c \ + ao_notask.c \ ao_timer.c \ - ao_mutex.c \ ao_usb_stm.c \ ao_stdio.c \ - ao_flash_stm.c \ - ao_cmd.c + ao_flash_stm.c PRODUCT=StmFlash-v0.0 PRODUCT_DEF=-DSTM_FLASH diff --git a/src/stm-flash/ao_pins.h b/src/stm-flash/ao_pins.h index 048fc828..6779fc42 100644 --- a/src/stm-flash/ao_pins.h +++ b/src/stm-flash/ao_pins.h @@ -47,6 +47,9 @@ #define HAS_USB 1 #define USE_USB_STDIN 1 #define HAS_BEEP 0 +#define HAS_TASK 0 +#define HAS_ECHO 0 +#define HAS_TICK 0 #define PACKET_HAS_SLAVE 0 diff --git a/src/stm-flash/ao_stm_flash.c b/src/stm-flash/ao_stm_flash.c index 344bceb9..f0abe7fb 100644 --- a/src/stm-flash/ao_stm_flash.c +++ b/src/stm-flash/ao_stm_flash.c @@ -26,6 +26,14 @@ ao_panic(uint8_t reason) for (;;); } +void +ao_put_string(__code char *s) +{ + char c; + while ((c = *s++)) + putchar(c); +} + void ao_application(void) { @@ -33,30 +41,35 @@ ao_application(void) } static uint32_t -ao_cmd_hex32(void) +ao_get_hex32(void) { - __pdata uint8_t r = ao_cmd_lex_error; int8_t n; uint32_t v = 0; - ao_cmd_white(); + for (;;) { + n = getchar(); + if (n != ' ') + break; + } for(;;) { - n = ao_cmd_hexchar(ao_cmd_lex_c); - if (n < 0) + if ('0' <= n && n <= '9') + n = n - '0'; + else if ('a' <= n && n <= 'f') + n = n - ('a' - 10); + else if ('A' <= n && n <= 'F') + n = n - ('A' - 10); + else break; v = (v << 4) | n; - r = ao_cmd_success; - ao_cmd_lex(); + n = getchar(); } - if (r != ao_cmd_success) - ao_cmd_status = r; return v; } void ao_block_erase(void) { - uint32_t addr = ao_cmd_hex32(); + uint32_t addr = ao_get_hex32(); uint32_t *p = (uint32_t *) addr; ao_flash_erase_page(p); @@ -65,7 +78,7 @@ ao_block_erase(void) void ao_block_write(void) { - uint32_t addr = ao_cmd_hex32(); + uint32_t addr = ao_get_hex32(); uint32_t *p = (uint32_t *) addr; union { uint8_t data8[256]; @@ -82,45 +95,17 @@ ao_block_write(void) ao_flash_page(p, u.data32); } -static void -puthex(uint8_t c) -{ - c &= 0xf; - if (c < 10) - c += '0'; - else - c += 'a' - 10; - putchar (c); -} - void ao_block_read(void) { - uint32_t addr = ao_cmd_hex32(); + uint32_t addr = ao_get_hex32(); uint8_t *p = (uint8_t *) addr; uint16_t i; uint8_t c; for (i = 0; i < 256; i++) { c = *p++; - (*ao_stdios[ao_cur_stdio].putchar)(c); - } -} - -void -ao_block_read_hex(void) -{ - uint32_t addr = ao_cmd_hex32(); - uint8_t *p = (uint8_t *) addr; - uint16_t i; - uint8_t c; - - for (i = 0; i < 256; i++) { - c = *p++; - puthex(c>>4); - puthex(c); - if ((i & 0xf) == 0xf) - putchar('\n'); + putchar(c); } } @@ -133,15 +118,18 @@ ao_show_version(void) ao_put_string("software-version "); puts(ao_version); } -__code struct ao_cmds ao_flash_cmds[] = { - { ao_show_version, "v\0Version" }, - { ao_application, "a\0Switch to application" }, - { ao_block_erase, "X \0Erase block." }, - { ao_block_write, "W \0Write block. 256 binary bytes follow newline" }, - { ao_block_read, "R \0Read block. Returns 256 binary bytes" }, - { ao_block_read_hex, "H \0Hex read block. Returns 256 bytes in hex" }, - { 0, NULL }, -}; +static void +ao_flash_task(void) { + for (;;) { + switch (getchar()) { + case 'v': ao_show_version(); break; + case 'a': ao_application(); break; + case 'X': ao_block_erase(); break; + case 'W': ao_block_write(); break; + case 'R': ao_block_read(); break; + } + } +} int @@ -149,15 +137,11 @@ main(void) { ao_clock_init(); - ao_task_init(); - - ao_timer_init(); +// ao_timer_init(); // ao_dma_init(); - ao_cmd_init(); // ao_exti_init(); ao_usb_init(); - ao_cmd_register(&ao_flash_cmds[0]); - ao_start_scheduler(); + ao_flash_task(); return 0; } diff --git a/src/stm/altos-loader.ld b/src/stm/altos-loader.ld index 14b45351..78649be2 100644 --- a/src/stm/altos-loader.ld +++ b/src/stm/altos-loader.ld @@ -32,21 +32,7 @@ SECTIONS { .text : { __text_start__ = .; *(.interrupt) /* Interrupt vectors */ - - . = ORIGIN(rom) + 0x100; - - /* Ick. What I want is to specify the - * addresses of some global constants so - * that I can find them across versions - * of the application. I can't figure out - * how to make gnu ld do that, so instead - * we just load the two files that include - * these defines in the right order here and - * expect things to 'just work'. Don't change - * the contents of those files, ok? - */ - ao_romconfig.o(.romconfig*) - ao_product.o(.romconfig*) + *(.romconfig) *(.text) /* Executable code */ *(.rodata) /* Constants */ -- cgit v1.2.3 From f6d6df03826083a244715b88a30ad681f17b4510 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 27 Apr 2013 00:25:36 -0700 Subject: altos: Remove stdio from stm-flash This saves enough memory to fit in under 4kB Signed-off-by: Keith Packard --- src/stm-flash/Makefile | 7 +++---- src/stm-flash/ao_pins.h | 8 ++++---- src/stm-flash/ao_stm_flash.c | 27 ++++++++++++++++----------- 3 files changed, 23 insertions(+), 19 deletions(-) (limited to 'src/stm-flash/Makefile') diff --git a/src/stm-flash/Makefile b/src/stm-flash/Makefile index a4dd5ab8..1ea35581 100644 --- a/src/stm-flash/Makefile +++ b/src/stm-flash/Makefile @@ -23,16 +23,15 @@ ALTOS_SRC = \ ao_notask.c \ ao_timer.c \ ao_usb_stm.c \ - ao_stdio.c \ ao_flash_stm.c -PRODUCT=StmFlash-v0.0 -PRODUCT_DEF=-DSTM_FLASH +PRODUCT=AltosFlash-$(VERSION) +PRODUCT_DEF=-DALTOS_FLASH IDPRODUCT=0x000a CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) -g -Os -PROG=stm-flash-$(VERSION).elf +PROG=altos-flash-$(VERSION).elf SRC=$(ALTOS_SRC) ao_stm_flash.c OBJ=$(SRC:.c=.o) diff --git a/src/stm-flash/ao_pins.h b/src/stm-flash/ao_pins.h index 8fb56f7b..d6c72653 100644 --- a/src/stm-flash/ao_pins.h +++ b/src/stm-flash/ao_pins.h @@ -45,7 +45,7 @@ #define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_1 #define HAS_USB 1 -#define USE_USB_STDIN 1 +#define USE_USB_STDIO 0 #define HAS_BEEP 0 #define HAS_TASK 0 #define HAS_ECHO 0 @@ -71,9 +71,9 @@ #define AO_BOOT_CHAIN 1 #define AO_BOOT_PIN 1 -#define AO_BOOT_APPLICATION_GPIO stm_gpioa -#define AO_BOOT_APPLICATION_PIN 0 +#define AO_BOOT_APPLICATION_GPIO stm_gpiod +#define AO_BOOT_APPLICATION_PIN 2 #define AO_BOOT_APPLICATION_VALUE 1 -#define AO_BOOT_APPLICATION_MODE 0 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP #endif /* _AO_PINS_H_ */ diff --git a/src/stm-flash/ao_stm_flash.c b/src/stm-flash/ao_stm_flash.c index df06bb09..f8580735 100644 --- a/src/stm-flash/ao_stm_flash.c +++ b/src/stm-flash/ao_stm_flash.c @@ -30,8 +30,11 @@ void ao_put_string(__code char *s) { char c; - while ((c = *s++)) - putchar(c); + while ((c = *s++)) { + if (c == '\n') + ao_usb_putchar('\r'); + ao_usb_putchar(c); + } } void @@ -47,7 +50,7 @@ ao_get_hex32(void) uint32_t v = 0; for (;;) { - n = getchar(); + n = ao_usb_getchar(); if (n != ' ') break; } @@ -61,7 +64,7 @@ ao_get_hex32(void) else break; v = (v << 4) | n; - n = getchar(); + n = ao_usb_getchar(); } return v; } @@ -91,7 +94,7 @@ ao_block_write(void) return; } for (i = 0; i < 256; i++) - u.data8[i] = getchar(); + u.data8[i] = ao_usb_getchar(); ao_flash_page(p, u.data32); } @@ -105,23 +108,25 @@ ao_block_read(void) for (i = 0; i < 256; i++) { c = *p++; - putchar(c); + ao_usb_putchar(c); } } static void ao_show_version(void) { - puts("altos-loader"); - ao_put_string("manufacturer "); puts(ao_manufacturer); - ao_put_string("product "); puts(ao_product); - ao_put_string("software-version "); puts(ao_version); + ao_put_string("altos-loader"); + ao_put_string("\nmanufacturer "); ao_put_string(ao_manufacturer); + ao_put_string("\nproduct "); ao_put_string(ao_product); + ao_put_string("\nsoftware-version "); ao_put_string(ao_version); + ao_put_string("\n"); } static void ao_flash_task(void) { for (;;) { - switch (getchar()) { + ao_usb_flush(); + switch (ao_usb_getchar()) { case 'v': ao_show_version(); break; case 'a': ao_application(); break; case 'X': ao_block_erase(); break; -- cgit v1.2.3