stm32: Resync stm32 code with upstream Klipper code

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2022-12-15 18:33:51 -05:00 committed by Eric Callahan
parent 6f67a01a60
commit bcff5ca488
12 changed files with 387 additions and 58 deletions

View File

@ -2,6 +2,7 @@
#define __COMMAND_H #define __COMMAND_H
#include <stdarg.h> // va_list #include <stdarg.h> // va_list
#include <stddef.h>
#include <stdint.h> // uint32_t #include <stdint.h> // uint32_t
#include "ctr.h" // DECL_CTR #include "ctr.h" // DECL_CTR

View File

@ -9,7 +9,7 @@ config STM32_SELECT
select HAVE_GPIO_ADC select HAVE_GPIO_ADC
select HAVE_GPIO_I2C if !(MACH_STM32F031 || MACH_STM32H7) select HAVE_GPIO_I2C if !(MACH_STM32F031 || MACH_STM32H7)
select HAVE_GPIO_SPI if !MACH_STM32F031 select HAVE_GPIO_SPI if !MACH_STM32F031
select HAVE_GPIO_HARD_PWM if MACH_STM32F1 || MACH_STM32F4 || MACH_STM32H7 select HAVE_GPIO_HARD_PWM if MACH_STM32F1 || MACH_STM32F4 || MACH_STM32G0 || MACH_STM32H7
select HAVE_GPIO_BITBANGING if !MACH_STM32F031 select HAVE_GPIO_BITBANGING if !MACH_STM32F031
select HAVE_STRICT_TIMING select HAVE_STRICT_TIMING
select HAVE_CHIPID select HAVE_CHIPID
@ -64,15 +64,29 @@ choice
bool "STM32F072" bool "STM32F072"
select MACH_STM32F0 select MACH_STM32F0
select MACH_STM32F0x2 select MACH_STM32F0x2
config MACH_STM32G0B0
bool "STM32G0B0"
select MACH_STM32G0
select MACH_STM32G0Bx
config MACH_STM32G0B1 config MACH_STM32G0B1
bool "STM32G0B1" bool "STM32G0B1"
select MACH_STM32G0 select MACH_STM32G0
select MACH_STM32G0Bx
config MACH_STM32G431
bool "STM32G431" if 0
select MACH_STM32G4
config MACH_STM32H723
bool "STM32H723" if 0
select MACH_STM32H7
config MACH_STM32H743 config MACH_STM32H743
bool "STM32H743" if 0 bool "STM32H743" if 0
select MACH_STM32H7 select MACH_STM32H7
config MACH_STM32H750 config MACH_STM32H750
bool "STM32H750" if 0 bool "STM32H750" if 0
select MACH_STM32H7 select MACH_STM32H7
config MACH_STM32L412
bool "STM32L412" if 0
select MACH_STM32L4
endchoice endchoice
config MACH_STM32F103x6 config MACH_STM32F103x6
@ -89,15 +103,21 @@ config MACH_STM32F4
bool bool
config MACH_STM32G0 config MACH_STM32G0
bool bool
config MACH_STM32G0Bx
bool
config MACH_STM32G4
bool
config MACH_STM32H7 config MACH_STM32H7
bool bool
config MACH_STM32F0x2 # F042, F072 series config MACH_STM32F0x2 # F042, F072 series
bool bool
config MACH_STM32F4x5 # F405, F407, F429 series config MACH_STM32F4x5 # F405, F407, F429 series
bool bool
config MACH_STM32L4
bool
config HAVE_STM32_USBFS config HAVE_STM32_USBFS
bool bool
default y if MACH_STM32F0x2 || MACH_STM32G0 default y if MACH_STM32F0x2 || MACH_STM32G0Bx || MACH_STM32L4 || MACH_STM32G4
default y if (MACH_STM32F103 || MACH_STM32F070) && !STM32_CLOCK_REF_INTERNAL default y if (MACH_STM32F103 || MACH_STM32F070) && !STM32_CLOCK_REF_INTERNAL
config HAVE_STM32_USBOTG config HAVE_STM32_USBOTG
bool bool
@ -107,7 +127,9 @@ config HAVE_STM32_CANBUS
default y if MACH_STM32F1 || MACH_STM32F2 || MACH_STM32F4x5 || MACH_STM32F446 || MACH_STM32F0x2 default y if MACH_STM32F1 || MACH_STM32F2 || MACH_STM32F4x5 || MACH_STM32F446 || MACH_STM32F0x2
config HAVE_STM32_FDCANBUS config HAVE_STM32_FDCANBUS
bool bool
default y if MACH_STM32G0 default y if MACH_STM32G0B1 || MACH_STM32H7 || MACH_STM32G4
config HAVE_STM32_USBCANBUS
bool
config MCU config MCU
string string
@ -122,9 +144,13 @@ config MCU
default "stm32f407xx" if MACH_STM32F407 default "stm32f407xx" if MACH_STM32F407
default "stm32f429xx" if MACH_STM32F429 default "stm32f429xx" if MACH_STM32F429
default "stm32f446xx" if MACH_STM32F446 default "stm32f446xx" if MACH_STM32F446
default "stm32g0b0xx" if MACH_STM32G0B0
default "stm32g0b1xx" if MACH_STM32G0B1 default "stm32g0b1xx" if MACH_STM32G0B1
default "stm32g431xx" if MACH_STM32G431
default "stm32h723xx" if MACH_STM32H723
default "stm32h743xx" if MACH_STM32H743 default "stm32h743xx" if MACH_STM32H743
default "stm32h750xx" if MACH_STM32H750 default "stm32h750xx" if MACH_STM32H750
default "stm32l412xx" if MACH_STM32L412
config CLOCK_FREQ config CLOCK_FREQ
int int
@ -136,31 +162,28 @@ config CLOCK_FREQ
default 168000000 if MACH_STM32F4x5 default 168000000 if MACH_STM32F4x5
default 180000000 if MACH_STM32F446 default 180000000 if MACH_STM32F446
default 64000000 if MACH_STM32G0 default 64000000 if MACH_STM32G0
default 150000000 if MACH_STM32G431
default 400000000 if MACH_STM32H7 # 400Mhz is max Klipper currently supports default 400000000 if MACH_STM32H7 # 400Mhz is max Klipper currently supports
default 80000000 if MACH_STM32L412
config FLASH_START
hex
default 0x8000000
config FLASH_BOOT_ADDRESS
hex
default 0x8000000
config FLASH_SIZE config FLASH_SIZE
hex hex
default 0x4000 if MACH_STM32F031 default 0x4000 if MACH_STM32F031
default 0x8000 if MACH_STM32F042 default 0x8000 if MACH_STM32F042
default 0x20000 if MACH_STM32F070 || MACH_STM32F072 default 0x20000 if MACH_STM32F070 || MACH_STM32F072
default 0x10000 if MACH_STM32F103 # Flash size of stm32f103x8 (64KiB) default 0x10000 if MACH_STM32F103 || MACH_STM32L412 # Flash size of stm32f103x8 (64KiB)
default 0x40000 if MACH_STM32F2 || MACH_STM32F401 default 0x40000 if MACH_STM32F2 || MACH_STM32F401 || MACH_STM32H723
default 0x80000 if MACH_STM32F4x5 || MACH_STM32F446 default 0x80000 if MACH_STM32F4x5 || MACH_STM32F446
default 0x20000 if MACH_STM32G0B1 default 0x20000 if MACH_STM32G0 || MACH_STM32G431
default 0x20000 if MACH_STM32H750 default 0x20000 if MACH_STM32H750
default 0x200000 if MACH_STM32H743 default 0x200000 if MACH_STM32H743
config FLASH_BOOT_ADDRESS
hex
default 0x8000000
config RAM_START config RAM_START
hex hex
default 0x24000000 if MACH_STM32H743
default 0x20000000 default 0x20000000
config RAM_SIZE config RAM_SIZE
@ -170,12 +193,13 @@ config RAM_SIZE
default 0x4000 if MACH_STM32F070 || MACH_STM32F072 default 0x4000 if MACH_STM32F070 || MACH_STM32F072
default 0x2800 if MACH_STM32F103x6 default 0x2800 if MACH_STM32F103x6
default 0x5000 if MACH_STM32F103 && !MACH_STM32F103x6 # Ram size of stm32f103x8 default 0x5000 if MACH_STM32F103 && !MACH_STM32F103x6 # Ram size of stm32f103x8
default 0x8000 if MACH_STM32G431
default 0xa000 if MACH_STM32L412
default 0x20000 if MACH_STM32F207 default 0x20000 if MACH_STM32F207
default 0x10000 if MACH_STM32F401 default 0x10000 if MACH_STM32F401
default 0x20000 if MACH_STM32F4x5 || MACH_STM32F446 default 0x20000 if MACH_STM32F4x5 || MACH_STM32F446
default 0x24000 if MACH_STM32G0B1 default 0x24000 if MACH_STM32G0Bx
default 0x20000 if MACH_STM32H750 default 0x20000 if MACH_STM32H7
default 0x80000 if MACH_STM32H743
config STACK_SIZE config STACK_SIZE
int int
@ -191,6 +215,15 @@ config STM32F103GD_DISABLE_SWD
and PA14 pins from being available. Selecting this option and PA14 pins from being available. Selecting this option
disables SWD at startup and thus makes these pins available. disables SWD at startup and thus makes these pins available.
config STM32_DFU_ROM_ADDRESS
hex
default 0 if !USB
default 0x1fffc400 if MACH_STM32F042
default 0x1fffc800 if MACH_STM32F072
default 0x1fff0000 if MACH_STM32F4 || MACH_STM32G0 || MACH_STM32G4 || MACH_STM32L4
default 0x1ff09800 if MACH_STM32H7
default 0
###################################################################### ######################################################################
# Bootloader # Bootloader
@ -224,7 +257,7 @@ choice
config STM32_FLASH_START_4000 config STM32_FLASH_START_4000
bool "16KiB bootloader (HID Bootloader)" if MACH_STM32F207 || MACH_STM32F401 || MACH_STM32F4x5 || MACH_STM32F103 || MACH_STM32F072 bool "16KiB bootloader (HID Bootloader)" if MACH_STM32F207 || MACH_STM32F401 || MACH_STM32F4x5 || MACH_STM32F103 || MACH_STM32F072
config STM32_FLASH_START_20000 config STM32_FLASH_START_20000
bool "128KiB bootloader (SKR SE BX v2.0)" if MACH_STM32H743 bool "128KiB bootloader (SKR SE BX v2.0)" if MACH_STM32H743 || MACH_STM32H723
endchoice endchoice
config FLASH_APPLICATION_ADDRESS config FLASH_APPLICATION_ADDRESS
hex hex
@ -260,6 +293,8 @@ choice
bool "12 MHz crystal" bool "12 MHz crystal"
config STM32_CLOCK_REF_16M config STM32_CLOCK_REF_16M
bool "16 MHz crystal" bool "16 MHz crystal"
config STM32_CLOCK_REF_20M
bool "20 MHz crystal"
config STM32_CLOCK_REF_25M config STM32_CLOCK_REF_25M
bool "25 MHz crystal" bool "25 MHz crystal"
config STM32_CLOCK_REF_INTERNAL config STM32_CLOCK_REF_INTERNAL
@ -268,6 +303,7 @@ endchoice
config CLOCK_REF_FREQ config CLOCK_REF_FREQ
int int
default 25000000 if STM32_CLOCK_REF_25M default 25000000 if STM32_CLOCK_REF_25M
default 20000000 if STM32_CLOCK_REF_20M
default 16000000 if STM32_CLOCK_REF_16M default 16000000 if STM32_CLOCK_REF_16M
default 12000000 if STM32_CLOCK_REF_12M default 12000000 if STM32_CLOCK_REF_12M
default 1 if STM32_CLOCK_REF_INTERNAL default 1 if STM32_CLOCK_REF_INTERNAL
@ -297,7 +333,7 @@ choice
select USBSERIAL select USBSERIAL
config STM32_USB_PB14_PB15 config STM32_USB_PB14_PB15
bool "USB (on PB14/PB15)" bool "USB (on PB14/PB15)"
depends on MACH_STM32H7 depends on MACH_STM32H743 || MACH_STM32H750
select USBSERIAL select USBSERIAL
config STM32_SERIAL_USART1 config STM32_SERIAL_USART1
bool "Serial (on USART1 PA10/PA9)" bool "Serial (on USART1 PA10/PA9)"
@ -309,7 +345,10 @@ choice
bool "Serial (on USART2 PA3/PA2)" if LOW_LEVEL_OPTIONS bool "Serial (on USART2 PA3/PA2)" if LOW_LEVEL_OPTIONS
select SERIAL select SERIAL
config STM32_SERIAL_USART2_ALT_PA15_PA14 config STM32_SERIAL_USART2_ALT_PA15_PA14
bool "Serial (on USART2 PA15/PA14)" if LOW_LEVEL_OPTIONS && MACH_STM32F0 bool "Serial (on USART2 PA15/PA14)" if LOW_LEVEL_OPTIONS && (MACH_STM32F0 || MACH_STM32G4)
select SERIAL
config STM32_SERIAL_USART2_ALT_PB4_PB3
bool "Serial (on USART2 PB4/PB3)" if LOW_LEVEL_OPTIONS && MACH_STM32G4
select SERIAL select SERIAL
config STM32_SERIAL_USART2_ALT_PD6_PD5 config STM32_SERIAL_USART2_ALT_PD6_PD5
bool "Serial (on USART2 PD6/PD5)" if LOW_LEVEL_OPTIONS && !MACH_STM32F0 bool "Serial (on USART2 PD6/PD5)" if LOW_LEVEL_OPTIONS && !MACH_STM32F0
@ -334,36 +373,109 @@ choice
bool "CAN bus (on PA9/PA10)" if LOW_LEVEL_OPTIONS bool "CAN bus (on PA9/PA10)" if LOW_LEVEL_OPTIONS
depends on HAVE_STM32_CANBUS && MACH_STM32F042 depends on HAVE_STM32_CANBUS && MACH_STM32F042
select CANSERIAL select CANSERIAL
config STM32_CANBUS_PB8_PB9 config STM32_CANBUS_PA11_PB9
bool "CAN bus (on PA11/PB9)"
depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS
select CANSERIAL
config STM32_MMENU_CANBUS_PB8_PB9
bool "CAN bus (on PB8/PB9)" if LOW_LEVEL_OPTIONS bool "CAN bus (on PB8/PB9)" if LOW_LEVEL_OPTIONS
depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS
select CANSERIAL select CANSERIAL
config STM32_CANBUS_PI9_PH13 config STM32_MMENU_CANBUS_PI9_PH13
bool "CAN bus (on PI9/PH13)" if LOW_LEVEL_OPTIONS bool "CAN bus (on PI9/PH13)" if LOW_LEVEL_OPTIONS
depends on HAVE_STM32_CANBUS && MACH_STM32F4 depends on HAVE_STM32_CANBUS && MACH_STM32F4
select CANSERIAL select CANSERIAL
config STM32_CANBUS_PB5_PB6 config STM32_MMENU_CANBUS_PB5_PB6
bool "CAN bus (on PB5/PB6)" if LOW_LEVEL_OPTIONS bool "CAN bus (on PB5/PB6)" if LOW_LEVEL_OPTIONS
depends on HAVE_STM32_CANBUS && MACH_STM32F4 depends on HAVE_STM32_CANBUS && MACH_STM32F4
select CANSERIAL select CANSERIAL
config STM32_CANBUS_PB12_PB13 config STM32_MMENU_CANBUS_PB12_PB13
bool "CAN bus (on PB12/PB13)" if LOW_LEVEL_OPTIONS bool "CAN bus (on PB12/PB13)" if LOW_LEVEL_OPTIONS
depends on HAVE_STM32_CANBUS && MACH_STM32F4 depends on HAVE_STM32_CANBUS && MACH_STM32F4
select CANSERIAL select CANSERIAL
config STM32_CANBUS_PD0_PD1 config STM32_MMENU_CANBUS_PD0_PD1
bool "CAN bus (on PD0/PD1)" if LOW_LEVEL_OPTIONS bool "CAN bus (on PD0/PD1)" if LOW_LEVEL_OPTIONS
depends on HAVE_STM32_CANBUS depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS
select CANSERIAL select CANSERIAL
config STM32_CANBUS_PB0_PB1 config STM32_MMENU_CANBUS_PB0_PB1
bool "CAN bus (on PB0/PB1)" bool "CAN bus (on PB0/PB1)"
depends on HAVE_STM32_FDCANBUS depends on HAVE_STM32_FDCANBUS
select CANSERIAL select CANSERIAL
config STM32_MMENU_CANBUS_PD12_PD13
bool "CAN bus (on PD12/PD13)"
depends on HAVE_STM32_FDCANBUS
select CANSERIAL
config STM32_MMENU_CANBUS_PC2_PC3
bool "CAN bus (on PC2/PC3)"
depends on HAVE_STM32_FDCANBUS
select CANSERIAL
config STM32_USBCANBUS_PA11_PA12
bool "USB to CAN bus bridge (USB on PA11/PA12)"
depends on HAVE_STM32_USBCANBUS
select USBCANBUS
endchoice endchoice
choice
prompt "CAN bus interface" if USBCANBUS
config STM32_CMENU_CANBUS_PB8_PB9
bool "CAN bus (on PB8/PB9)"
config STM32_CMENU_CANBUS_PI9_PH13
bool "CAN bus (on PI9/PH13)"
depends on HAVE_STM32_CANBUS && MACH_STM32F4
config STM32_CMENU_CANBUS_PB5_PB6
bool "CAN bus (on PB5/PB6)"
depends on HAVE_STM32_CANBUS && MACH_STM32F4
config STM32_CMENU_CANBUS_PB12_PB13
bool "CAN bus (on PB12/PB13)"
depends on HAVE_STM32_CANBUS && MACH_STM32F4
config STM32_CMENU_CANBUS_PD0_PD1
bool "CAN bus (on PD0/PD1)"
depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS
config STM32_CMENU_CANBUS_PB0_PB1
bool "CAN bus (on PB0/PB1)"
depends on HAVE_STM32_FDCANBUS
config STM32_CMENU_CANBUS_PD12_PD13
bool "CAN bus (on PD12/PD13)"
depends on HAVE_STM32_FDCANBUS
config STM32_CMENU_CANBUS_PC2_PC3
bool "CAN bus (on PC2/PC3)"
depends on HAVE_STM32_FDCANBUS
endchoice
config STM32_CANBUS_PB8_PB9
bool
default y if STM32_MMENU_CANBUS_PB8_PB9 || STM32_CMENU_CANBUS_PB8_PB9
config STM32_CANBUS_PI9_PH13
bool
default y if STM32_MMENU_CANBUS_PI9_PH13 || STM32_CMENU_CANBUS_PI9_PH13
config STM32_CANBUS_PB5_PB6
bool
default y if STM32_MMENU_CANBUS_PB5_PB6 || STM32_CMENU_CANBUS_PB5_PB6
config STM32_CANBUS_PB12_PB13
bool
default y if STM32_MMENU_CANBUS_PB12_PB13 || STM32_CMENU_CANBUS_PB12_PB13
config STM32_CANBUS_PD0_PD1
bool
default y if STM32_MMENU_CANBUS_PD0_PD1 || STM32_CMENU_CANBUS_PD0_PD1
config STM32_CANBUS_PB0_PB1
bool
default y if STM32_MMENU_CANBUS_PB0_PB1 || STM32_CMENU_CANBUS_PB0_PB1
config STM32_CANBUS_PD12_PD13
bool
default y if STM32_MMENU_CANBUS_PD12_PD13 || STM32_CMENU_CANBUS_PD12_PD13
config STM32_CANBUS_PC2_PC3
bool
default y if STM32_MMENU_CANBUS_PC2_PC3 || STM32_CMENU_CANBUS_PC2_PC3
###################################################################### ######################################################################
# Flash settings # Flash settings
###################################################################### ######################################################################
config FLASH_START
hex
default 0x8000000
choice choice
prompt "Application start offset" prompt "Application start offset"
config STM32_APP_START_8000 config STM32_APP_START_8000

