diff --git a/src/Kconfig b/src/Kconfig index 40bf427b..2d238c50 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -24,7 +24,7 @@ choice config MACH_STM32F1 bool "STMicroelectronics STM32F103" config MACH_STM32F4 - bool "STMicroelectronics STM32F446" + bool "STMicroelectronics STM32F4" config MACH_PRU bool "Beaglebone PRU" config MACH_LINUX diff --git a/src/stm32f4/Kconfig b/src/stm32f4/Kconfig index 7edf61b5..1a019be4 100644 --- a/src/stm32f4/Kconfig +++ b/src/stm32f4/Kconfig @@ -14,9 +14,40 @@ config BOARD_DIRECTORY string default "stm32f4" +choice + prompt "Processor model" + config MACH_STM32F405 + bool "STM32F405" + config MACH_STM32F407 + bool "STM32F407" + config MACH_STM32F446 + bool "STM32F446" +endchoice + +config MCU + string + default "stm32f405" if MACH_STM32F405 + default "stm32f407" if MACH_STM32F407 + default "stm32f446" if MACH_STM32F446 + config CLOCK_FREQ int - default 180000000 + default 168000000 if MACH_STM32F405 || MACH_STM32F407 + default 180000000 if MACH_STM32F446 + +config FLASH_SIZE + hex + default 0x80000 if MACH_STM32F405 || MACH_STM32F407 + default 0x80000 if MACH_STM32F446 + +config RAM_SIZE + hex + default 0x30000 if MACH_STM32F405 || MACH_STM32F407 + default 0x20000 if MACH_STM32F446 + +config STACK_SIZE + int + default 512 choice prompt "Clock Reference" diff --git a/src/stm32f4/Makefile b/src/stm32f4/Makefile index 1586a36f..bfd8a6cf 100644 --- a/src/stm32f4/Makefile +++ b/src/stm32f4/Makefile @@ -6,9 +6,13 @@ CROSS_PREFIX=arm-none-eabi- dirs-y += src/stm32f4 src/generic dirs-y += lib/stm32f4 lib/stm32f4/gcc +MCU := $(shell echo $(CONFIG_MCU) | tr a-z A-Z) +CFLAGS += -D$(MCU)xx + CFLAGS += -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard CFLAGS += -Ilib/cmsis-core -Ilib/stm32f4/include -CFLAGS += -DSTM32F446xx + +CFLAGS_klipper.elf += -T $(OUT)stm32f4.ld --specs=nano.specs --specs=nosys.specs # Add source files src-y += stm32f4/main.c stm32f4/clock.c stm32f4/watchdog.c stm32f4/gpio.c @@ -24,17 +28,14 @@ $(OUT)%.o: %.s $(OUT)autoconf.h $(OUT)board-link @echo " Assembling $@" $(Q)$(AS) $< -o $@ -asmsrc-y = ../lib/stm32f4/gcc/startup_stm32f446xx.s +asmsrc-y := ../lib/stm32f4/gcc/startup_$(shell echo $(CONFIG_MCU))xx.s OBJS_klipper.elf += $(patsubst %.s, $(OUT)src/%.o,$(asmsrc-y)) # Build the linker script -$(OUT)stm32f4.ld: src/stm32f4/stm32f4.ld $(OUT)board-link +$(OUT)stm32f4.ld: src/stm32f4/stm32f4.lds.S $(OUT)board-link @echo " Preprocessing $@" - $(Q)$(CPP) -P -MD -MT $@ -DFLASH_START=0 $< -o $@ - -CFLAGS_klipper.elf += -T $(OUT)stm32f4.ld -CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs -$(OUT)klipper.elf : $(OUT)stm32f4.ld + $(Q)$(CPP) -I$(OUT) -P -MD -MT $@ $< -o $@ +$(OUT)klipper.elf: $(OUT)stm32f4.ld # Binary output file rules target-y += $(OUT)klipper.bin diff --git a/src/stm32f4/clock.c b/src/stm32f4/clock.c index 5b98722a..bbd58aa5 100644 --- a/src/stm32f4/clock.c +++ b/src/stm32f4/clock.c @@ -1,4 +1,4 @@ -// Code to setup clocks on stm32f446 +// Code to setup clocks on stm32f4 // // Copyright (C) 2019 Kevin O'Connor // @@ -7,7 +7,7 @@ #include "autoconf.h" // CONFIG_STM32F4_CLOCK_REF_8M #include "internal.h" // enable_pclock -#define FREQ_PERIPH 45000000 +#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 4) // Enable a peripheral clock void @@ -35,10 +35,33 @@ get_pclock_frequency(uint32_t periph_base) return FREQ_PERIPH; } -// Main clock setup called at chip startup -void -clock_setup(void) +// Clock configuration +static void +enable_clock_stm32f40x(void) { +#if CONFIG_MACH_STM32F405 || CONFIG_MACH_STM32F407 + if (CONFIG_STM32F4_CLOCK_REF_8M) { + // Configure 168Mhz PLL from external 8Mhz crystal (HSE) + RCC->CR |= RCC_CR_HSEON; + RCC->PLLCFGR = ( + RCC_PLLCFGR_PLLSRC_HSE | (4 << RCC_PLLCFGR_PLLM_Pos) + | (168 << RCC_PLLCFGR_PLLN_Pos) | (0 << RCC_PLLCFGR_PLLP_Pos) + | (7 << RCC_PLLCFGR_PLLQ_Pos)); + } else { + // Configure 168Mhz PLL from internal 16Mhz oscillator (HSI) + RCC->PLLCFGR = ( + RCC_PLLCFGR_PLLSRC_HSI | (8 << RCC_PLLCFGR_PLLM_Pos) + | (168 << RCC_PLLCFGR_PLLN_Pos) | (0 << RCC_PLLCFGR_PLLP_Pos) + | (7 << RCC_PLLCFGR_PLLQ_Pos)); + } + RCC->CR |= RCC_CR_PLLON; +#endif +} + +static void +enable_clock_stm32f446(void) +{ +#if CONFIG_MACH_STM32F446 if (CONFIG_STM32F4_CLOCK_REF_8M) { // Configure 180Mhz PLL from external 8Mhz crystal (HSE) RCC->CR |= RCC_CR_HSEON; @@ -63,6 +86,17 @@ clock_setup(void) PWR->CR = (3 << PWR_CR_VOS_Pos) | PWR_CR_ODEN | PWR_CR_ODSWEN; while (!(PWR->CSR & PWR_CSR_ODSWRDY)) ; +#endif +} + +// Main clock setup called at chip startup +void +clock_setup(void) +{ + if (CONFIG_MACH_STM32F405 || CONFIG_MACH_STM32F407) + enable_clock_stm32f40x(); + else + enable_clock_stm32f446(); // Set flash latency FLASH->ACR = (FLASH_ACR_LATENCY_5WS | FLASH_ACR_ICEN | FLASH_ACR_DCEN diff --git a/src/stm32f4/main.c b/src/stm32f4/main.c index a1a60578..a6424770 100644 --- a/src/stm32f4/main.c +++ b/src/stm32f4/main.c @@ -4,11 +4,12 @@ // // This file may be distributed under the terms of the GNU GPLv3 license. +#include "autoconf.h" // CONFIG_MCU #include "command.h" // DECL_CONSTANT_STR #include "internal.h" // clock_setup #include "sched.h" // sched_main -DECL_CONSTANT_STR("MCU", "stm32f446"); +DECL_CONSTANT_STR("MCU", CONFIG_MCU); void command_reset(uint32_t *args) diff --git a/src/stm32f4/stm32f4.ld b/src/stm32f4/stm32f4.ld deleted file mode 100644 index 84df83fc..00000000 --- a/src/stm32f4/stm32f4.ld +++ /dev/null @@ -1,109 +0,0 @@ -/* Cortex-M linker script */ - -ENTRY(Reset_Handler) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x08000000 + FLASH_START, LENGTH = 512K - FLASH_START - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K -} - -/* highest address of the user mode stack */ -_estack = 0x20005000; - -SECTIONS -{ - /* Interrupt vector table */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) - . = ALIGN(4); - } >FLASH - - /* Program code and constant data */ - .text : - { - . = ALIGN(4); - *(.text) - *(.text*) - *(.rodata) - *(.rodata*) - KEEP (*(.init)) - KEEP (*(.fini)) - . = ALIGN(4); - _etext = .; - } >FLASH - - /* Exception handling */ - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >FLASH - - /* Static constructor initialization (C++) */ - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - - /* Initialized data, needs to be handled by startup code */ - _sidata = .; - .data : AT (_sidata) - { - . = ALIGN(4); - _sdata = . ; - _data = . ; - *(.data) - *(.data*) - *(.RAMtext) - . = ALIGN(4); - _edata = . ; - } >RAM - - /* Uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = .; - __bss_start__ = .; - _bss = .; - *(.bss) - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - __bss_end__ = _ebss; - } >RAM - - /* Pointers to end of data for dynamic memory management */ - PROVIDE (end = _ebss); - PROVIDE (_end = _ebss); - - /* Remove debugging from standard libraries */ - /DISCARD/ : - { - libc.a (*) - libm.a (*) - libgcc.a (*) - } -} diff --git a/src/stm32f4/stm32f4.lds.S b/src/stm32f4/stm32f4.lds.S new file mode 100644 index 00000000..17edd23a --- /dev/null +++ b/src/stm32f4/stm32f4.lds.S @@ -0,0 +1,63 @@ +/* Linker script for stm32f4 chips + * + * Copyright (C) 2019 Kevin O'Connor + * + * This file may be distributed under the terms of the GNU GPLv3 license. + */ + +#include "autoconf.h" + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +MEMORY +{ + rom (rx) : ORIGIN = 0x8000000 + CONFIG_FLASH_START , LENGTH = CONFIG_FLASH_SIZE + ram (rwx) : ORIGIN = 0x20000000, LENGTH = CONFIG_RAM_SIZE +} + +SECTIONS +{ + .text : { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.isr_vector)) + *(.text .text.*) + *(.rodata .rodata*) + + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + KEEP(*(.fini)) + } > rom + + . = ALIGN(4); + _sidata = .; + + .data : AT (_sidata) + { + . = ALIGN(4); + _sdata = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _edata = .; + } > ram + + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } > ram + + _sstack = 0x20000000 + CONFIG_RAM_SIZE - CONFIG_STACK_SIZE ; + .stack _sstack (NOLOAD) : + { + . = . + CONFIG_STACK_SIZE; + _estack = .; + } > ram +}