stm32f1: Get boot loader working
authorKeith Packard <keithp@keithp.com>
Sun, 26 Feb 2023 03:24:11 +0000 (19:24 -0800)
committerKeith Packard <keithp@keithp.com>
Thu, 1 Feb 2024 01:50:19 +0000 (17:50 -0800)
Signed-off-by: Keith Packard <keithp@keithp.com>
16 files changed:
src/stm32f1/Makefile-flash.defs [new file with mode: 0644]
src/stm32f1/Makefile.defs
src/stm32f1/altos-loader.ld [new file with mode: 0644]
src/stm32f1/altos.ld [new file with mode: 0644]
src/stm32f1/ao_arch.h
src/stm32f1/ao_arch_funcs.h
src/stm32f1/ao_boot_chain.c [new file with mode: 0644]
src/stm32f1/ao_boot_pin.c [new file with mode: 0644]
src/stm32f1/ao_exti.h
src/stm32f1/ao_flash.h [new file with mode: 0644]
src/stm32f1/ao_flash_loader_stm.c [new file with mode: 0644]
src/stm32f1/ao_flash_stm.c
src/stm32f1/ao_flash_stm_pins.h [new file with mode: 0644]
src/stm32f1/ao_serial_stm.c
src/stm32f1/registers.ld
src/stm32f1/stm32f1.h

diff --git a/src/stm32f1/Makefile-flash.defs b/src/stm32f1/Makefile-flash.defs
new file mode 100644 (file)
index 0000000..461d929
--- /dev/null
@@ -0,0 +1,58 @@
+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:
index e292fc672ad986dbe5fcba6f7cc7f49c02fe1fbb..98b331890fca38162ebb61a46dc0c9e5dfbd7d37 100644 (file)
@@ -4,8 +4,8 @@ endif
 
 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
diff --git a/src/stm32f1/altos-loader.ld b/src/stm32f1/altos-loader.ld
new file mode 100644 (file)
index 0000000..798106e
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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
diff --git a/src/stm32f1/altos.ld b/src/stm32f1/altos.ld
new file mode 100644 (file)
index 0000000..15be8fa
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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
index 743651330e96cad130890e3a162516837fc980bb..7e53f2269ed2901e2119708b8ca77e3b9a2dedca 100644 (file)
@@ -58,4 +58,9 @@
 #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_ */
index 35e9374fc66ffd9fdf79dfd15f05d030170f1387..502fb140b47cb1777ef126aad4378324073ec2e4 100644 (file)
 #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)
 {
@@ -71,6 +81,29 @@ ao_enable_output(struct stm_gpio *port, int bit, uint8_t v)
                      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
diff --git a/src/stm32f1/ao_boot_chain.c b/src/stm32f1/ao_boot_chain.c
new file mode 100644 (file)
index 0000000..d91afda
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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();
+}
diff --git a/src/stm32f1/ao_boot_pin.c b/src/stm32f1/ao_boot_pin.c
new file mode 100644 (file)
index 0000000..e1c21c8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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;
+}
index 1d19a48f60dcd63b99a3b964d318710197b9f72a..d072d140292bac9b58843209a142584075f63761 100644 (file)
 #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));
 
diff --git a/src/stm32f1/ao_flash.h b/src/stm32f1/ao_flash.h
new file mode 100644 (file)
index 0000000..d191d80
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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_ */
diff --git a/src/stm32f1/ao_flash_loader_stm.c b/src/stm32f1/ao_flash_loader_stm.c
new file mode 100644 (file)
index 0000000..18bf272
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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;
+}
index 0e873d774ec6dbcaf6de5cb6440cd0fd27a913fa..48c702f7a8d893a9e5af316d5323610326846b75 100644 (file)
@@ -72,12 +72,12 @@ stm_flash_page_size(void)
        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);
diff --git a/src/stm32f1/ao_flash_stm_pins.h b/src/stm32f1/ao_flash_stm_pins.h
new file mode 100644 (file)
index 0000000..b58bd36
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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_ */
index f5d51088bdc04b1b05a9700835c0238e97ba743d..5bfa6d487d6fc0b5e133b2523678fa7f2dbc869d 100644 (file)
@@ -196,15 +196,17 @@ ao_usart_set_speed(struct ao_stm_usart *usart, uint8_t speed)
 
        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) |
@@ -247,16 +249,8 @@ ao_usart_init(struct ao_stm_usart *usart, int hw_flow)
                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
 
@@ -485,10 +479,20 @@ ao_serial_init(void)
         */
 
 #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,
@@ -498,28 +502,57 @@ ao_serial_init(void)
                                 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);
index b94316540017ef25931772685b2aeb946912b5b5..abaebc873637714580b25edb0edde6d2b59e7856 100644 (file)
@@ -39,7 +39,7 @@ stm_scb    = 0xe000ed00;
 
 stm_mpu    = 0xe000ed90;
 
-stm_dbg_mcu = 0xe0042000;
+stm_dbgmcu = 0xe0042000;
 
 /* data in system memory */
 stm_flash_data = 0x1ffff7e0;
index acb3b39ae14733fbc262b23a96592d3b94459c02..ba6f4db3550bdfb92401d9bbe046441dcd09172a 100644 (file)
@@ -355,6 +355,17 @@ extern struct stm_scb stm_scb;
 #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;
@@ -398,8 +409,8 @@ extern struct stm_flash stm_flash;
 #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 {