View File

@ -25,7 +25,7 @@ CFLAGS_canboot.elf += -T $(OUT)src/generic/armcm_link.ld
$(OUT)canboot.elf: $(OUT)src/generic/armcm_link.ld $(OUT)canboot.elf: $(OUT)src/generic/armcm_link.ld
# Add source files # Add source files
mcu-y = stm32/gpio.c stm32/flash.c stm32/clockline.c mcu-y = stm32/gpio.c stm32/flash.c stm32/clockline.c stm32/dfu_reboot.c
mcu-y += generic/armcm_irq.c generic/crc16_ccitt.c mcu-y += generic/armcm_irq.c generic/crc16_ccitt.c
mcu-$(CONFIG_MACH_STM32F0) += ../lib/stm32f0/system_stm32f0xx.c mcu-$(CONFIG_MACH_STM32F0) += ../lib/stm32f0/system_stm32f0xx.c
mcu-$(CONFIG_MACH_STM32F0) += stm32/stm32f0.c stm32/stm32f0_timer.c mcu-$(CONFIG_MACH_STM32F0) += stm32/stm32f0.c stm32/stm32f0_timer.c

19
src/stm32/dfu_reboot.c Normal file
View File

@ -0,0 +1,19 @@
// Reboot into stm32 ROM dfu bootloader
//
// Copyright (C) 2019-2022 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include "internal.h" // NVIC_SystemReset
// Flag that bootloader is desired and reboot
void
dfu_reboot(void)
{
}
// Check if rebooting into system DFU Bootloader
void
dfu_reboot_check(void)
{
}

