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
#include <stdarg.h> // va_list
#include <stddef.h>
#include <stdint.h> // uint32_t
#include "ctr.h" // DECL_CTR

View File

@ -9,7 +9,7 @@ config STM32_SELECT
select HAVE_GPIO_ADC
select HAVE_GPIO_I2C if !(MACH_STM32F031 || MACH_STM32H7)
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_STRICT_TIMING
select HAVE_CHIPID
@ -64,15 +64,29 @@ choice
bool "STM32F072"
select MACH_STM32F0
select MACH_STM32F0x2
config MACH_STM32G0B0
bool "STM32G0B0"
select MACH_STM32G0
select MACH_STM32G0Bx
config MACH_STM32G0B1
bool "STM32G0B1"
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
bool "STM32H743" if 0
select MACH_STM32H7
config MACH_STM32H750
bool "STM32H750" if 0
select MACH_STM32H7
config MACH_STM32L412
bool "STM32L412" if 0
select MACH_STM32L4
endchoice
config MACH_STM32F103x6
@ -89,15 +103,21 @@ config MACH_STM32F4
bool
config MACH_STM32G0
bool
config MACH_STM32G0Bx
bool
config MACH_STM32G4
bool
config MACH_STM32H7
bool
config MACH_STM32F0x2 # F042, F072 series
bool
config MACH_STM32F4x5 # F405, F407, F429 series
bool
config MACH_STM32L4
bool
config HAVE_STM32_USBFS
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
config HAVE_STM32_USBOTG
bool
@ -107,7 +127,9 @@ config HAVE_STM32_CANBUS
default y if MACH_STM32F1 || MACH_STM32F2 || MACH_STM32F4x5 || MACH_STM32F446 || MACH_STM32F0x2
config HAVE_STM32_FDCANBUS
bool
default y if MACH_STM32G0
default y if MACH_STM32G0B1 || MACH_STM32H7 || MACH_STM32G4
config HAVE_STM32_USBCANBUS
bool
config MCU
string
@ -122,9 +144,13 @@ config MCU
default "stm32f407xx" if MACH_STM32F407
default "stm32f429xx" if MACH_STM32F429
default "stm32f446xx" if MACH_STM32F446
default "stm32g0b0xx" if MACH_STM32G0B0
default "stm32g0b1xx" if MACH_STM32G0B1
default "stm32g431xx" if MACH_STM32G431
default "stm32h723xx" if MACH_STM32H723
default "stm32h743xx" if MACH_STM32H743
default "stm32h750xx" if MACH_STM32H750
default "stm32l412xx" if MACH_STM32L412
config CLOCK_FREQ
int
@ -136,31 +162,28 @@ config CLOCK_FREQ
default 168000000 if MACH_STM32F4x5
default 180000000 if MACH_STM32F446
default 64000000 if MACH_STM32G0
default 150000000 if MACH_STM32G431
default 400000000 if MACH_STM32H7 # 400Mhz is max Klipper currently supports
config FLASH_START
hex
default 0x8000000
config FLASH_BOOT_ADDRESS
hex
default 0x8000000
default 80000000 if MACH_STM32L412
config FLASH_SIZE
hex
default 0x4000 if MACH_STM32F031
default 0x8000 if MACH_STM32F042
default 0x20000 if MACH_STM32F070 || MACH_STM32F072
default 0x10000 if MACH_STM32F103 # Flash size of stm32f103x8 (64KiB)
default 0x40000 if MACH_STM32F2 || MACH_STM32F401
default 0x10000 if MACH_STM32F103 || MACH_STM32L412 # Flash size of stm32f103x8 (64KiB)
default 0x40000 if MACH_STM32F2 || MACH_STM32F401 || MACH_STM32H723
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 0x200000 if MACH_STM32H743
config FLASH_BOOT_ADDRESS
hex
default 0x8000000
config RAM_START
hex
default 0x24000000 if MACH_STM32H743
default 0x20000000
config RAM_SIZE
@ -170,12 +193,13 @@ config RAM_SIZE
default 0x4000 if MACH_STM32F070 || MACH_STM32F072
default 0x2800 if MACH_STM32F103x6
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 0x10000 if MACH_STM32F401
default 0x20000 if MACH_STM32F4x5 || MACH_STM32F446
default 0x24000 if MACH_STM32G0B1
default 0x20000 if MACH_STM32H750
default 0x80000 if MACH_STM32H743
default 0x24000 if MACH_STM32G0Bx
default 0x20000 if MACH_STM32H7
config STACK_SIZE
int
@ -191,6 +215,15 @@ config STM32F103GD_DISABLE_SWD
and PA14 pins from being available. Selecting this option
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
@ -224,7 +257,7 @@ choice
config STM32_FLASH_START_4000
bool "16KiB bootloader (HID Bootloader)" if MACH_STM32F207 || MACH_STM32F401 || MACH_STM32F4x5 || MACH_STM32F103 || MACH_STM32F072
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
config FLASH_APPLICATION_ADDRESS
hex
@ -260,6 +293,8 @@ choice
bool "12 MHz crystal"
config STM32_CLOCK_REF_16M
bool "16 MHz crystal"
config STM32_CLOCK_REF_20M
bool "20 MHz crystal"
config STM32_CLOCK_REF_25M
bool "25 MHz crystal"
config STM32_CLOCK_REF_INTERNAL
@ -268,6 +303,7 @@ endchoice
config CLOCK_REF_FREQ
int
default 25000000 if STM32_CLOCK_REF_25M
default 20000000 if STM32_CLOCK_REF_20M
default 16000000 if STM32_CLOCK_REF_16M
default 12000000 if STM32_CLOCK_REF_12M
default 1 if STM32_CLOCK_REF_INTERNAL
@ -297,7 +333,7 @@ choice
select USBSERIAL
config STM32_USB_PB14_PB15
bool "USB (on PB14/PB15)"
depends on MACH_STM32H7
depends on MACH_STM32H743 || MACH_STM32H750
select USBSERIAL
config STM32_SERIAL_USART1
bool "Serial (on USART1 PA10/PA9)"
@ -309,7 +345,10 @@ choice
bool "Serial (on USART2 PA3/PA2)" if LOW_LEVEL_OPTIONS
select SERIAL
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
config STM32_SERIAL_USART2_ALT_PD6_PD5
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
depends on HAVE_STM32_CANBUS && MACH_STM32F042
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
depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS
select CANSERIAL
config STM32_CANBUS_PI9_PH13
config STM32_MMENU_CANBUS_PI9_PH13
bool "CAN bus (on PI9/PH13)" if LOW_LEVEL_OPTIONS
depends on HAVE_STM32_CANBUS && MACH_STM32F4
select CANSERIAL
config STM32_CANBUS_PB5_PB6
config STM32_MMENU_CANBUS_PB5_PB6
bool "CAN bus (on PB5/PB6)" if LOW_LEVEL_OPTIONS
depends on HAVE_STM32_CANBUS && MACH_STM32F4
select CANSERIAL
config STM32_CANBUS_PB12_PB13
config STM32_MMENU_CANBUS_PB12_PB13
bool "CAN bus (on PB12/PB13)" if LOW_LEVEL_OPTIONS
depends on HAVE_STM32_CANBUS && MACH_STM32F4
select CANSERIAL
config STM32_CANBUS_PD0_PD1
config STM32_MMENU_CANBUS_PD0_PD1
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
config STM32_CANBUS_PB0_PB1
config STM32_MMENU_CANBUS_PB0_PB1
bool "CAN bus (on PB0/PB1)"
depends on HAVE_STM32_FDCANBUS
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
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
######################################################################
config FLASH_START
hex
default 0x8000000
choice
prompt "Application start offset"
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
# 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-$(CONFIG_MACH_STM32F0) += ../lib/stm32f0/system_stm32f0xx.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"
#elif CONFIG_MACH_STM32G0
#include "stm32g0xx.h"
#elif CONFIG_MACH_STM32G4
#include "stm32g4xx.h"
#elif CONFIG_MACH_STM32H7
#include "stm32h7xx.h"
#elif CONFIG_MACH_STM32L4
#include "stm32l4xx.h"
#endif
// gpio.c
@ -36,6 +40,10 @@ void gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup);
void enable_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
struct cline { volatile uint32_t *en, *rst; uint32_t bit; };
struct cline lookup_clock_line(uint32_t periph_base);

