diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/stm-demo/Makefile | 1 | ||||
| -rw-r--r-- | src/stm-demo/ao_demo.c | 9 | ||||
| -rw-r--r-- | src/stm-demo/ao_pins.h | 2 | ||||
| -rw-r--r-- | src/stm-flash/Makefile | 2 | ||||
| -rw-r--r-- | src/stm-flash/ao_pins.h | 5 | ||||
| -rw-r--r-- | src/stm-flash/ao_stm_flash.c | 84 | ||||
| -rw-r--r-- | src/stm/altos-application.ld | 17 | ||||
| -rw-r--r-- | src/stm/altos-loader.ld | 13 | ||||
| -rw-r--r-- | src/stm/ao_boot.h | 11 | ||||
| -rw-r--r-- | src/stm/ao_boot_chain.c | 62 | ||||
| -rw-r--r-- | src/stm/ao_boot_pin.c | 43 | ||||
| -rw-r--r-- | src/stm/ao_interrupt.c | 64 | 
12 files changed, 166 insertions, 147 deletions
| 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 <ao_event.h>  #include <ao_quadrature.h>  #include <ao_button.h> +#include <ao_boot.h>  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 <addr>\0Erase block." }, -	{ ao_block_write, "W <addr>\0Write block. 256 binary bytes follow newline" }, -	{ ao_block_read, "R <addr>\0Read block. Returns 256 bytes" }, +	{ ao_application, "A\0Switch to application" },  	{ 0, NULL },  }; @@ -133,7 +52,6 @@ main(void)  	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 <keithp@keithp.com> + * + * 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 <ao.h> +#include <ao_boot.h> + +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 <keithp@keithp.com> + * + * 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 <ao.h> +#include <ao_boot.h> +#include <ao_exti.h> + +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 <ao.h>  #include "stm32l.h"  #include <string.h> +#include <ao_boot.h>  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 <ao_exti.h> - -#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__); | 