View File

@ -14,8 +14,12 @@
#include "stm32f4xx.h" #include "stm32f4xx.h"
#elif CONFIG_MACH_STM32G0 #elif CONFIG_MACH_STM32G0
#include "stm32g0xx.h" #include "stm32g0xx.h"
#elif CONFIG_MACH_STM32G4
#include "stm32g4xx.h"
#elif CONFIG_MACH_STM32H7 #elif CONFIG_MACH_STM32H7
#include "stm32h7xx.h" #include "stm32h7xx.h"
#elif CONFIG_MACH_STM32L4
#include "stm32l4xx.h"
#endif #endif
// gpio.c // gpio.c
@ -36,6 +40,10 @@ void gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup);
void enable_pclock(uint32_t periph_base); void enable_pclock(uint32_t periph_base);
int is_enabled_pclock(uint32_t periph_base); int is_enabled_pclock(uint32_t periph_base);
// dfu_reboot.c
void dfu_reboot(void);
void dfu_reboot_check(void);
// stm32??.c // stm32??.c
struct cline { volatile uint32_t *en, *rst; uint32_t bit; }; struct cline { volatile uint32_t *en, *rst; uint32_t bit; };
struct cline lookup_clock_line(uint32_t periph_base); struct cline lookup_clock_line(uint32_t periph_base);

