--- /dev/null
+include $(TOPDIR)/stm32f1/Makefile-stm32f1.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_flash_pins.h \
+ ao_flash_stm_pins.h \
+ ao_flash_task.h \
+ ao_pins.h \
+ ao_product.h \
+ Makefile
+
+#
+# Common AltOS sources
+#
+SRC = \
+ ao_interrupt.c \
+ ao_romconfig.c \
+ ao_boot_chain.c \
+ ao_boot_pin.c \
+ ao_product.c \
+ ao_notask.c \
+ ao_clock.c \
+ ao_usb_stm.c \
+ ao_flash_stm.c \
+ ao_flash_task.c \
+ ao_flash_loader_stm.c
+
+OBJ=$(SRC:.c=.o)
+
+PRODUCT=AltosFlash
+PRODUCT_DEF=-DALTOS_FLASH
+IDPRODUCT=0x000a
+
+CFLAGS = $(PRODUCT_DEF) $(STM32F1_CFLAGS)
+
+LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stm32f1 -Taltos-loader.ld -n -Wl,--gc-sections
+
+PROGNAME=$(HARDWARE)-altos-flash
+PROG=$(PROGNAME)-$(VERSION).elf
+
+$(PROG): Makefile $(OBJ) altos-loader.ld
+ $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+$(OBJ): $(INC)
+
+all: $(PROG)
+
+distclean: clean
+
+clean:
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.map
+ rm -f ao_product.h
+
+install:
+
+uninstall:
include $(TOPDIR)/stm32f1/Makefile-stm32f1.defs
-STM32F1_LINKER_SCRIPT=altos-raw.ld
+STM32F1_LINKER_SCRIPT=altos.ld
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stm32f1 -T$(STM32F1_LINKER_SCRIPT) -n
+LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stm32f1 -T$(STM32F1_LINKER_SCRIPT) -n -Wl,--gc-sections
.DEFAULT_GOAL=all
--- /dev/null
+/*
+ * Copyright © 2018 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; 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
+ * 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.
+ */
+
+__flash = 0x08000000;
+__flash_size = 4k;
+__ram = 0x20000000;
+__ram_size = 20k;
+__stack_size = 512;
+
+INCLUDE registers.ld
+INCLUDE picolibc.ld
--- /dev/null
+/*
+ * Copyright © 2012 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; 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
+ * 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.
+ */
+
+__flash = 0x08001000;
+__flash_size = 60K;
+__ram = 0x20000000;
+__ram_size = 20k;
+__stack_size = 512;
+
+INCLUDE registers.ld
+INCLUDE picolibc.ld
#define AO_PCLK1 AO_APB1CLK
#define AO_PCLK2 AO_APB2CLK
+#define AO_BOOT_APPLICATION_BASE ((uint32_t *) 0x08001000)
+#define AO_BOOT_APPLICATION_BOUND ((uint32_t *) (0x08000000 + stm_flash_size()))
+#define AO_BOOT_LOADER_BASE ((uint32_t *) 0x08000000)
+#define HAS_BOOT_LOADER 1
+
#endif /* _AO_ARCH_H_ */
#ifndef _AO_ARCH_FUNCS_H_
#define _AO_ARCH_FUNCS_H_
+#define AO_EXTI_MODE_RISING 1
+#define AO_EXTI_MODE_FALLING 2
+#define AO_EXTI_MODE_PULL_NONE 0
+#define AO_EXTI_MODE_PULL_UP 4
+#define AO_EXTI_MODE_PULL_DOWN 8
+#define AO_EXTI_PRIORITY_LOW 16
+#define AO_EXTI_PRIORITY_MED 0
+#define AO_EXTI_PRIORITY_HIGH 32
+#define AO_EXTI_PIN_NOCONFIGURE 64
+
static inline void
ao_enable_port(struct stm_gpio *port)
{
STM_GPIO_CR_CNF_OUTPUT_PUSH_PULL);
}
+static inline void
+ao_gpio_set_mode(struct stm_gpio *port, int bit, int mode)
+{
+ uint8_t cnf;
+
+ if (mode == AO_EXTI_MODE_PULL_NONE)
+ cnf = STM_GPIO_CR_CNF_INPUT_FLOATING;
+ else {
+ cnf = STM_GPIO_CR_CNF_INPUT_PULL;
+ ao_gpio_set(port, bit, mode == AO_EXTI_MODE_PULL_UP);
+ }
+ stm_gpio_conf(port, bit,
+ STM_GPIO_CR_MODE_INPUT,
+ cnf);
+}
+
+static inline void
+ao_enable_input(struct stm_gpio *port, int bit, int mode)
+{
+ ao_enable_port(port);
+ ao_gpio_set_mode(port, bit, mode);
+}
+
#if USE_SERIAL_1_SW_FLOW || USE_SERIAL_2_SW_FLOW || USE_SERIAL_3_SW_FLOW
#define HAS_SERIAL_SW_FLOW 1
#else
--- /dev/null
+/*
+ * 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; 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
+ * 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];
+ if (0x08000100 <= pc && pc <= 0x08200000 && (pc & 1) == 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;
+};
+
+struct ao_boot ao_boot __attribute__((section(".preserve.2")));
+
+int
+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;
+ if (ao_boot.base == AO_BOOT_FORCE_LOADER)
+ return 0;
+ ao_boot_chain(ao_boot.base);
+ }
+ return 1;
+}
+
+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();
+}
--- /dev/null
+/*
+ * 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; 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
+ * 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>
+
+int
+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);
+
+ for (v = 0; v < 100; v++)
+ ao_arch_nop();
+
+ /* Read the value */
+ v = ao_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 &= ~(1UL << STM_RCC_APB1ENR_PWREN);
+ return v == AO_BOOT_APPLICATION_VALUE;
+}
#ifndef _AO_EXTI_H_
#define _AO_EXTI_H_
-#define AO_EXTI_MODE_RISING 1
-#define AO_EXTI_MODE_FALLING 2
-#define AO_EXTI_MODE_PULL_NONE 0
-#define AO_EXTI_MODE_PULL_UP 4
-#define AO_EXTI_MODE_PULL_DOWN 8
-#define AO_EXTI_PRIORITY_LOW 16
-#define AO_EXTI_PRIORITY_MED 0
-#define AO_EXTI_PRIORITY_HIGH 32
-#define AO_EXTI_PIN_NOCONFIGURE 64
-
void
ao_exti_setup(struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback)(void));
--- /dev/null
+/*
+ * 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; 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
+ * 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_erase_page(uint32_t *page);
+
+void
+ao_flash_page(uint32_t *page, uint32_t *src);
+
+#endif /* _AO_FLASH_STM_H_ */
--- /dev/null
+/*
+ * 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; 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
+ * 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_exti.h>
+#include <ao_boot.h>
+#include <ao_flash_task.h>
+
+int
+main(void)
+{
+ ao_clock_init();
+
+ ao_usb_init();
+
+#if HAS_TICK
+ ao_timer_init();
+#endif
+
+#ifdef AO_FLASH_LOADER_INIT
+ AO_FLASH_LOADER_INIT;
+#endif
+ ao_flash_task();
+ return 0;
+}
uint16_t dev_id = stm_dev_id();
switch (dev_id) {
- case 0x440: /* stm32f05x */
- case 0x444: /* stm32f03x */
- case 0x445: /* stm32f04x */
+ case 0x412: /* low-density devices */
+ case 0x410: /* medium-density devices */
return 1024;
- case 0x442: /* stm32f09x */
- case 0x448: /* stm32f07x */
+ case 0x414: /* high-density devices */
+ case 0x430: /* XL-density devices */
+ case 0x418: /* Connectivity devices */
return 2048;
}
ao_panic(AO_PANIC_FLASH);
--- /dev/null
+/*
+ * 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; 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
+ * 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_PINS_H_
+#define _AO_FLASH_STM_PINS_H_
+
+#include <ao_flash_pins.h>
+
+#ifndef AO_SYSCLK
+
+#define AO_SYSCLK 72000000
+#define AO_HCLK 72000000
+#define AO_APB1CLK 36000000
+#define AO_APB2CLK 72000000
+#define AO_ADCCLK 12000000
+
+#define AO_RCC_CFGR_USBPRE STM_RCC_CFGR_USBPRE_1_5
+#define AO_RCC_CFGR_PLLMUL STM_RCC_CFGR_PLLMUL_9
+#define AO_RCC_CFGR_PLLXTPRE STM_RCC_CFGR_PLLXTPRE_1
+#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_1
+#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE1_DIV_2
+#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1
+#define AO_RCC_CFGR_ADCPRE STM_RCC_CFGR_ADCPRE_6
+
+#endif
+
+#endif /* _AO_FLASH_STM_PINS_H_ */
if (speed > AO_SERIAL_SPEED_115200)
return;
+#if HAS_SERIAL_1
if (usart == &ao_stm_usart1)
brr = AO_PCLK2 / ao_usart_speeds[speed].baud;
else
+#endif
brr = AO_PCLK1 / ao_usart_speeds[speed].baud;
usart->reg->brr = brr;
}
static void
-ao_usart_init(struct ao_stm_usart *usart, int hw_flow)
+ao_usart_init(struct ao_stm_usart *usart, int hw_flow, uint8_t speed)
{
usart->reg->cr1 = ((1 << STM_USART_CR1_UE) |
(0 << STM_USART_CR1_M) |
usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) |
(1 << STM_USART_CR3_RTSE));
- /* Pick a 9600 baud rate */
- ao_usart_set_speed(usart, AO_SERIAL_SPEED_9600);
-}
-
-#if HAS_SERIAL_HW_FLOW
-static void
-ao_usart_set_flow(struct ao_stm_usart *usart)
-{
+ ao_usart_set_speed(usart, speed);
}
-#endif
#if HAS_SERIAL_1
*/
#if SERIAL_2_PA2_PA3
- stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN);
+ ao_enable_port(&stm_gpioa);
+ stm_gpio_conf(&stm_gpioa, 2,
+ STM_GPIO_CR_MODE_OUTPUT_2MHZ,
+ STM_GPIO_CR_CNF_OUTPUT_AF_PUSH_PULL);
+
+ stm_gpio_conf(&stm_gpioa, 3,
+ STM_GPIO_CR_MODE_INPUT,
+ STM_GPIO_CR_CNF_INPUT_FLOATING);
+
+#ifndef USE_SERIAL_2_FLOW
+#define USE_SERIAL_2_FLOW 0
+#define USE_SERIAL_2_SW_FLOW 0
+#endif
- stm_afr_set(&stm_gpioa, 2, STM_AFR_AF7);
- stm_afr_set(&stm_gpioa, 3, STM_AFR_AF7);
# if USE_SERIAL_2_FLOW
# if USE_SERIAL_2_SW_FLOW
ao_serial_set_sw_rts_cts(&ao_stm_usart2,
SERIAL_2_PORT_CTS,
SERIAL_2_PIN_CTS);
# else
- stm_afr_set(&stm_gpioa, 0, STM_AFR_AF7);
- stm_afr_set(&stm_gpioa, 1, STM_AFR_AF7);
+ stm_gpio_conf(&stm_gpioa, 0, /* CTS */
+ STM_GPIO_CR_MODE_INPUT,
+ STM_GPIO_CR_CNF_INPUT_FLOATING);
+ stm_gpio_conf(&stm_gpioa, 1, /* RTS */
+ STM_GPIO_CR_MODE_OUTPUT_2MHZ,
+ STM_GPIO_CR_CNF_OUTPUT_AF_PUSH_PULL);
+
# endif
# endif
-#else
-#if SERIAL_2_PD5_PD6
- stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN);
+ stm_set_afio_mapr(STM_AFIO_MAPR_USART2_REMAP,
+ STM_AFIO_MAPR_USART2_REMAP_PA0_PA1_PA2_PA3_PA4,
+ STM_AFIO_MAPR_USART2_REMAP_MASK);
+#elif SERIAL_2_PD5_PD6
+ ao_enable_port(&stm_gpiod);
+ stm_gpio_conf(&stm_gpiod, 5,
+ STM_GPIO_CR_MODE_OUTPUT_2MHZ,
+ STM_GPIO_CR_CNF_OUTPUT_AF_PUSH_PULL);
- stm_afr_set(&stm_gpiod, 5, STM_AFR_AF7);
- stm_afr_set(&stm_gpiod, 6, STM_AFR_AF7);
-#if USE_SERIAL_2_FLOW
-#error "Don't know how to set flowcontrol for serial 2 on PD"
-#endif
+ stm_gpio_conf(&stm_gpiod, 6,
+ STM_GPIO_CR_MODE_INPUT,
+ STM_GPIO_CR_CNF_INPUT_FLOATING);
+
+# if USE_SERIAL_2_FLOW
+# if USE_SERIAL_2_SW_FLOW
+ ao_serial_set_sw_rts_cts(&ao_stm_usart2,
+ ao_serial2_cts,
+ SERIAL_2_PORT_RTS,
+ SERIAL_2_PIN_RTS,
+ SERIAL_2_PORT_CTS,
+ SERIAL_2_PIN_CTS);
+# else
+ stm_gpio_conf(&stm_gpiod, 3, /* CTS */
+ STM_GPIO_CR_MODE_INPUT,
+ STM_GPIO_CR_CNF_INPUT_FLOATING);
+ stm_gpio_conf(&stm_gpiod, 4, /* RTS */
+ STM_GPIO_CR_MODE_OUTPUT_2MHZ,
+ STM_GPIO_CR_CNF_OUTPUT_AF_PUSH_PULL);
+
+# endif
+# endif
+ stm_set_afio_mapr(STM_AFIO_MAPR_USART2_REMAP,
+ STM_AFIO_MAPR_USART2_REMAP_PD3_PD4_PD5_PD6_PD7,
+ STM_AFIO_MAPR_USART2_REMAP_MASK);
#else
#error "No SERIAL_2 port configuration specified"
-#endif
#endif
/* Enable USART */
stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART2EN);
ao_stm_usart2.reg = &stm_usart2;
- ao_usart_init(&ao_stm_usart2, USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW);
+ ao_usart_init(&ao_stm_usart2, USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW, SERIAL_2_SPEED);
stm_nvic_set_enable(STM_ISR_USART2_POS);
stm_nvic_set_priority(STM_ISR_USART2_POS, AO_STM_NVIC_MED_PRIORITY);
stm_mpu = 0xe000ed90;
-stm_dbg_mcu = 0xe0042000;
+stm_dbgmcu = 0xe0042000;
/* data in system memory */
stm_flash_data = 0x1ffff7e0;
#define STM_SCB_AIRCR_VECTCLRACTIVE 1
#define STM_SCB_AIRCR_VECTRESET 0
+struct stm_dbgmcu {
+ uint32_t idcode;
+};
+
+extern struct stm_dbgmcu stm_dbgmcu;
+
+static inline uint16_t
+stm_dev_id(void) {
+ return stm_dbgmcu.idcode & 0xfff;
+}
+
struct stm_flash {
vuint32_t acr;
vuint32_t keyr;
#define STM_FLASH_CR_PG 0
#define STM_FLASH_RDPRT_KEY 0x00A5
-#define STM_FLASH_FPEC_KEY1 0x45670123
-#define STM_FLASH_FPEC_KEY2 0xCDEF89AB
+#define STM_FLASH_KEYR_KEY1 0x45670123
+#define STM_FLASH_KEYR_KEY2 0xCDEF89AB
struct stm_flash_data {