View File

@ -57,8 +57,11 @@ void
USARTx_IRQHandler(void)
{
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);
}
if (sr & USART_SR_TXE && USARTx->CR1 & USART_CR1_TXEIE) {
uint8_t data;
int ret = serial_get_tx_byte(&data);

View File

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

View File

@ -16,30 +16,68 @@
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA10,PA9");
#define GPIO_Rx GPIO('A', 10)
#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_IRQn USART1_IRQn
#elif CONFIG_STM32_SERIAL_USART1_ALT_PB7_PB6
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PB7,PB6");
#define GPIO_Rx GPIO('B', 7)
#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_IRQn USART1_IRQn
#elif CONFIG_STM32_SERIAL_USART2
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA3,PA2");
#define GPIO_Rx GPIO('A', 3)
#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_IRQn USART2_IRQn
#elif CONFIG_STM32_SERIAL_USART2_ALT_PA15_PA14
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA15,PA14");
#define GPIO_Rx GPIO('A', 15)
#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_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
#if CONFIG_MACH_STM32F031
@ -49,14 +87,23 @@
#endif
#if CONFIG_MACH_STM32G0
// The stm32g0 has slightly different register names
#define USART2_IRQn USART2_LPUART2_IRQn
// Some of the stm32g0 MCUs have slightly different register names
#if CONFIG_MACH_STM32G0B1
#define USART2_IRQn USART2_LPUART2_IRQn
#endif
#define USART_CR1_RXNEIE USART_CR1_RXNEIE_RXFNEIE
#define USART_CR1_TXEIE USART_CR1_TXEIE_TXFNFIE
#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE
#define USART_ISR_TXE USART_ISR_TXE_TXFNF
#define USART_BRR_DIV_MANTISSA_Pos 4
#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
#define CR1_FLAGS (USART_CR1_UE | USART_CR1_RE | USART_CR1_TE \
@ -66,7 +113,7 @@ void
USARTx_IRQHandler(void)
{
uint32_t sr = USARTx->ISR;
if (sr & (USART_ISR_RXNE | USART_ISR_ORE))
if (sr & USART_ISR_RXNE)
serial_rx_byte(USARTx->RDR);
if (sr & USART_ISR_TXE && USARTx->CR1 & USART_CR1_TXEIE) {
uint8_t data;
@ -93,6 +140,7 @@ serial_init(void)
uint32_t div = DIV_ROUND_CLOSEST(pclk, CONFIG_SERIAL_BAUD);
USARTx->BRR = (((div / 16) << USART_BRR_DIV_MANTISSA_Pos)
| ((div % 16) << USART_BRR_DIV_FRACTION_Pos));
USARTx->CR3 = USART_CR3_OVRDIS; // disable the ORE ISR
USARTx->CR1 = CR1_FLAGS;
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.
#include "board/armcm_boot.h" // armcm_enable_irq
#include "board/armcm_timer.h" // udelay
#include "board/internal.h" // TIM3
#include "board/io.h" // readl
#include "board/irq.h" // irq_disable
@ -17,14 +18,19 @@
****************************************************************/
// Use 32bit TIM2 timer if available (otherwise use 16bit TIM3 timer)
#ifdef TIM2
#define TIMx TIM2
#define TIMx_IRQn TIM2_IRQn
#define HAVE_TIMER_32BIT 1
#else
#define TIMx TIM3
#define TIMx_IRQn TIM3_IRQn
#define HAVE_TIMER_32BIT 0
#if defined(TIM2)
#define TIMx TIM2
#define TIMx_IRQn TIM2_IRQn
#define HAVE_TIMER_32BIT 1
#elif defined(TIM3)
#define TIMx TIM3
#define TIMx_IRQn TIM3_IRQn
#define HAVE_TIMER_32BIT 0
#endif
// Some chips have slightly different register names
#if CONFIG_MACH_STM32G0B0
#define TIM3_IRQn TIM3_TIM4_IRQn
#endif
static inline uint32_t
@ -40,12 +46,13 @@ timer_set(uint32_t next)
TIMx->SR = 0;
}
/****************************************************************
* 16bit hardware timer to 32bit conversion
****************************************************************/
// 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).
uint32_t __always_inline
@ -60,6 +67,7 @@ timer_read_time(void)
return (th ^ cur) + (th & 0xffff);
}
/****************************************************************
* Setup and irqs
****************************************************************/

View File

@ -1,13 +1,14 @@
// 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.
#include "autoconf.h" // CONFIG_CLOCK_REF_FREQ
#include "board/armcm_boot.h" // VectorTable
#include "board/armcm_reset.h" // try_request_canboot
#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 "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
****************************************************************/

View File

@ -6,8 +6,9 @@
#include "autoconf.h" // CONFIG_CLOCK_REF_FREQ
#include "board/armcm_boot.h" // VectorTable
#include "board/armcm_reset.h" // try_request_canboot
#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 "internal.h" // enable_pclock
#include "sched.h" // sched_main
@ -138,7 +139,7 @@ enable_clock_stm32f446(void)
;
// Enable 48Mhz USB clock
if (CONFIG_USBSERIAL) {
if (CONFIG_USB) {
uint32_t ref = (CONFIG_STM32_CLOCK_REF_INTERNAL
? 16000000 : CONFIG_CLOCK_REF_FREQ);
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
****************************************************************/
@ -193,6 +223,8 @@ clock_setup(void)
void
armcm_main(void)
{
dfu_reboot_check();
// Run SystemInit() and then restore VTOR
SystemInit();
SCB->VTOR = (uint32_t)VectorTable;

View File

@ -6,7 +6,9 @@
#include "autoconf.h" // CONFIG_CLOCK_REF_FREQ
#include "board/armcm_boot.h" // armcm_main
#include "board/armcm_reset.h" // try_request_canboot
#include "board/irq.h" // irq_disable
#include "board/misc.h" // bootloader_request
#include "command.h" // DECL_CONSTANT_STR
#include "internal.h" // enable_pclock
#include "sched.h" // sched_main
@ -30,20 +32,41 @@ lookup_clock_line(uint32_t periph_base)
uint32_t bit = 1 << ((periph_base - AHBPERIPH_BASE) / 0x400);
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))
return (struct cline){.en=&RCC->APBENR1,.rst=&RCC->APBRSTR1,.bit=1<<12};
#endif
if (periph_base == USB_BASE)
return (struct cline){.en=&RCC->APBENR1,.rst=&RCC->APBRSTR1,.bit=1<<13};
#ifdef CRS_BASE
if (periph_base == CRS_BASE)
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)
return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<12};
if (periph_base == USART1_BASE)
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)
return (struct cline){.en=&RCC->APBENR2,.rst=&RCC->APBRSTR2,.bit=1<<20};
uint32_t bit = 1 << ((periph_base - APBPERIPH_BASE) / 0x400);
return (struct cline){.en=&RCC->APBENR1, .rst=&RCC->APBRSTR1, .bit=bit};
if (periph_base >= APBPERIPH_BASE
&& periph_base < APBPERIPH_BASE + 32*0x400) {
uint32_t bit = 1 << ((periph_base - APBPERIPH_BASE) / 0x400);
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
@ -101,6 +124,19 @@ clock_setup(void)
}
/****************************************************************
* Bootloader
****************************************************************/
// Handle USB reboot requests
void
bootloader_request(void)
{
try_request_canboot();
dfu_reboot();
}
/****************************************************************
* Startup
****************************************************************/
@ -125,8 +161,13 @@ armcm_main(void)
RCC->APBENR1 = 0x00000000;
RCC->APBENR2 = 0x00000000;
// Set flash latency
FLASH->ACR = (2<<FLASH_ACR_LATENCY_Pos) | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN;
dfu_reboot_check();
// 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
clock_setup();