View File

@ -57,8 +57,11 @@ void
USARTx_IRQHandler(void) USARTx_IRQHandler(void)
{ {
uint32_t sr = USARTx->SR; uint32_t sr = USARTx->SR;
if (sr & (USART_SR_RXNE | USART_SR_ORE)) if (sr & (USART_SR_RXNE | USART_SR_ORE)) {
// The ORE flag is automatically cleared by reading SR, followed
// by reading DR.
serial_rx_byte(USARTx->DR); serial_rx_byte(USARTx->DR);
}
if (sr & USART_SR_TXE && USARTx->CR1 & USART_CR1_TXEIE) { if (sr & USART_SR_TXE && USARTx->CR1 & USART_CR1_TXEIE) {
uint8_t data; uint8_t data;
int ret = serial_get_tx_byte(&data); int ret = serial_get_tx_byte(&data);

View File

@ -6,7 +6,9 @@
#include "autoconf.h" // CONFIG_CLOCK_REF_FREQ #include "autoconf.h" // CONFIG_CLOCK_REF_FREQ
#include "board/armcm_boot.h" // armcm_main #include "board/armcm_boot.h" // armcm_main
#include "board/armcm_reset.h" // try_request_canboot
#include "board/irq.h" // irq_disable #include "board/irq.h" // irq_disable
#include "board/misc.h" // bootloader_request
#include "command.h" // DECL_CONSTANT_STR #include "command.h" // DECL_CONSTANT_STR
#include "deployer.h" // deployer_is_active #include "deployer.h" // deployer_is_active
#include "internal.h" // enable_pclock #include "internal.h" // enable_pclock
@ -85,7 +87,7 @@ pll_setup(void)
// Setup CFGR3 register // Setup CFGR3 register
uint32_t cfgr3 = RCC_CFGR3_I2C1SW; uint32_t cfgr3 = RCC_CFGR3_I2C1SW;
#if CONFIG_USBSERIAL #if CONFIG_USB
// Select PLL as source for USB clock // Select PLL as source for USB clock
cfgr3 |= RCC_CFGR3_USBSW; cfgr3 |= RCC_CFGR3_USBSW;
#endif #endif
@ -108,7 +110,7 @@ hsi48_setup(void)
; ;
// Enable USB clock recovery // Enable USB clock recovery
if (CONFIG_USBSERIAL) { if (CONFIG_USB) {
enable_pclock(CRS_BASE); enable_pclock(CRS_BASE);
CRS->CR |= CRS_CR_AUTOTRIMEN | CRS_CR_CEN; CRS->CR |= CRS_CR_AUTOTRIMEN | CRS_CR_CEN;
} }
@ -128,6 +130,20 @@ hsi14_setup(void)
; ;
} }
/****************************************************************
* Bootloader
****************************************************************/
// Handle reboot requests
void
bootloader_request(void)
{
try_request_canboot();
dfu_reboot();
}
/**************************************************************** /****************************************************************
* Startup * Startup
****************************************************************/ ****************************************************************/
@ -151,6 +167,7 @@ enable_ram_vectortable(void)
void void
armcm_main(void) armcm_main(void)
{ {
dfu_reboot_check();
SystemInit(); SystemInit();
enable_pclock(SYSCFG_BASE); enable_pclock(SYSCFG_BASE);
@ -161,8 +178,7 @@ armcm_main(void)
FLASH->ACR = (1 << FLASH_ACR_LATENCY_Pos) | FLASH_ACR_PRFTBE; FLASH->ACR = (1 << FLASH_ACR_LATENCY_Pos) | FLASH_ACR_PRFTBE;
// Configure main clock // Configure main clock
if (CONFIG_MACH_STM32F0x2 && CONFIG_STM32_CLOCK_REF_INTERNAL if (CONFIG_MACH_STM32F0x2 && CONFIG_STM32_CLOCK_REF_INTERNAL && CONFIG_USB)
&& CONFIG_USBSERIAL)
hsi48_setup(); hsi48_setup();
else else
pll_setup(); pll_setup();

View File

@ -16,30 +16,68 @@
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA10,PA9"); DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA10,PA9");
#define GPIO_Rx GPIO('A', 10) #define GPIO_Rx GPIO('A', 10)
#define GPIO_Tx GPIO('A', 9) #define GPIO_Tx GPIO('A', 9)
#define USARTx_FUNCTION GPIO_FUNCTION(1) #define USARTx_FUNCTION GPIO_FUNCTION( \
(CONFIG_MACH_STM32H7 | CONFIG_MACH_STM32G4) ? 7 : 1)
#define USARTx USART1 #define USARTx USART1
#define USARTx_IRQn USART1_IRQn #define USARTx_IRQn USART1_IRQn
#elif CONFIG_STM32_SERIAL_USART1_ALT_PB7_PB6 #elif CONFIG_STM32_SERIAL_USART1_ALT_PB7_PB6
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PB7,PB6"); DECL_CONSTANT_STR("RESERVE_PINS_serial", "PB7,PB6");
#define GPIO_Rx GPIO('B', 7) #define GPIO_Rx GPIO('B', 7)
#define GPIO_Tx GPIO('B', 6) #define GPIO_Tx GPIO('B', 6)
#define USARTx_FUNCTION GPIO_FUNCTION(0) #define USARTx_FUNCTION GPIO_FUNCTION( \
(CONFIG_MACH_STM32H7 | CONFIG_MACH_STM32G4) ? 7 : 0)
#define USARTx USART1 #define USARTx USART1
#define USARTx_IRQn USART1_IRQn #define USARTx_IRQn USART1_IRQn
#elif CONFIG_STM32_SERIAL_USART2 #elif CONFIG_STM32_SERIAL_USART2
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA3,PA2"); DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA3,PA2");
#define GPIO_Rx GPIO('A', 3) #define GPIO_Rx GPIO('A', 3)
#define GPIO_Tx GPIO('A', 2) #define GPIO_Tx GPIO('A', 2)
#define USARTx_FUNCTION GPIO_FUNCTION(1) #define USARTx_FUNCTION GPIO_FUNCTION( \
(CONFIG_MACH_STM32H7 | CONFIG_MACH_STM32G4) ? 7 : 1)
#define USARTx USART2 #define USARTx USART2
#define USARTx_IRQn USART2_IRQn #define USARTx_IRQn USART2_IRQn
#elif CONFIG_STM32_SERIAL_USART2_ALT_PA15_PA14 #elif CONFIG_STM32_SERIAL_USART2_ALT_PA15_PA14
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA15,PA14"); DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA15,PA14");
#define GPIO_Rx GPIO('A', 15) #define GPIO_Rx GPIO('A', 15)
#define GPIO_Tx GPIO('A', 14) #define GPIO_Tx GPIO('A', 14)
#define USARTx_FUNCTION GPIO_FUNCTION(1) #define USARTx_FUNCTION GPIO_FUNCTION(CONFIG_MACH_STM32G4 ? 7 : 1)
#define USARTx USART2 #define USARTx USART2
#define USARTx_IRQn USART2_IRQn #define USARTx_IRQn USART2_IRQn
#elif CONFIG_STM32_SERIAL_USART2_ALT_PB4_PB3
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PB4,PB3");
#define GPIO_Rx GPIO('B', 4)
#define GPIO_Tx GPIO('B', 3)
#define USARTx_FUNCTION GPIO_FUNCTION(7)
#define USARTx USART2
#define USARTx_IRQn USART2_IRQn
#elif CONFIG_STM32_SERIAL_USART2_ALT_PD6_PD5
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PD6,PD5");
#define GPIO_Rx GPIO('D', 6)
#define GPIO_Tx GPIO('D', 5)
#define USARTx_FUNCTION GPIO_FUNCTION(7)
#define USARTx USART2
#define USARTx_IRQn USART2_IRQn
#elif CONFIG_STM32_SERIAL_USART3
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PB11,PB10");
#define GPIO_Rx GPIO('B', 11)
#define GPIO_Tx GPIO('B', 10)
#define USARTx_FUNCTION GPIO_FUNCTION(7)
#define USARTx USART3
#define USARTx_IRQn USART3_IRQn
#elif CONFIG_STM32_SERIAL_USART3_ALT_PD9_PD8
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PD9,PD8");
#define GPIO_Rx GPIO('D', 9)
#define GPIO_Tx GPIO('D', 8)
#define USARTx_FUNCTION GPIO_FUNCTION(7)
#define USARTx USART3
#define USARTx_IRQn USART3_IRQn
#elif CONFIG_STM32_SERIAL_UART4
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA1,PA0");
#define GPIO_Rx GPIO('A', 1)
#define GPIO_Tx GPIO('A', 0)
#define USARTx_FUNCTION GPIO_FUNCTION(8)
#define USARTx UART4
#define USARTx_IRQn UART4_IRQn
#endif #endif
#if CONFIG_MACH_STM32F031 #if CONFIG_MACH_STM32F031
@ -49,14 +87,23 @@
#endif #endif
#if CONFIG_MACH_STM32G0 #if CONFIG_MACH_STM32G0
// The stm32g0 has slightly different register names // Some of the stm32g0 MCUs have slightly different register names
#if CONFIG_MACH_STM32G0B1
#define USART2_IRQn USART2_LPUART2_IRQn #define USART2_IRQn USART2_LPUART2_IRQn
#endif
#define USART_CR1_RXNEIE USART_CR1_RXNEIE_RXFNEIE #define USART_CR1_RXNEIE USART_CR1_RXNEIE_RXFNEIE
#define USART_CR1_TXEIE USART_CR1_TXEIE_TXFNFIE #define USART_CR1_TXEIE USART_CR1_TXEIE_TXFNFIE
#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE #define USART_ISR_RXNE USART_ISR_RXNE_RXFNE
#define USART_ISR_TXE USART_ISR_TXE_TXFNF #define USART_ISR_TXE USART_ISR_TXE_TXFNF
#define USART_BRR_DIV_MANTISSA_Pos 4 #define USART_BRR_DIV_MANTISSA_Pos 4
#define USART_BRR_DIV_FRACTION_Pos 0 #define USART_BRR_DIV_FRACTION_Pos 0
#elif CONFIG_MACH_STM32G4
#define USART_BRR_DIV_MANTISSA_Pos 4
#define USART_BRR_DIV_FRACTION_Pos 0
#elif CONFIG_MACH_STM32H7
// The stm32h7 has slightly different register names
#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE
#define USART_ISR_TXE USART_ISR_TXE_TXFNF
#endif #endif
#define CR1_FLAGS (USART_CR1_UE | USART_CR1_RE | USART_CR1_TE \ #define CR1_FLAGS (USART_CR1_UE | USART_CR1_RE | USART_CR1_TE \
@ -66,7 +113,7 @@ void
USARTx_IRQHandler(void) USARTx_IRQHandler(void)
{ {
uint32_t sr = USARTx->ISR; uint32_t sr = USARTx->ISR;
if (sr & (USART_ISR_RXNE | USART_ISR_ORE)) if (sr & USART_ISR_RXNE)
serial_rx_byte(USARTx->RDR); serial_rx_byte(USARTx->RDR);
if (sr & USART_ISR_TXE && USARTx->CR1 & USART_CR1_TXEIE) { if (sr & USART_ISR_TXE && USARTx->CR1 & USART_CR1_TXEIE) {
uint8_t data; uint8_t data;
@ -93,6 +140,7 @@ serial_init(void)
uint32_t div = DIV_ROUND_CLOSEST(pclk, CONFIG_SERIAL_BAUD); uint32_t div = DIV_ROUND_CLOSEST(pclk, CONFIG_SERIAL_BAUD);
USARTx->BRR = (((div / 16) << USART_BRR_DIV_MANTISSA_Pos) USARTx->BRR = (((div / 16) << USART_BRR_DIV_MANTISSA_Pos)
| ((div % 16) << USART_BRR_DIV_FRACTION_Pos)); | ((div % 16) << USART_BRR_DIV_FRACTION_Pos));
USARTx->CR3 = USART_CR3_OVRDIS; // disable the ORE ISR
USARTx->CR1 = CR1_FLAGS; USARTx->CR1 = CR1_FLAGS;
armcm_enable_irq(USARTx_IRQHandler, USARTx_IRQn, 0); armcm_enable_irq(USARTx_IRQHandler, USARTx_IRQn, 0);

View File

@ -5,6 +5,7 @@
// This file may be distributed under the terms of the GNU GPLv3 license. // This file may be distributed under the terms of the GNU GPLv3 license.
#include "board/armcm_boot.h" // armcm_enable_irq #include "board/armcm_boot.h" // armcm_enable_irq
#include "board/armcm_timer.h" // udelay
#include "board/internal.h" // TIM3 #include "board/internal.h" // TIM3
#include "board/io.h" // readl #include "board/io.h" // readl
#include "board/irq.h" // irq_disable #include "board/irq.h" // irq_disable
@ -17,16 +18,21 @@
****************************************************************/ ****************************************************************/
// Use 32bit TIM2 timer if available (otherwise use 16bit TIM3 timer) // Use 32bit TIM2 timer if available (otherwise use 16bit TIM3 timer)
#ifdef TIM2 #if defined(TIM2)
#define TIMx TIM2 #define TIMx TIM2
#define TIMx_IRQn TIM2_IRQn #define TIMx_IRQn TIM2_IRQn
#define HAVE_TIMER_32BIT 1 #define HAVE_TIMER_32BIT 1
#else #elif defined(TIM3)
#define TIMx TIM3 #define TIMx TIM3
#define TIMx_IRQn TIM3_IRQn #define TIMx_IRQn TIM3_IRQn
#define HAVE_TIMER_32BIT 0 #define HAVE_TIMER_32BIT 0
#endif #endif
// Some chips have slightly different register names
#if CONFIG_MACH_STM32G0B0
#define TIM3_IRQn TIM3_TIM4_IRQn
#endif
static inline uint32_t static inline uint32_t
timer_get(void) timer_get(void)
{ {
@ -40,12 +46,13 @@ timer_set(uint32_t next)
TIMx->SR = 0; TIMx->SR = 0;
} }
/**************************************************************** /****************************************************************
* 16bit hardware timer to 32bit conversion * 16bit hardware timer to 32bit conversion
****************************************************************/ ****************************************************************/
// High bits of timer (top 17 bits) // High bits of timer (top 17 bits)
static uint32_t timer_high = 0; static uint32_t timer_high;
// Return the current time (in absolute clock ticks). // Return the current time (in absolute clock ticks).
uint32_t __always_inline uint32_t __always_inline
@ -60,6 +67,7 @@ timer_read_time(void)
return (th ^ cur) + (th & 0xffff); return (th ^ cur) + (th & 0xffff);
} }
/**************************************************************** /****************************************************************
* Setup and irqs * Setup and irqs
****************************************************************/ ****************************************************************/

View File

@ -1,13 +1,14 @@
// Code to setup clocks and gpio on stm32f1 // Code to setup clocks and gpio on stm32f1
// //
// Copyright (C) 2019-2021 Kevin O'Connor <kevin@koconnor.net> // Copyright (C) 2019-2022 Kevin O'Connor <kevin@koconnor.net>
// //
// This file may be distributed under the terms of the GNU GPLv3 license. // This file may be distributed under the terms of the GNU GPLv3 license.
#include "autoconf.h" // CONFIG_CLOCK_REF_FREQ #include "autoconf.h" // CONFIG_CLOCK_REF_FREQ
#include "board/armcm_boot.h" // VectorTable #include "board/armcm_boot.h" // VectorTable
#include "board/armcm_reset.h" // try_request_canboot
#include "board/irq.h" // irq_disable #include "board/irq.h" // irq_disable
#include "board/usb_cdc.h" // usb_request_bootloader #include "board/misc.h" // bootloader_request
#include "internal.h" // enable_pclock #include "internal.h" // enable_pclock
#include "sched.h" // sched_main #include "sched.h" // sched_main
@ -211,6 +212,46 @@ gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup)
} }
/****************************************************************
* Bootloader
****************************************************************/
// Reboot into USB "HID" bootloader
static void
usb_hid_bootloader(void)
{
irq_disable();
RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
PWR->CR |= PWR_CR_DBP;
BKP->DR4 = 0x424C; // HID Bootloader magic key
PWR->CR &=~ PWR_CR_DBP;
NVIC_SystemReset();
}
// Reboot into USB "stm32duino" bootloader
static void
usb_stm32duino_bootloader(void)
{
irq_disable();
RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
PWR->CR |= PWR_CR_DBP;
BKP->DR10 = 0x01; // stm32duino bootloader magic key
PWR->CR &=~ PWR_CR_DBP;
NVIC_SystemReset();
}
// Handle reboot requests
void
bootloader_request(void)
{
try_request_canboot();
if (CONFIG_STM32_FLASH_START_800)
usb_hid_bootloader();
else if (CONFIG_STM32_FLASH_START_2000)
usb_stm32duino_bootloader();
}
/**************************************************************** /****************************************************************
* Startup * Startup
****************************************************************/ ****************************************************************/

View File

@ -6,8 +6,9 @@
#include "autoconf.h" // CONFIG_CLOCK_REF_FREQ #include "autoconf.h" // CONFIG_CLOCK_REF_FREQ
#include "board/armcm_boot.h" // VectorTable #include "board/armcm_boot.h" // VectorTable
#include "board/armcm_reset.h" // try_request_canboot
#include "board/irq.h" // irq_disable #include "board/irq.h" // irq_disable
#include "board/usb_cdc.h" // usb_request_bootloader #include "board/misc.h" // bootloader_request
#include "command.h" // DECL_CONSTANT_STR #include "command.h" // DECL_CONSTANT_STR
#include "internal.h" // enable_pclock #include "internal.h" // enable_pclock
#include "sched.h" // sched_main #include "sched.h" // sched_main
@ -138,7 +139,7 @@ enable_clock_stm32f446(void)
; ;
// Enable 48Mhz USB clock // Enable 48Mhz USB clock
if (CONFIG_USBSERIAL) { if (CONFIG_USB) {
uint32_t ref = (CONFIG_STM32_CLOCK_REF_INTERNAL uint32_t ref = (CONFIG_STM32_CLOCK_REF_INTERNAL
? 16000000 : CONFIG_CLOCK_REF_FREQ); ? 16000000 : CONFIG_CLOCK_REF_FREQ);
uint32_t plls_base = 2000000, plls_freq = FREQ_USB * 4; uint32_t plls_base = 2000000, plls_freq = FREQ_USB * 4;
@ -185,6 +186,35 @@ clock_setup(void)
; ;
} }
/****************************************************************
* Bootloader
****************************************************************/
// Reboot into USB "HID" bootloader
static void
usb_hid_bootloader(void)
{
irq_disable();
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
RCC->APB1ENR;
PWR->CR |= PWR_CR_DBP;
RTC->BKP4R = 0x424C; // HID Bootloader magic key
PWR->CR &= ~PWR_CR_DBP;
NVIC_SystemReset();
}
// Handle reboot requests
void
bootloader_request(void)
{
try_request_canboot();
if (CONFIG_STM32_FLASH_START_4000)
usb_hid_bootloader();
dfu_reboot();
}
/**************************************************************** /****************************************************************
* Startup * Startup
****************************************************************/ ****************************************************************/
@ -193,6 +223,8 @@ clock_setup(void)
void void
armcm_main(void) armcm_main(void)
{ {
dfu_reboot_check();
// Run SystemInit() and then restore VTOR // Run SystemInit() and then restore VTOR
SystemInit(); SystemInit();
SCB->VTOR = (uint32_t)VectorTable; SCB->VTOR = (uint32_t)VectorTable;

View File

@ -6,7 +6,9 @@
#include "autoconf.h" // CONFIG_CLOCK_REF_FREQ #include "autoconf.h" // CONFIG_CLOCK_REF_FREQ
#include "board/armcm_boot.h" // armcm_main #include "board/armcm_boot.h" // armcm_main
#include "board/armcm_reset.h" // try_request_canboot
#include "board/irq.h" // irq_disable #include "board/irq.h" // irq_disable
#include "board/misc.h" // bootloader_request
#include "command.h" // DECL_CONSTANT_STR #include "command.h" // DECL_CONSTANT_STR
#include "internal.h" // enable_pclock #include "internal.h" // enable_pclock
#include "sched.h" // sched_main #include "sched.h" // sched_main
@ -30,21 +32,42 @@ lookup_clock_line(uint32_t periph_base)
uint32_t bit = 1 << ((periph_base - AHBPERIPH_BASE) / 0x400); uint32_t bit = 1 << ((periph_base - AHBPERIPH_BASE) / 0x400);
return (struct cline){.en=&RCC->AHBENR, .rst=&RCC->AHBRSTR, .bit=bit}; return (struct cline){.en=&RCC->AHBENR, .rst=&RCC->AHBRSTR, .bit=bit};
} }
#if defined(FDCAN1_BASE) || defined(FDCAN2_BASE)
if ((periph_base == FDCAN1_BASE) || (periph_base == FDCAN2_BASE)) if ((periph_base == FDCAN1_BASE) || (periph_base == FDCAN2_BASE))
return (struct cline){.en=&RCC->APBENR1,.rst=&RCC->APBRSTR1,.bit=1<<12}; return (struct cline){.en=&RCC->APBENR1,.rst=&RCC->APBRSTR1,.bit=1<<12};
#endif
if (periph_base == USB_BASE) if (periph_base == USB_BASE)
return (struct cline){.en=&RCC->APBENR1,.rst=&RCC->APBRSTR1,.bit=1<<13}; return (struct cline){.en=&RCC->APBENR1,.rst=&RCC->APBRSTR1,.bit=1<<13};
#ifdef CRS_BASE
if (periph_base == CRS_BASE) if (periph_base == CRS_BASE)
return (struct cline){.en=&RCC->APBENR1,.rst=&RCC->APBRSTR1,.bit=1<<16}; return (struct cline){.en=&RCC->APBENR1,.rst=&RCC->APBRSTR1,.bit=1<<16};
#endif
if (periph_base == I2C3_BASE)
return (struct cline){.en=&RCC->APBENR1,.rst=&RCC->APBRSTR1,.bit=1<<23};
if (periph_base == TIM1_BASE)
return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<11};
if (periph_base == SPI1_BASE) if (periph_base == SPI1_BASE)
return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<12}; return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<12};
if (periph_base == USART1_BASE) if (periph_base == USART1_BASE)
return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<14}; return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<14};
if (periph_base == TIM14_BASE)
return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<15};
if (periph_base == TIM15_BASE)
return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<16};
if (periph_base == TIM16_BASE)
return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<17};
if (periph_base == TIM17_BASE)
return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<18};
if (periph_base == ADC1_BASE) if (periph_base == ADC1_BASE)
return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<20}; return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<20};
if (periph_base >= APBPERIPH_BASE
&& periph_base < APBPERIPH_BASE + 32*0x400) {
uint32_t bit = 1 << ((periph_base - APBPERIPH_BASE) / 0x400); uint32_t bit = 1 << ((periph_base - APBPERIPH_BASE) / 0x400);
return (struct cline){.en=&RCC->APBENR1, .rst=&RCC->APBRSTR1, .bit=bit}; return (struct cline){.en=&RCC->APBENR1, .rst=&RCC->APBRSTR1, .bit=bit};
} }
// unknown peripheral. returning .bit=0 makes this a no-op
return (struct cline){.en=&RCC->APBENR1, .rst=NULL, .bit=0};
}
// Return the frequency of the given peripheral clock // Return the frequency of the given peripheral clock
uint32_t uint32_t
@ -101,6 +124,19 @@ clock_setup(void)
} }
/****************************************************************
* Bootloader
****************************************************************/
// Handle USB reboot requests
void
bootloader_request(void)
{
try_request_canboot();
dfu_reboot();
}
/**************************************************************** /****************************************************************
* Startup * Startup
****************************************************************/ ****************************************************************/
@ -125,8 +161,13 @@ armcm_main(void)
RCC->APBENR1 = 0x00000000; RCC->APBENR1 = 0x00000000;
RCC->APBENR2 = 0x00000000; RCC->APBENR2 = 0x00000000;
// Set flash latency dfu_reboot_check();
FLASH->ACR = (2<<FLASH_ACR_LATENCY_Pos) | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN;
// Set flash latency, cache and prefetch; use reset value as base
uint32_t acr = 0x00040600;
acr = (acr & ~FLASH_ACR_LATENCY) | (2<<FLASH_ACR_LATENCY_Pos);
acr |= FLASH_ACR_ICEN | FLASH_ACR_PRFTEN;
FLASH->ACR = acr;
// Configure main clock // Configure main clock
clock_setup(); clock_setup();