mirror of
https://github.com/andreili/katapult.git
synced 2025-08-24 03:44:06 +02:00
src: update stm32 source
Bring in the latest changes from Klipper. The STM32F4 variants are still unsupported at this time. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
73d7ddd5aa
commit
26b12a658b
@ -12,7 +12,7 @@ config CANSERIAL
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config CANBUS_BAUD
|
config CONFIG_CANBUS_FREQUENCY
|
||||||
int "CAN bus speed"
|
int "CAN bus speed"
|
||||||
default 500000
|
default 500000
|
||||||
|
|
||||||
|
@ -17,18 +17,27 @@ choice
|
|||||||
config MACH_STM32F405
|
config MACH_STM32F405
|
||||||
bool "STM32F405"
|
bool "STM32F405"
|
||||||
select MACH_STM32F4
|
select MACH_STM32F4
|
||||||
|
select MACH_STM32F4x5
|
||||||
config MACH_STM32F407
|
config MACH_STM32F407
|
||||||
bool "STM32F407"
|
bool "STM32F407"
|
||||||
select MACH_STM32F4
|
select MACH_STM32F4
|
||||||
|
select MACH_STM32F4x5
|
||||||
|
config MACH_STM32F429
|
||||||
|
bool "STM32F429"
|
||||||
|
select MACH_STM32F4
|
||||||
|
select MACH_STM32F4x5
|
||||||
config MACH_STM32F446
|
config MACH_STM32F446
|
||||||
bool "STM32F446"
|
bool "STM32F446"
|
||||||
select MACH_STM32F4
|
select MACH_STM32F4
|
||||||
config MACH_STM32F042
|
config MACH_STM32F042
|
||||||
bool "STM32F042"
|
bool "STM32F042"
|
||||||
select MACH_STM32F0
|
select MACH_STM32F0
|
||||||
config MACH_STM32F070
|
select MACH_STM32F0x2
|
||||||
bool "STM32F070"
|
config MACH_STM32F072
|
||||||
|
bool "STM32F072"
|
||||||
select MACH_STM32F0
|
select MACH_STM32F0
|
||||||
|
select MACH_STM32F0x2
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config MACH_STM32F0
|
config MACH_STM32F0
|
||||||
@ -43,11 +52,12 @@ config MACH_STM32F4
|
|||||||
config MCU
|
config MCU
|
||||||
string
|
string
|
||||||
default "stm32f042x6" if MACH_STM32F042
|
default "stm32f042x6" if MACH_STM32F042
|
||||||
default "stm32f070xb" if MACH_STM32F070
|
default "stm32f072xb" if MACH_STM32F072
|
||||||
default "stm32f103xe" if MACH_STM32F103
|
default "stm32f103xe" if MACH_STM32F103
|
||||||
default "stm32f207xx" if MACH_STM32F207
|
default "stm32f207xx" if MACH_STM32F207
|
||||||
default "stm32f405xx" if MACH_STM32F405
|
default "stm32f405xx" if MACH_STM32F405
|
||||||
default "stm32f407xx" if MACH_STM32F407
|
default "stm32f407xx" if MACH_STM32F407
|
||||||
|
default "stm32f429xx" if MACH_STM32F429
|
||||||
default "stm32f446xx" if MACH_STM32F446
|
default "stm32f446xx" if MACH_STM32F446
|
||||||
|
|
||||||
config CLOCK_FREQ
|
config CLOCK_FREQ
|
||||||
@ -56,13 +66,13 @@ config CLOCK_FREQ
|
|||||||
default 64000000 if MACH_STM32F103 && STM32_CLOCK_REF_INTERNAL
|
default 64000000 if MACH_STM32F103 && STM32_CLOCK_REF_INTERNAL
|
||||||
default 72000000 if MACH_STM32F103
|
default 72000000 if MACH_STM32F103
|
||||||
default 120000000 if MACH_STM32F207
|
default 120000000 if MACH_STM32F207
|
||||||
default 168000000 if MACH_STM32F405 || MACH_STM32F407
|
default 168000000 if MACH_STM32F4x5
|
||||||
default 180000000 if MACH_STM32F446
|
default 180000000 if MACH_STM32F446
|
||||||
|
|
||||||
config FLASH_SIZE
|
config FLASH_SIZE
|
||||||
hex
|
hex
|
||||||
default 0x8000 if MACH_STM32F042
|
default 0x8000 if MACH_STM32F042
|
||||||
default 0x20000 if MACH_STM32F070
|
default 0x20000 if MACH_STM32F072
|
||||||
default 0x10000 if MACH_STM32F103 # Flash size of stm32f103x8 (64KiB)
|
default 0x10000 if MACH_STM32F103 # Flash size of stm32f103x8 (64KiB)
|
||||||
default 0x40000 if MACH_STM32F2
|
default 0x40000 if MACH_STM32F2
|
||||||
default 0x80000 if MACH_STM32F4
|
default 0x80000 if MACH_STM32F4
|
||||||
@ -74,7 +84,7 @@ config RAM_START
|
|||||||
config RAM_SIZE
|
config RAM_SIZE
|
||||||
hex
|
hex
|
||||||
default 0x1800 if MACH_STM32F042
|
default 0x1800 if MACH_STM32F042
|
||||||
default 0x4000 if MACH_STM32F070
|
default 0x4000 if MACH_STM32F072
|
||||||
default 0x5000 if MACH_STM32F103 # Ram size of stm32f103x8 (20KiB)
|
default 0x5000 if MACH_STM32F103 # Ram size of stm32f103x8 (20KiB)
|
||||||
default 0x20000 if MACH_STM32F207
|
default 0x20000 if MACH_STM32F207
|
||||||
default 0x20000 if MACH_STM32F4
|
default 0x20000 if MACH_STM32F4
|
||||||
@ -97,6 +107,16 @@ config ARMCM_RAM_VECTORTABLE
|
|||||||
default y if MACH_STM32F0 && FLASH_START != 0x8000000
|
default y if MACH_STM32F0 && FLASH_START != 0x8000000
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config STM32F103GD_DISABLE_SWD
|
||||||
|
bool "Disable SWD at startup (for GigaDevice stm32f103 clones)"
|
||||||
|
depends on MACH_STM32F103
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
The GigaDevice clone of the STM32F103 may not be able to
|
||||||
|
reliably disable SWD at run-time. This can prevent the PA13
|
||||||
|
and PA14 pins from being available. Selecting this option
|
||||||
|
disables SWD at startup and thus makes these pins available.
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "Clock Reference"
|
prompt "Clock Reference"
|
||||||
config STM32_CLOCK_REF_8M
|
config STM32_CLOCK_REF_8M
|
||||||
@ -105,11 +125,14 @@ 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_25M
|
||||||
|
bool "25 MHz crystal"
|
||||||
config STM32_CLOCK_REF_INTERNAL
|
config STM32_CLOCK_REF_INTERNAL
|
||||||
bool "Internal clock"
|
bool "Internal clock"
|
||||||
endchoice
|
endchoice
|
||||||
config CLOCK_REF_FREQ
|
config CLOCK_REF_FREQ
|
||||||
int
|
int
|
||||||
|
default 25000000 if STM32_CLOCK_REF_25M
|
||||||
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
|
||||||
@ -117,16 +140,20 @@ config CLOCK_REF_FREQ
|
|||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "CAN pins"
|
prompt "CAN pins"
|
||||||
config CAN_PINS_PA11_PA12
|
config STM32_CANBUS_PA11_PA12
|
||||||
bool "Pins PA11(rx) and PA12(tx)"
|
bool "Pins PA11(rx) and PA12(tx)"
|
||||||
config CAN_PINS_PB8_PB9
|
config STM32_CANBUS_PA11_PA12_REMAP
|
||||||
|
bool "Pins on PA9(rx) and PA10(tx)" if MACH_STM32F042
|
||||||
|
config STM32_CANBUS_PB8_PB9
|
||||||
bool "Pins PB8(rx) and PB9(tx)"
|
bool "Pins PB8(rx) and PB9(tx)"
|
||||||
config CAN_PINS_PI8_PH13
|
config STM32_CANBUS_PI9_PH13
|
||||||
bool "Pins PI8(rx) and PH13(tx)" if MACH_STM32F4
|
bool "Pins PI9(rx) and PH13(tx)" if MACH_STM32F4
|
||||||
config CAN_PINS_PB5_PB6
|
config STM32_CANBUS_PB5_PB6
|
||||||
bool "Pins PB5(rx) and PB6(tx)" if MACH_STM32F4
|
bool "Pins PB5(rx) and PB6(tx)" if MACH_STM32F4
|
||||||
config CAN_PINS_PB12_PB13
|
config STM32_CANBUS_PB12_PB13
|
||||||
bool "Pins PB12(rx) and PB13(tx)" if MACH_STM32F4
|
bool "Pins PB12(rx) and PB13(tx)" if MACH_STM32F4
|
||||||
|
config STM32_CANBUS_PD0_PD1
|
||||||
|
bool "Pins PD0(rx) and PD1(tx)"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config STM32F0_TRIM
|
config STM32F0_TRIM
|
||||||
@ -138,14 +165,6 @@ config STM32F0_TRIM
|
|||||||
Default is 16 (use factory default). Each increment increases
|
Default is 16 (use factory default). Each increment increases
|
||||||
the clock rate by ~240KHz.
|
the clock rate by ~240KHz.
|
||||||
|
|
||||||
config STM32F042_PIN_SWAP
|
|
||||||
bool "Use PA9/PA10 for USB or CAN" if MACH_STM32F042
|
|
||||||
depends on MACH_STM32F042
|
|
||||||
default y if MACH_STM32F042
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
Remaps logical pins PA11/PA12 to physical PA9/PA10 on low pincount F042 devices.
|
|
||||||
|
|
||||||
choice
|
choice
|
||||||
depends on MACH_STM32F103
|
depends on MACH_STM32F103
|
||||||
prompt "Flash Page Size"
|
prompt "Flash Page Size"
|
||||||
|
@ -24,19 +24,22 @@ 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
|
||||||
src-y += stm32/gpio.c stm32/flash.c
|
src-y += stm32/gpio.c stm32/flash.c stm32/clockline.c
|
||||||
src-y += generic/armcm_boot.c generic/armcm_irq.c
|
src-y += generic/armcm_boot.c generic/armcm_irq.c
|
||||||
src-$(CONFIG_MACH_STM32F0) += ../lib/stm32f0/system_stm32f0xx.c
|
src-$(CONFIG_MACH_STM32F0) += ../lib/stm32f0/system_stm32f0xx.c
|
||||||
src-$(CONFIG_MACH_STM32F0) += stm32/stm32f0.c stm32/stm32f0_timer.c
|
src-$(CONFIG_MACH_STM32F0) += stm32/stm32f0.c stm32/stm32f0_timer.c
|
||||||
|
src-$(CONFIG_MACH_STM32F0) += stm32/gpioperiph.c
|
||||||
|
|
||||||
src-$(CONFIG_MACH_STM32F1) += ../lib/stm32f1/system_stm32f1xx.c
|
src-$(CONFIG_MACH_STM32F1) += ../lib/stm32f1/system_stm32f1xx.c
|
||||||
src-$(CONFIG_MACH_STM32F1) += stm32/stm32f1.c generic/armcm_timer.c
|
src-$(CONFIG_MACH_STM32F1) += stm32/stm32f1.c generic/armcm_timer.c
|
||||||
|
|
||||||
src-$(CONFIG_MACH_STM32F2) += ../lib/stm32f2/system_stm32f2xx.c
|
src-$(CONFIG_MACH_STM32F2) += ../lib/stm32f2/system_stm32f2xx.c
|
||||||
src-$(CONFIG_MACH_STM32F2) += stm32/stm32f4.c generic/armcm_timer.c
|
src-$(CONFIG_MACH_STM32F2) += stm32/stm32f4.c generic/armcm_timer.c
|
||||||
|
src-$(CONFIG_MACH_STM32F2) += stm32/gpioperiph.c
|
||||||
|
|
||||||
src-$(CONFIG_MACH_STM32F4) += ../lib/stm32f4/system_stm32f4xx.c
|
src-$(CONFIG_MACH_STM32F4) += ../lib/stm32f4/system_stm32f4xx.c
|
||||||
src-$(CONFIG_MACH_STM32F4) += stm32/stm32f4.c generic/armcm_timer.c
|
src-$(CONFIG_MACH_STM32F4) += stm32/stm32f4.c generic/armcm_timer.c
|
||||||
|
src-$(CONFIG_MACH_STM32F4) += stm32/gpioperiph.c
|
||||||
|
|
||||||
can-src-$(CONFIG_CANSERIAL) += stm32/can.c ../lib/fast-hash/fasthash.c
|
can-src-$(CONFIG_CANSERIAL) += stm32/can.c ../lib/fast-hash/fasthash.c
|
||||||
src-$(CONFIG_CANSERIAL) += $(can-src-y) generic/canbus.c
|
src-$(CONFIG_CANSERIAL) += $(can-src-y) generic/canbus.c
|
||||||
|
103
src/stm32/can.c
103
src/stm32/can.c
@ -15,31 +15,36 @@
|
|||||||
#include "internal.h" // enable_pclock
|
#include "internal.h" // enable_pclock
|
||||||
#include "ctr.h" // DECL_CONSTANT_STR
|
#include "ctr.h" // DECL_CONSTANT_STR
|
||||||
|
|
||||||
#if CONFIG_CAN_PINS_PA11_PA12
|
#if CONFIG_STM32_CANBUS_PA11_PA12 || CONFIG_STM32_CANBUS_PA11_PA12_REMAP
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PA11,PA12");
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PA11,PA12");
|
||||||
#define GPIO_Rx GPIO('A', 11)
|
#define GPIO_Rx GPIO('A', 11)
|
||||||
#define GPIO_Tx GPIO('A', 12)
|
#define GPIO_Tx GPIO('A', 12)
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_CAN_PINS_PB8_PB9
|
#if CONFIG_STM32_CANBUS_PB8_PB9
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB8,PB9");
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB8,PB9");
|
||||||
#define GPIO_Rx GPIO('B', 8)
|
#define GPIO_Rx GPIO('B', 8)
|
||||||
#define GPIO_Tx GPIO('B', 9)
|
#define GPIO_Tx GPIO('B', 9)
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_CAN_PINS_PI8_PH13
|
#if CONFIG_STM32_CANBUS_PI9_PH13
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PI8,PH13");
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PI9,PH13");
|
||||||
#define GPIO_Rx GPIO('I', 8)
|
#define GPIO_Rx GPIO('I', 9)
|
||||||
#define GPIO_Tx GPIO('H', 13)
|
#define GPIO_Tx GPIO('H', 13)
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_CAN_PINS_PB5_PB6
|
#if CONFIG_STM32_CANBUS_PB5_PB6
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB5,PB6");
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB5,PB6");
|
||||||
#define GPIO_Rx GPIO('B', 5)
|
#define GPIO_Rx GPIO('B', 5)
|
||||||
#define GPIO_Tx GPIO('B', 6)
|
#define GPIO_Tx GPIO('B', 6)
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_CAN_PINS_PB12_PB13
|
#if CONFIG_STM32_CANBUS_PB12_PB13
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB12,PB13");
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB12,PB13");
|
||||||
#define GPIO_Rx GPIO('B', 12)
|
#define GPIO_Rx GPIO('B', 12)
|
||||||
#define GPIO_Tx GPIO('B', 13)
|
#define GPIO_Tx GPIO('B', 13)
|
||||||
#endif
|
#endif
|
||||||
|
#if CONFIG_STM32_CANBUS_PD0_PD1
|
||||||
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PD0,PD1");
|
||||||
|
#define GPIO_Rx GPIO('D', 0)
|
||||||
|
#define GPIO_Tx GPIO('D', 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_MACH_STM32F0
|
#if CONFIG_MACH_STM32F0
|
||||||
#define SOC_CAN CAN
|
#define SOC_CAN CAN
|
||||||
@ -61,14 +66,14 @@
|
|||||||
|
|
||||||
#if CONFIG_MACH_STM32F4
|
#if CONFIG_MACH_STM32F4
|
||||||
#warning CAN on STM32F4 is untested
|
#warning CAN on STM32F4 is untested
|
||||||
#if (CONFIG_CAN_PINS_PA11_PA12 || CONFIG_CAN_PINS_PB8_PB9 \
|
#if (CONFIG_STM32_CANBUS_PA11_PA12 || CONFIG_STM32_CANBUS_PB8_PB9 \
|
||||||
|| CONFIG_CAN_PINS_PI8_PH13)
|
|| CONFIG_STM32_CANBUS_PD0_PD1 || CONFIG_STM32_CANBUS_PI9_PH13)
|
||||||
#define SOC_CAN CAN1
|
#define SOC_CAN CAN1
|
||||||
#define CAN_RX0_IRQn CAN1_RX0_IRQn
|
#define CAN_RX0_IRQn CAN1_RX0_IRQn
|
||||||
#define CAN_RX1_IRQn CAN1_RX1_IRQn
|
#define CAN_RX1_IRQn CAN1_RX1_IRQn
|
||||||
#define CAN_TX_IRQn CAN1_TX_IRQn
|
#define CAN_TX_IRQn CAN1_TX_IRQn
|
||||||
#define CAN_SCE_IRQn CAN1_SCE_IRQn
|
#define CAN_SCE_IRQn CAN1_SCE_IRQn
|
||||||
#elif CONFIG_CAN_PINS_PB5_PB6 || CONFIG_CAN_PINS_PB12_PB13
|
#elif CONFIG_STM32_CANBUS_PB5_PB6 || CONFIG_STM32_CANBUS_PB12_PB13
|
||||||
#define SOC_CAN CAN2
|
#define SOC_CAN CAN2
|
||||||
#define CAN_RX0_IRQn CAN2_RX0_IRQn
|
#define CAN_RX0_IRQn CAN2_RX0_IRQn
|
||||||
#define CAN_RX1_IRQn CAN2_RX1_IRQn
|
#define CAN_RX1_IRQn CAN2_RX1_IRQn
|
||||||
@ -152,62 +157,64 @@ canbus_send(uint32_t id, uint32_t len, uint8_t *data)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CAN_FILTER_NUMBER 0
|
|
||||||
|
|
||||||
// Setup the receive packet filter
|
// Setup the receive packet filter
|
||||||
static void
|
void
|
||||||
can_set_filter(uint32_t id1, uint32_t id2)
|
canbus_set_filter(uint32_t id)
|
||||||
{
|
{
|
||||||
uint32_t filternbrbitpos = 1 << CAN_FILTER_NUMBER;
|
|
||||||
|
|
||||||
/* Select the start slave bank */
|
/* Select the start slave bank */
|
||||||
SOC_CAN->FMR |= CAN_FMR_FINIT;
|
SOC_CAN->FMR |= CAN_FMR_FINIT;
|
||||||
/* Initialisation mode for the filter */
|
/* Initialisation mode for the filter */
|
||||||
SOC_CAN->FA1R = 0;
|
SOC_CAN->FA1R = 0;
|
||||||
|
|
||||||
SOC_CAN->sFilterRegister[CAN_FILTER_NUMBER].FR1 = id1 << (5 + 16);
|
uint32_t mask = CAN_RI0R_STID | CAN_TI0R_IDE | CAN_TI0R_RTR;
|
||||||
SOC_CAN->sFilterRegister[CAN_FILTER_NUMBER].FR2 = id2 << (5 + 16);
|
SOC_CAN->sFilterRegister[0].FR1 = CANBUS_ID_ADMIN << CAN_RI0R_STID_Pos;
|
||||||
|
SOC_CAN->sFilterRegister[0].FR2 = mask;
|
||||||
|
SOC_CAN->sFilterRegister[1].FR1 = (id + 1) << CAN_RI0R_STID_Pos;
|
||||||
|
SOC_CAN->sFilterRegister[1].FR2 = mask;
|
||||||
|
SOC_CAN->sFilterRegister[2].FR1 = id << CAN_RI0R_STID_Pos;
|
||||||
|
SOC_CAN->sFilterRegister[2].FR2 = mask;
|
||||||
|
|
||||||
/* Identifier list mode for the filter */
|
|
||||||
SOC_CAN->FM1R = filternbrbitpos;
|
|
||||||
/* 32-bit scale for the filter */
|
/* 32-bit scale for the filter */
|
||||||
SOC_CAN->FS1R = filternbrbitpos;
|
SOC_CAN->FS1R = (1<<0) | (1<<1) | (1<<2);
|
||||||
|
|
||||||
/* FIFO 0 assigned for the filter */
|
/* FIFO 1 assigned to 'id' */
|
||||||
SOC_CAN->FFA1R = 0;
|
SOC_CAN->FFA1R = (1<<2);
|
||||||
|
|
||||||
/* Filter activation */
|
/* Filter activation */
|
||||||
SOC_CAN->FA1R = filternbrbitpos;
|
SOC_CAN->FA1R = (1<<0) | (id ? (1<<1) | (1<<2) : 0);
|
||||||
/* Leave the initialisation mode for the filter */
|
/* Leave the initialisation mode for the filter */
|
||||||
SOC_CAN->FMR &= ~CAN_FMR_FINIT;
|
SOC_CAN->FMR &= ~CAN_FMR_FINIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
canbus_set_dataport(uint32_t id)
|
|
||||||
{
|
|
||||||
can_set_filter(CANBUS_ID_UUID, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
canbus_reboot(void)
|
|
||||||
{
|
|
||||||
NVIC_SystemReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function handles CAN global interrupts
|
// This function handles CAN global interrupts
|
||||||
void
|
void
|
||||||
CAN_IRQHandler(void)
|
CAN_IRQHandler(void)
|
||||||
{
|
{
|
||||||
if (SOC_CAN->RF0R & CAN_RF0R_FMP0) {
|
if (SOC_CAN->RF1R & CAN_RF1R_FMP1) {
|
||||||
// Rx
|
// Read and ack data packet
|
||||||
SOC_CAN->IER &= ~CAN_IER_FMPIE0;
|
CAN_FIFOMailBox_TypeDef *mb = &SOC_CAN->sFIFOMailBox[1];
|
||||||
canbus_notify_rx();
|
uint32_t rir_id = (mb->RIR >> CAN_RI0R_STID_Pos) & 0x7FF;
|
||||||
|
uint32_t dlc = mb->RDTR & CAN_RDT0R_DLC;
|
||||||
|
uint32_t rdlr = mb->RDLR, rdhr = mb->RDHR;
|
||||||
|
SOC_CAN->RF1R = CAN_RF1R_RFOM1;
|
||||||
|
|
||||||
|
// Process packet
|
||||||
|
union {
|
||||||
|
struct { uint32_t rdlr, rdhr; };
|
||||||
|
uint8_t data[8];
|
||||||
|
} rdata = { .rdlr = rdlr, .rdhr = rdhr };
|
||||||
|
canbus_process_data(rir_id, dlc, rdata.data);
|
||||||
}
|
}
|
||||||
uint32_t ier = SOC_CAN->IER;
|
uint32_t ier = SOC_CAN->IER;
|
||||||
|
if (ier & CAN_IER_FMPIE0 && SOC_CAN->RF0R & CAN_RF0R_FMP0) {
|
||||||
|
// Admin Rx
|
||||||
|
SOC_CAN->IER = ier = ier & ~CAN_IER_FMPIE0;
|
||||||
|
canbus_notify_rx();
|
||||||
|
}
|
||||||
if (ier & CAN_IER_TMEIE
|
if (ier & CAN_IER_TMEIE
|
||||||
&& SOC_CAN->TSR & (CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2)) {
|
&& SOC_CAN->TSR & (CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2)) {
|
||||||
// Tx
|
// Tx
|
||||||
SOC_CAN->IER &= ~CAN_IER_TMEIE;
|
SOC_CAN->IER = ier & ~CAN_IER_TMEIE;
|
||||||
canbus_notify_tx();
|
canbus_notify_tx();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,6 +267,12 @@ compute_btr(uint32_t pclock, uint32_t bitrate)
|
|||||||
return make_btr(sjw, time_seg1, time_seg2, brp);
|
return make_btr(sjw, time_seg1, time_seg2, brp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
canbus_reboot(void)
|
||||||
|
{
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
can_init(void)
|
can_init(void)
|
||||||
{
|
{
|
||||||
@ -270,7 +283,7 @@ can_init(void)
|
|||||||
|
|
||||||
uint32_t pclock = get_pclock_frequency((uint32_t)SOC_CAN);
|
uint32_t pclock = get_pclock_frequency((uint32_t)SOC_CAN);
|
||||||
|
|
||||||
uint32_t btr = compute_btr(pclock, CONFIG_CANBUS_BAUD);
|
uint32_t btr = compute_btr(pclock, CONFIG_CANBUS_FREQUENCY);
|
||||||
|
|
||||||
/*##-1- Configure the CAN #######################################*/
|
/*##-1- Configure the CAN #######################################*/
|
||||||
|
|
||||||
@ -290,17 +303,15 @@ can_init(void)
|
|||||||
;
|
;
|
||||||
|
|
||||||
/*##-2- Configure the CAN Filter #######################################*/
|
/*##-2- Configure the CAN Filter #######################################*/
|
||||||
can_set_filter(CANBUS_ID_UUID, CANBUS_ID_SET);
|
canbus_set_filter(0);
|
||||||
|
|
||||||
/*##-3- Configure Interrupts #################################*/
|
/*##-3- Configure Interrupts #################################*/
|
||||||
|
|
||||||
SOC_CAN->IER = CAN_IER_FMPIE0; // RX mailbox IRQ
|
|
||||||
|
|
||||||
armcm_enable_irq(CAN_IRQHandler, CAN_RX0_IRQn, 0);
|
armcm_enable_irq(CAN_IRQHandler, CAN_RX0_IRQn, 0);
|
||||||
if (CAN_RX0_IRQn != CAN_RX1_IRQn)
|
if (CAN_RX0_IRQn != CAN_RX1_IRQn)
|
||||||
armcm_enable_irq(CAN_IRQHandler, CAN_RX1_IRQn, 0);
|
armcm_enable_irq(CAN_IRQHandler, CAN_RX1_IRQn, 0);
|
||||||
if (CAN_RX0_IRQn != CAN_TX_IRQn)
|
if (CAN_RX0_IRQn != CAN_TX_IRQn)
|
||||||
armcm_enable_irq(CAN_IRQHandler, CAN_TX_IRQn, 0);
|
armcm_enable_irq(CAN_IRQHandler, CAN_TX_IRQn, 0);
|
||||||
|
SOC_CAN->IER = CAN_IER_FMPIE1;
|
||||||
|
|
||||||
// Convert unique 96-bit chip id into 48 bit representation
|
// Convert unique 96-bit chip id into 48 bit representation
|
||||||
uint64_t hash = fasthash64((uint8_t*)UID_BASE, 12, 0xA16231A7);
|
uint64_t hash = fasthash64((uint8_t*)UID_BASE, 12, 0xA16231A7);
|
||||||
|
32
src/stm32/clockline.c
Normal file
32
src/stm32/clockline.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Code to enable clock lines on stm32
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 Kevin O'Connor <kevin@koconnor.net>
|
||||||
|
//
|
||||||
|
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
|
|
||||||
|
#include "board/irq.h" // irq_save
|
||||||
|
#include "internal.h" // struct cline
|
||||||
|
|
||||||
|
// Enable a peripheral clock
|
||||||
|
void
|
||||||
|
enable_pclock(uint32_t periph_base)
|
||||||
|
{
|
||||||
|
struct cline cl = lookup_clock_line(periph_base);
|
||||||
|
irqstatus_t flag = irq_save();
|
||||||
|
*cl.en |= cl.bit;
|
||||||
|
*cl.en; // Pause 2 cycles to ensure peripheral is enabled
|
||||||
|
if (cl.rst) {
|
||||||
|
// Reset peripheral
|
||||||
|
*cl.rst = cl.bit;
|
||||||
|
*cl.rst = 0;
|
||||||
|
}
|
||||||
|
irq_restore(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a peripheral clock has been enabled
|
||||||
|
int
|
||||||
|
is_enabled_pclock(uint32_t periph_base)
|
||||||
|
{
|
||||||
|
struct cline cl = lookup_clock_line(periph_base);
|
||||||
|
return *cl.en & cl.bit;
|
||||||
|
}
|
38
src/stm32/gpioperiph.c
Normal file
38
src/stm32/gpioperiph.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Code to setup gpio on stm32 chip (except for stm32f1)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019-2021 Kevin O'Connor <kevin@koconnor.net>
|
||||||
|
//
|
||||||
|
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
|
|
||||||
|
#include "internal.h" // gpio_peripheral
|
||||||
|
|
||||||
|
// Set the mode and extended function of a pin
|
||||||
|
void
|
||||||
|
gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup)
|
||||||
|
{
|
||||||
|
GPIO_TypeDef *regs = digital_regs[GPIO2PORT(gpio)];
|
||||||
|
|
||||||
|
// Enable GPIO clock
|
||||||
|
gpio_clock_enable(regs);
|
||||||
|
|
||||||
|
// Configure GPIO
|
||||||
|
uint32_t mode_bits = mode & 0xf, func = (mode >> 4) & 0xf, od = mode >> 8;
|
||||||
|
uint32_t pup = pullup ? (pullup > 0 ? 1 : 2) : 0;
|
||||||
|
uint32_t pos = gpio % 16, af_reg = pos / 8;
|
||||||
|
uint32_t af_shift = (pos % 8) * 4, af_msk = 0x0f << af_shift;
|
||||||
|
uint32_t m_shift = pos * 2, m_msk = 0x03 << m_shift;
|
||||||
|
|
||||||
|
regs->AFR[af_reg] = (regs->AFR[af_reg] & ~af_msk) | (func << af_shift);
|
||||||
|
regs->MODER = (regs->MODER & ~m_msk) | (mode_bits << m_shift);
|
||||||
|
regs->PUPDR = (regs->PUPDR & ~m_msk) | (pup << m_shift);
|
||||||
|
regs->OTYPER = (regs->OTYPER & ~(1 << pos)) | (od << pos);
|
||||||
|
|
||||||
|
// Setup OSPEEDR:
|
||||||
|
// stm32f0 is ~10Mhz at 50pF
|
||||||
|
// stm32f2 is ~25Mhz at 40pF
|
||||||
|
// stm32f4 is ~50Mhz at 40pF
|
||||||
|
// stm32g0 is ~30Mhz at 50pF
|
||||||
|
// stm32h7 is ~85Mhz at 50pF
|
||||||
|
uint32_t ospeed = CONFIG_MACH_STM32F0 ? 0x01 : 0x02;
|
||||||
|
regs->OSPEEDR = (regs->OSPEEDR & ~m_msk) | (ospeed << m_shift);
|
||||||
|
}
|
@ -12,24 +12,34 @@
|
|||||||
#include "stm32f2xx.h"
|
#include "stm32f2xx.h"
|
||||||
#elif CONFIG_MACH_STM32F4
|
#elif CONFIG_MACH_STM32F4
|
||||||
#include "stm32f4xx.h"
|
#include "stm32f4xx.h"
|
||||||
|
#elif CONFIG_MACH_STM32G0
|
||||||
|
#include "stm32g0xx.h"
|
||||||
|
#elif CONFIG_MACH_STM32H7
|
||||||
|
#include "stm32h7xx.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// gpio.c
|
||||||
extern GPIO_TypeDef * const digital_regs[];
|
extern GPIO_TypeDef * const digital_regs[];
|
||||||
|
|
||||||
#define GPIO(PORT, NUM) (((PORT)-'A') * 16 + (NUM))
|
#define GPIO(PORT, NUM) (((PORT)-'A') * 16 + (NUM))
|
||||||
#define GPIO2PORT(PIN) ((PIN) / 16)
|
#define GPIO2PORT(PIN) ((PIN) / 16)
|
||||||
#define GPIO2BIT(PIN) (1<<((PIN) % 16))
|
#define GPIO2BIT(PIN) (1<<((PIN) % 16))
|
||||||
|
|
||||||
|
// gpioperiph.c
|
||||||
#define GPIO_INPUT 0
|
#define GPIO_INPUT 0
|
||||||
#define GPIO_OUTPUT 1
|
#define GPIO_OUTPUT 1
|
||||||
#define GPIO_OPEN_DRAIN 0x100
|
#define GPIO_OPEN_DRAIN 0x100
|
||||||
#define GPIO_FUNCTION(fn) (2 | ((fn) << 4))
|
#define GPIO_FUNCTION(fn) (2 | ((fn) << 4))
|
||||||
#define GPIO_ANALOG 3
|
#define GPIO_ANALOG 3
|
||||||
|
|
||||||
void enable_pclock(uint32_t periph_base);
|
|
||||||
int is_enabled_pclock(uint32_t periph_base);
|
|
||||||
uint32_t get_pclock_frequency(uint32_t periph_base);
|
|
||||||
void gpio_clock_enable(GPIO_TypeDef *regs);
|
|
||||||
void gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup);
|
void gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup);
|
||||||
|
|
||||||
|
// clockline.c
|
||||||
|
void enable_pclock(uint32_t periph_base);
|
||||||
|
int is_enabled_pclock(uint32_t periph_base);
|
||||||
|
|
||||||
|
// stm32??.c
|
||||||
|
struct cline { volatile uint32_t *en, *rst; uint32_t bit; };
|
||||||
|
struct cline lookup_clock_line(uint32_t periph_base);
|
||||||
|
uint32_t get_pclock_frequency(uint32_t periph_base);
|
||||||
|
void gpio_clock_enable(GPIO_TypeDef *regs);
|
||||||
|
|
||||||
#endif // internal.h
|
#endif // internal.h
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code to setup clocks and gpio on stm32f0
|
// Code to setup clocks on stm32f0
|
||||||
//
|
//
|
||||||
// Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
|
// Copyright (C) 2019-2021 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.
|
||||||
|
|
||||||
@ -13,38 +13,19 @@
|
|||||||
|
|
||||||
#define FREQ_PERIPH 48000000
|
#define FREQ_PERIPH 48000000
|
||||||
|
|
||||||
// Enable a peripheral clock
|
// Map a peripheral address to its enable bits
|
||||||
void
|
struct cline
|
||||||
enable_pclock(uint32_t periph_base)
|
lookup_clock_line(uint32_t periph_base)
|
||||||
{
|
{
|
||||||
if (periph_base < SYSCFG_BASE) {
|
if (periph_base >= AHB2PERIPH_BASE) {
|
||||||
uint32_t pos = (periph_base - APBPERIPH_BASE) / 0x400;
|
uint32_t bit = 1 << ((periph_base - AHB2PERIPH_BASE) / 0x400 + 17);
|
||||||
RCC->APB1ENR |= 1 << pos;
|
return (struct cline){.en=&RCC->AHBENR, .rst=&RCC->AHBRSTR, .bit=bit};
|
||||||
RCC->APB1ENR;
|
} else if (periph_base >= SYSCFG_BASE) {
|
||||||
} else if (periph_base < AHBPERIPH_BASE) {
|
uint32_t bit = 1 << ((periph_base - SYSCFG_BASE) / 0x400);
|
||||||
uint32_t pos = (periph_base - SYSCFG_BASE) / 0x400;
|
return (struct cline){.en=&RCC->APB2ENR, .rst=&RCC->APB2RSTR, .bit=bit};
|
||||||
RCC->APB2ENR |= 1 << pos;
|
|
||||||
RCC->APB2ENR;
|
|
||||||
} else {
|
} else {
|
||||||
uint32_t pos = (periph_base - AHB2PERIPH_BASE) / 0x400;
|
uint32_t bit = 1 << ((periph_base - APBPERIPH_BASE) / 0x400);
|
||||||
RCC->AHBENR |= 1 << (pos + 17);
|
return (struct cline){.en=&RCC->APB1ENR, .rst=&RCC->APB1RSTR, .bit=bit};
|
||||||
RCC->AHBENR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if a peripheral clock has been enabled
|
|
||||||
int
|
|
||||||
is_enabled_pclock(uint32_t periph_base)
|
|
||||||
{
|
|
||||||
if (periph_base < SYSCFG_BASE) {
|
|
||||||
uint32_t pos = (periph_base - APBPERIPH_BASE) / 0x400;
|
|
||||||
return RCC->APB1ENR & (1 << pos);
|
|
||||||
} else if (periph_base < AHBPERIPH_BASE) {
|
|
||||||
uint32_t pos = (periph_base - SYSCFG_BASE) / 0x400;
|
|
||||||
return RCC->APB2ENR & (1 << pos);
|
|
||||||
} else {
|
|
||||||
uint32_t pos = (periph_base - AHB2PERIPH_BASE) / 0x400;
|
|
||||||
return RCC->AHBENR & (1 << (pos + 17));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,41 +45,6 @@ gpio_clock_enable(GPIO_TypeDef *regs)
|
|||||||
RCC->AHBENR;
|
RCC->AHBENR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the mode and extended function of a pin
|
|
||||||
void
|
|
||||||
gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup)
|
|
||||||
{
|
|
||||||
GPIO_TypeDef *regs = digital_regs[GPIO2PORT(gpio)];
|
|
||||||
|
|
||||||
// Enable GPIO clock
|
|
||||||
gpio_clock_enable(regs);
|
|
||||||
|
|
||||||
// Configure GPIO
|
|
||||||
uint32_t mode_bits = mode & 0xf, func = (mode >> 4) & 0xf, od = mode >> 8;
|
|
||||||
uint32_t pup = pullup ? (pullup > 0 ? 1 : 2) : 0;
|
|
||||||
uint32_t pos = gpio % 16, af_reg = pos / 8;
|
|
||||||
uint32_t af_shift = (pos % 8) * 4, af_msk = 0x0f << af_shift;
|
|
||||||
uint32_t m_shift = pos * 2, m_msk = 0x03 << m_shift;
|
|
||||||
|
|
||||||
regs->AFR[af_reg] = (regs->AFR[af_reg] & ~af_msk) | (func << af_shift);
|
|
||||||
regs->MODER = (regs->MODER & ~m_msk) | (mode_bits << m_shift);
|
|
||||||
regs->PUPDR = (regs->PUPDR & ~m_msk) | (pup << m_shift);
|
|
||||||
regs->OTYPER = (regs->OTYPER & ~(1 << pos)) | (od << pos);
|
|
||||||
regs->OSPEEDR = (regs->OSPEEDR & ~m_msk) | (0x02 << m_shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define USB_BOOT_FLAG_ADDR (CONFIG_RAM_START + CONFIG_RAM_SIZE - 1024)
|
|
||||||
#define USB_BOOT_FLAG 0x55534220424f4f54 // "USB BOOT"
|
|
||||||
|
|
||||||
// Handle USB reboot requests
|
|
||||||
void
|
|
||||||
usb_request_bootloader(void)
|
|
||||||
{
|
|
||||||
irq_disable();
|
|
||||||
*(uint64_t*)USB_BOOT_FLAG_ADDR = USB_BOOT_FLAG;
|
|
||||||
NVIC_SystemReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure and enable the PLL as clock source
|
// Configure and enable the PLL as clock source
|
||||||
static void
|
static void
|
||||||
pll_setup(void)
|
pll_setup(void)
|
||||||
@ -160,7 +106,7 @@ armcm_main(void)
|
|||||||
|
|
||||||
// Support pin remapping USB/CAN pins on low pinout stm32f042
|
// Support pin remapping USB/CAN pins on low pinout stm32f042
|
||||||
#ifdef SYSCFG_CFGR1_PA11_PA12_RMP
|
#ifdef SYSCFG_CFGR1_PA11_PA12_RMP
|
||||||
if (CONFIG_STM32F042_PIN_SWAP) {
|
if (CONFIG_STM32_CANBUS_PA11_PA12_REMAP) {
|
||||||
enable_pclock(SYSCFG_BASE);
|
enable_pclock(SYSCFG_BASE);
|
||||||
SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;
|
SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code to setup clocks and gpio on stm32f1
|
// Code to setup clocks and gpio on stm32f1
|
||||||
//
|
//
|
||||||
// Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
|
// Copyright (C) 2019-2021 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.
|
||||||
|
|
||||||
@ -13,38 +13,19 @@
|
|||||||
|
|
||||||
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 2)
|
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 2)
|
||||||
|
|
||||||
// Enable a peripheral clock
|
// Map a peripheral address to its enable bits
|
||||||
void
|
struct cline
|
||||||
enable_pclock(uint32_t periph_base)
|
lookup_clock_line(uint32_t periph_base)
|
||||||
{
|
{
|
||||||
if (periph_base < APB2PERIPH_BASE) {
|
if (periph_base >= AHBPERIPH_BASE) {
|
||||||
uint32_t pos = (periph_base - APB1PERIPH_BASE) / 0x400;
|
uint32_t bit = 1 << ((periph_base - AHBPERIPH_BASE) / 0x400);
|
||||||
RCC->APB1ENR |= (1<<pos);
|
return (struct cline){.en=&RCC->AHBENR, .bit=bit};
|
||||||
RCC->APB1ENR;
|
} else if (periph_base >= APB2PERIPH_BASE) {
|
||||||
} else if (periph_base < AHBPERIPH_BASE) {
|
uint32_t bit = 1 << ((periph_base - APB2PERIPH_BASE) / 0x400);
|
||||||
uint32_t pos = (periph_base - APB2PERIPH_BASE) / 0x400;
|
return (struct cline){.en=&RCC->APB2ENR, .rst=&RCC->APB2RSTR, .bit=bit};
|
||||||
RCC->APB2ENR |= (1<<pos);
|
|
||||||
RCC->APB2ENR;
|
|
||||||
} else {
|
} else {
|
||||||
uint32_t pos = (periph_base - AHBPERIPH_BASE) / 0x400;
|
uint32_t bit = 1 << ((periph_base - APB1PERIPH_BASE) / 0x400);
|
||||||
RCC->AHBENR |= (1<<pos);
|
return (struct cline){.en=&RCC->APB1ENR, .rst=&RCC->APB1RSTR, .bit=bit};
|
||||||
RCC->AHBENR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if a peripheral clock has been enabled
|
|
||||||
int
|
|
||||||
is_enabled_pclock(uint32_t periph_base)
|
|
||||||
{
|
|
||||||
if (periph_base < APB2PERIPH_BASE) {
|
|
||||||
uint32_t pos = (periph_base - APB1PERIPH_BASE) / 0x400;
|
|
||||||
return RCC->APB1ENR & (1<<pos);
|
|
||||||
} else if (periph_base < AHBPERIPH_BASE) {
|
|
||||||
uint32_t pos = (periph_base - APB2PERIPH_BASE) / 0x400;
|
|
||||||
return RCC->APB2ENR & (1<<pos);
|
|
||||||
} else {
|
|
||||||
uint32_t pos = (periph_base - AHBPERIPH_BASE) / 0x400;
|
|
||||||
return RCC->AHBENR & (1<<pos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,74 +45,6 @@ gpio_clock_enable(GPIO_TypeDef *regs)
|
|||||||
RCC->APB2ENR;
|
RCC->APB2ENR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void stm32f1_alternative_remap(uint32_t mapr_mask, uint32_t mapr_value)
|
|
||||||
{
|
|
||||||
// The MAPR register is a mix of write only and r/w bits
|
|
||||||
// We have to save the written values in a global variable
|
|
||||||
static uint32_t mapr = 0;
|
|
||||||
|
|
||||||
mapr &= ~mapr_mask;
|
|
||||||
mapr |= mapr_value;
|
|
||||||
AFIO->MAPR = mapr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the mode and extended function of a pin
|
|
||||||
void
|
|
||||||
gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup)
|
|
||||||
{
|
|
||||||
GPIO_TypeDef *regs = digital_regs[GPIO2PORT(gpio)];
|
|
||||||
|
|
||||||
// Enable GPIO clock
|
|
||||||
gpio_clock_enable(regs);
|
|
||||||
|
|
||||||
// Configure GPIO
|
|
||||||
uint32_t pos = gpio % 16, shift = (pos % 8) * 4, msk = 0xf << shift, cfg;
|
|
||||||
if (mode == GPIO_INPUT) {
|
|
||||||
cfg = pullup ? 0x8 : 0x4;
|
|
||||||
} else if (mode == GPIO_OUTPUT) {
|
|
||||||
cfg = 0x1;
|
|
||||||
} else if (mode == (GPIO_OUTPUT | GPIO_OPEN_DRAIN)) {
|
|
||||||
cfg = 0x5;
|
|
||||||
} else if (mode == GPIO_ANALOG) {
|
|
||||||
cfg = 0x0;
|
|
||||||
} else {
|
|
||||||
if (mode & GPIO_OPEN_DRAIN)
|
|
||||||
// Alternate function with open-drain mode
|
|
||||||
cfg = 0xd;
|
|
||||||
else if (pullup > 0)
|
|
||||||
// Alternate function input pins use GPIO_INPUT mode on the stm32f1
|
|
||||||
cfg = 0x8;
|
|
||||||
else
|
|
||||||
cfg = 0x9;
|
|
||||||
}
|
|
||||||
if (pos & 0x8)
|
|
||||||
regs->CRH = (regs->CRH & ~msk) | (cfg << shift);
|
|
||||||
else
|
|
||||||
regs->CRL = (regs->CRL & ~msk) | (cfg << shift);
|
|
||||||
|
|
||||||
if (pullup > 0)
|
|
||||||
regs->BSRR = 1 << pos;
|
|
||||||
else if (pullup < 0)
|
|
||||||
regs->BSRR = 1 << (pos + 16);
|
|
||||||
|
|
||||||
if (gpio == GPIO('A', 13) || gpio == GPIO('A', 14))
|
|
||||||
// Disable SWD to free PA13, PA14
|
|
||||||
stm32f1_alternative_remap(AFIO_MAPR_SWJ_CFG_Msk,
|
|
||||||
AFIO_MAPR_SWJ_CFG_DISABLE);
|
|
||||||
|
|
||||||
// STM32F1 remaps functions to pins in a very different
|
|
||||||
// way from other STM32s.
|
|
||||||
// Code below is emulating a few mappings to work like an STM32F4
|
|
||||||
uint32_t func = (mode >> 4) & 0xf;
|
|
||||||
if(( gpio == GPIO('B', 8) || gpio == GPIO('B', 9)) &&
|
|
||||||
func == 9) { // CAN
|
|
||||||
stm32f1_alternative_remap(AFIO_MAPR_CAN_REMAP_Msk,
|
|
||||||
AFIO_MAPR_CAN_REMAP_REMAP2);
|
|
||||||
}
|
|
||||||
// Add more as needed
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main clock setup called at chip startup
|
// Main clock setup called at chip startup
|
||||||
static void
|
static void
|
||||||
clock_setup(void)
|
clock_setup(void)
|
||||||
@ -140,9 +53,14 @@ clock_setup(void)
|
|||||||
uint32_t cfgr;
|
uint32_t cfgr;
|
||||||
if (!CONFIG_STM32_CLOCK_REF_INTERNAL) {
|
if (!CONFIG_STM32_CLOCK_REF_INTERNAL) {
|
||||||
// Configure 72Mhz PLL from external crystal (HSE)
|
// Configure 72Mhz PLL from external crystal (HSE)
|
||||||
uint32_t div = CONFIG_CLOCK_FREQ / CONFIG_CLOCK_REF_FREQ;
|
|
||||||
RCC->CR |= RCC_CR_HSEON;
|
RCC->CR |= RCC_CR_HSEON;
|
||||||
cfgr = (1 << RCC_CFGR_PLLSRC_Pos) | ((div - 2) << RCC_CFGR_PLLMULL_Pos);
|
uint32_t div = CONFIG_CLOCK_FREQ / (CONFIG_CLOCK_REF_FREQ / 2);
|
||||||
|
cfgr = 1 << RCC_CFGR_PLLSRC_Pos;
|
||||||
|
if ((div & 1) && div <= 16)
|
||||||
|
cfgr |= RCC_CFGR_PLLXTPRE_HSE_DIV2;
|
||||||
|
else
|
||||||
|
div /= 2;
|
||||||
|
cfgr |= (div - 2) << RCC_CFGR_PLLMULL_Pos;
|
||||||
} else {
|
} else {
|
||||||
// Configure 72Mhz PLL from internal 8Mhz oscillator (HSI)
|
// Configure 72Mhz PLL from internal 8Mhz oscillator (HSI)
|
||||||
uint32_t div2 = (CONFIG_CLOCK_FREQ / 8000000) * 2;
|
uint32_t div2 = (CONFIG_CLOCK_FREQ / 8000000) * 2;
|
||||||
@ -166,6 +84,131 @@ clock_setup(void)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* GPIO setup
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
stm32f1_alternative_remap(uint32_t mapr_mask, uint32_t mapr_value)
|
||||||
|
{
|
||||||
|
// The MAPR register is a mix of write only and r/w bits
|
||||||
|
// We have to save the written values in a global variable
|
||||||
|
static uint32_t mapr = 0;
|
||||||
|
|
||||||
|
mapr &= ~mapr_mask;
|
||||||
|
mapr |= mapr_value;
|
||||||
|
AFIO->MAPR = mapr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define STM_OSPEED 0x1 // ~10Mhz at 50pF
|
||||||
|
|
||||||
|
// Set the mode and extended function of a pin
|
||||||
|
void
|
||||||
|
gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup)
|
||||||
|
{
|
||||||
|
GPIO_TypeDef *regs = digital_regs[GPIO2PORT(gpio)];
|
||||||
|
|
||||||
|
// Enable GPIO clock
|
||||||
|
gpio_clock_enable(regs);
|
||||||
|
|
||||||
|
// Configure GPIO
|
||||||
|
uint32_t pos = gpio % 16, shift = (pos % 8) * 4, msk = 0xf << shift, cfg;
|
||||||
|
if (mode == GPIO_INPUT) {
|
||||||
|
cfg = pullup ? 0x8 : 0x4;
|
||||||
|
} else if (mode == GPIO_OUTPUT) {
|
||||||
|
cfg = STM_OSPEED;
|
||||||
|
} else if (mode == (GPIO_OUTPUT | GPIO_OPEN_DRAIN)) {
|
||||||
|
cfg = 0x4 | STM_OSPEED;
|
||||||
|
} else if (mode == GPIO_ANALOG) {
|
||||||
|
cfg = 0x0;
|
||||||
|
} else {
|
||||||
|
if (mode & GPIO_OPEN_DRAIN)
|
||||||
|
// Alternate function with open-drain mode
|
||||||
|
cfg = 0xc | STM_OSPEED;
|
||||||
|
else if (pullup > 0)
|
||||||
|
// Alternate function input pins use GPIO_INPUT mode on the stm32f1
|
||||||
|
cfg = 0x8;
|
||||||
|
else
|
||||||
|
cfg = 0x8 | STM_OSPEED;
|
||||||
|
}
|
||||||
|
if (pos & 0x8)
|
||||||
|
regs->CRH = (regs->CRH & ~msk) | (cfg << shift);
|
||||||
|
else
|
||||||
|
regs->CRL = (regs->CRL & ~msk) | (cfg << shift);
|
||||||
|
|
||||||
|
if (pullup > 0)
|
||||||
|
regs->BSRR = 1 << pos;
|
||||||
|
else if (pullup < 0)
|
||||||
|
regs->BSRR = 1 << (pos + 16);
|
||||||
|
|
||||||
|
if (gpio == GPIO('A', 13) || gpio == GPIO('A', 14))
|
||||||
|
// Disable SWD to free PA13, PA14
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_SWJ_CFG_Msk,
|
||||||
|
AFIO_MAPR_SWJ_CFG_DISABLE);
|
||||||
|
|
||||||
|
// STM32F1 remaps functions to pins in a very different
|
||||||
|
// way from other STM32s.
|
||||||
|
// Code below is emulating a few mappings to work like an STM32F4
|
||||||
|
uint32_t func = (mode >> 4) & 0xf;
|
||||||
|
if (func == 1) {
|
||||||
|
// TIM2
|
||||||
|
if (gpio == GPIO('A', 15) || gpio == GPIO('B', 3))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_TIM2_REMAP_Msk,
|
||||||
|
AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1);
|
||||||
|
else if (gpio == GPIO('B', 10) || gpio == GPIO('B', 11))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_TIM2_REMAP_Msk,
|
||||||
|
AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2);
|
||||||
|
} else if (func == 2) {
|
||||||
|
// TIM3 and TIM4
|
||||||
|
if (gpio == GPIO('B', 4) || gpio == GPIO('B', 5))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_TIM3_REMAP_Msk,
|
||||||
|
AFIO_MAPR_TIM3_REMAP_PARTIALREMAP);
|
||||||
|
else if (gpio == GPIO('C', 6) || gpio == GPIO('C', 7)
|
||||||
|
|| gpio == GPIO('C', 8) || gpio == GPIO('C', 9))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_TIM3_REMAP_Msk,
|
||||||
|
AFIO_MAPR_TIM3_REMAP_FULLREMAP);
|
||||||
|
else if (gpio == GPIO('D', 12) || gpio == GPIO('D', 13)
|
||||||
|
|| gpio == GPIO('D', 14) || gpio == GPIO('D', 15))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_TIM4_REMAP_Msk,
|
||||||
|
AFIO_MAPR_TIM4_REMAP);
|
||||||
|
} else if (func == 4) {
|
||||||
|
// I2C
|
||||||
|
if (gpio == GPIO('B', 8) || gpio == GPIO('B', 9))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_I2C1_REMAP_Msk,
|
||||||
|
AFIO_MAPR_I2C1_REMAP);
|
||||||
|
} else if (func == 5) {
|
||||||
|
// SPI
|
||||||
|
if (gpio == GPIO('B', 3) || gpio == GPIO('B', 4)
|
||||||
|
|| gpio == GPIO('B', 5))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_SPI1_REMAP_Msk,
|
||||||
|
AFIO_MAPR_SPI1_REMAP);
|
||||||
|
} else if (func == 7) {
|
||||||
|
// USART
|
||||||
|
if (gpio == GPIO('B', 6) || gpio == GPIO('B', 7))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_USART1_REMAP_Msk,
|
||||||
|
AFIO_MAPR_USART1_REMAP);
|
||||||
|
else if (gpio == GPIO('D', 5) || gpio == GPIO('D', 6))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_USART2_REMAP_Msk,
|
||||||
|
AFIO_MAPR_USART2_REMAP);
|
||||||
|
else if (gpio == GPIO('D', 8) || gpio == GPIO('D', 9))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_USART3_REMAP_Msk,
|
||||||
|
AFIO_MAPR_USART3_REMAP_FULLREMAP);
|
||||||
|
} else if (func == 9) {
|
||||||
|
// CAN
|
||||||
|
if (gpio == GPIO('B', 8) || gpio == GPIO('B', 9))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_CAN_REMAP_Msk,
|
||||||
|
AFIO_MAPR_CAN_REMAP_REMAP2);
|
||||||
|
if (gpio == GPIO('D', 0) || gpio == GPIO('D', 1))
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_CAN_REMAP_Msk,
|
||||||
|
AFIO_MAPR_CAN_REMAP_REMAP3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Startup
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
// Main entry point - called from armcm_boot.c:ResetHandler()
|
// Main entry point - called from armcm_boot.c:ResetHandler()
|
||||||
void
|
void
|
||||||
armcm_main(void)
|
armcm_main(void)
|
||||||
@ -174,7 +217,7 @@ armcm_main(void)
|
|||||||
SystemInit();
|
SystemInit();
|
||||||
SCB->VTOR = (uint32_t)VectorTable;
|
SCB->VTOR = (uint32_t)VectorTable;
|
||||||
|
|
||||||
// Reset peripheral clocks
|
// Reset peripheral clocks (for some bootloaders that don't)
|
||||||
RCC->AHBENR = 0x14;
|
RCC->AHBENR = 0x14;
|
||||||
RCC->APB1ENR = 0;
|
RCC->APB1ENR = 0;
|
||||||
RCC->APB2ENR = 0;
|
RCC->APB2ENR = 0;
|
||||||
@ -184,8 +227,13 @@ armcm_main(void)
|
|||||||
|
|
||||||
// Disable JTAG to free PA15, PB3, PB4
|
// Disable JTAG to free PA15, PB3, PB4
|
||||||
enable_pclock(AFIO_BASE);
|
enable_pclock(AFIO_BASE);
|
||||||
stm32f1_alternative_remap(AFIO_MAPR_SWJ_CFG_Msk,
|
if (CONFIG_STM32F103GD_DISABLE_SWD)
|
||||||
AFIO_MAPR_SWJ_CFG_JTAGDISABLE);
|
// GigaDevice clone can't enable PA13/PA14 at runtime - enable here
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_SWJ_CFG_Msk,
|
||||||
|
AFIO_MAPR_SWJ_CFG_DISABLE);
|
||||||
|
else
|
||||||
|
stm32f1_alternative_remap(AFIO_MAPR_SWJ_CFG_Msk,
|
||||||
|
AFIO_MAPR_SWJ_CFG_JTAGDISABLE);
|
||||||
|
|
||||||
canboot_main();
|
canboot_main();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code to setup clocks and gpio on stm32f2/stm32f4
|
// Code to setup clocks on stm32f2/stm32f4
|
||||||
//
|
//
|
||||||
// Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
|
// Copyright (C) 2019-2021 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.
|
||||||
|
|
||||||
@ -11,45 +11,34 @@
|
|||||||
#include "internal.h" // enable_pclock
|
#include "internal.h" // enable_pclock
|
||||||
#include "canboot_main.h" // sched_main
|
#include "canboot_main.h" // sched_main
|
||||||
|
|
||||||
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 4)
|
|
||||||
|
/****************************************************************
|
||||||
|
* Clock setup
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
#define FREQ_PERIPH_DIV (CONFIG_MACH_STM32F401 ? 2 : 4)
|
||||||
|
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / FREQ_PERIPH_DIV)
|
||||||
#define FREQ_USB 48000000
|
#define FREQ_USB 48000000
|
||||||
|
|
||||||
// Enable a peripheral clock
|
// Map a peripheral address to its enable bits
|
||||||
void
|
struct cline
|
||||||
enable_pclock(uint32_t periph_base)
|
lookup_clock_line(uint32_t periph_base)
|
||||||
{
|
{
|
||||||
if (periph_base < APB2PERIPH_BASE) {
|
if (periph_base >= AHB1PERIPH_BASE) {
|
||||||
uint32_t pos = (periph_base - APB1PERIPH_BASE) / 0x400;
|
uint32_t bit = 1 << ((periph_base - AHB1PERIPH_BASE) / 0x400);
|
||||||
RCC->APB1ENR |= (1<<pos);
|
return (struct cline){.en=&RCC->AHB1ENR, .rst=&RCC->AHB1RSTR, .bit=bit};
|
||||||
RCC->APB1ENR;
|
} else if (periph_base >= APB2PERIPH_BASE) {
|
||||||
} else if (periph_base < AHB1PERIPH_BASE) {
|
uint32_t bit = 1 << ((periph_base - APB2PERIPH_BASE) / 0x400);
|
||||||
uint32_t pos = (periph_base - APB2PERIPH_BASE) / 0x400;
|
if (bit & 0x700)
|
||||||
RCC->APB2ENR |= (1<<pos);
|
// Skip ADC peripheral reset as they share a bit
|
||||||
RCC->APB2ENR;
|
return (struct cline){.en=&RCC->APB2ENR, .bit=bit};
|
||||||
} else if (periph_base < AHB2PERIPH_BASE) {
|
return (struct cline){.en=&RCC->APB2ENR, .rst=&RCC->APB2RSTR, .bit=bit};
|
||||||
uint32_t pos = (periph_base - AHB1PERIPH_BASE) / 0x400;
|
} else {
|
||||||
RCC->AHB1ENR |= (1<<pos);
|
uint32_t bit = 1 << ((periph_base - APB1PERIPH_BASE) / 0x400);
|
||||||
RCC->AHB1ENR;
|
return (struct cline){.en=&RCC->APB1ENR, .rst=&RCC->APB1RSTR, .bit=bit};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a peripheral clock has been enabled
|
|
||||||
int
|
|
||||||
is_enabled_pclock(uint32_t periph_base)
|
|
||||||
{
|
|
||||||
if (periph_base < APB2PERIPH_BASE) {
|
|
||||||
uint32_t pos = (periph_base - APB1PERIPH_BASE) / 0x400;
|
|
||||||
return RCC->APB1ENR & (1<<pos);
|
|
||||||
} else if (periph_base < AHB1PERIPH_BASE) {
|
|
||||||
uint32_t pos = (periph_base - APB2PERIPH_BASE) / 0x400;
|
|
||||||
return RCC->APB2ENR & (1<<pos);
|
|
||||||
} else if (periph_base < AHB2PERIPH_BASE) {
|
|
||||||
uint32_t pos = (periph_base - AHB1PERIPH_BASE) / 0x400;
|
|
||||||
return RCC->AHB1ENR & (1<<pos);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the frequency of the given peripheral clock
|
// Return the frequency of the given peripheral clock
|
||||||
uint32_t
|
uint32_t
|
||||||
get_pclock_frequency(uint32_t periph_base)
|
get_pclock_frequency(uint32_t periph_base)
|
||||||
@ -66,52 +55,6 @@ gpio_clock_enable(GPIO_TypeDef *regs)
|
|||||||
RCC->AHB1ENR;
|
RCC->AHB1ENR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the mode and extended function of a pin
|
|
||||||
void
|
|
||||||
gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup)
|
|
||||||
{
|
|
||||||
GPIO_TypeDef *regs = digital_regs[GPIO2PORT(gpio)];
|
|
||||||
|
|
||||||
// Enable GPIO clock
|
|
||||||
gpio_clock_enable(regs);
|
|
||||||
|
|
||||||
// Configure GPIO
|
|
||||||
uint32_t mode_bits = mode & 0xf, func = (mode >> 4) & 0xf, od = mode >> 8;
|
|
||||||
uint32_t pup = pullup ? (pullup > 0 ? 1 : 2) : 0;
|
|
||||||
uint32_t pos = gpio % 16, af_reg = pos / 8;
|
|
||||||
uint32_t af_shift = (pos % 8) * 4, af_msk = 0x0f << af_shift;
|
|
||||||
uint32_t m_shift = pos * 2, m_msk = 0x03 << m_shift;
|
|
||||||
|
|
||||||
regs->AFR[af_reg] = (regs->AFR[af_reg] & ~af_msk) | (func << af_shift);
|
|
||||||
regs->MODER = (regs->MODER & ~m_msk) | (mode_bits << m_shift);
|
|
||||||
regs->PUPDR = (regs->PUPDR & ~m_msk) | (pup << m_shift);
|
|
||||||
regs->OTYPER = (regs->OTYPER & ~(1 << pos)) | (od << pos);
|
|
||||||
regs->OSPEEDR = (regs->OSPEEDR & ~m_msk) | (0x02 << m_shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define USB_BOOT_FLAG_ADDR (CONFIG_RAM_START + CONFIG_RAM_SIZE - 4096)
|
|
||||||
#define USB_BOOT_FLAG 0x55534220424f4f54 // "USB BOOT"
|
|
||||||
|
|
||||||
// Handle USB reboot requests
|
|
||||||
void
|
|
||||||
usb_request_bootloader(void)
|
|
||||||
{
|
|
||||||
irq_disable();
|
|
||||||
if (CONFIG_STM32_FLASH_START_4000) {
|
|
||||||
// HID Bootloader
|
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
|
|
||||||
RCC->APB1ENR;
|
|
||||||
PWR->CR |= PWR_CR_DBP;
|
|
||||||
// HID Bootloader magic key
|
|
||||||
RTC->BKP4R = 0x424C;
|
|
||||||
PWR->CR &= ~PWR_CR_DBP;
|
|
||||||
} else {
|
|
||||||
// System DFU Bootloader
|
|
||||||
*(uint64_t*)USB_BOOT_FLAG_ADDR = USB_BOOT_FLAG;
|
|
||||||
}
|
|
||||||
NVIC_SystemReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clock configuration
|
// Clock configuration
|
||||||
static void
|
static void
|
||||||
enable_clock_stm32f20x(void)
|
enable_clock_stm32f20x(void)
|
||||||
@ -138,8 +81,10 @@ enable_clock_stm32f20x(void)
|
|||||||
static void
|
static void
|
||||||
enable_clock_stm32f40x(void)
|
enable_clock_stm32f40x(void)
|
||||||
{
|
{
|
||||||
#if CONFIG_MACH_STM32F405 || CONFIG_MACH_STM32F407
|
#if CONFIG_MACH_STM32F401 || CONFIG_MACH_STM32F4x5
|
||||||
uint32_t pll_base = 2000000, pll_freq = CONFIG_CLOCK_FREQ * 2, pllcfgr;
|
uint32_t pll_base = (CONFIG_STM32_CLOCK_REF_25M) ? 1000000 : 2000000;
|
||||||
|
uint32_t pllp = (CONFIG_MACH_STM32F401) ? 4 : 2;
|
||||||
|
uint32_t pll_freq = CONFIG_CLOCK_FREQ * pllp, pllcfgr;
|
||||||
if (!CONFIG_STM32_CLOCK_REF_INTERNAL) {
|
if (!CONFIG_STM32_CLOCK_REF_INTERNAL) {
|
||||||
// Configure 168Mhz PLL from external crystal (HSE)
|
// Configure 168Mhz PLL from external crystal (HSE)
|
||||||
uint32_t div = CONFIG_CLOCK_REF_FREQ / pll_base;
|
uint32_t div = CONFIG_CLOCK_REF_FREQ / pll_base;
|
||||||
@ -151,7 +96,7 @@ enable_clock_stm32f40x(void)
|
|||||||
pllcfgr = RCC_PLLCFGR_PLLSRC_HSI | (div << RCC_PLLCFGR_PLLM_Pos);
|
pllcfgr = RCC_PLLCFGR_PLLSRC_HSI | (div << RCC_PLLCFGR_PLLM_Pos);
|
||||||
}
|
}
|
||||||
RCC->PLLCFGR = (pllcfgr | ((pll_freq/pll_base) << RCC_PLLCFGR_PLLN_Pos)
|
RCC->PLLCFGR = (pllcfgr | ((pll_freq/pll_base) << RCC_PLLCFGR_PLLN_Pos)
|
||||||
| (0 << RCC_PLLCFGR_PLLP_Pos)
|
| (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_Pos)
|
||||||
| ((pll_freq/FREQ_USB) << RCC_PLLCFGR_PLLQ_Pos));
|
| ((pll_freq/FREQ_USB) << RCC_PLLCFGR_PLLQ_Pos));
|
||||||
RCC->CR |= RCC_CR_PLLON;
|
RCC->CR |= RCC_CR_PLLON;
|
||||||
#endif
|
#endif
|
||||||
@ -213,7 +158,7 @@ clock_setup(void)
|
|||||||
// Configure and enable PLL
|
// Configure and enable PLL
|
||||||
if (CONFIG_MACH_STM32F207)
|
if (CONFIG_MACH_STM32F207)
|
||||||
enable_clock_stm32f20x();
|
enable_clock_stm32f20x();
|
||||||
else if (CONFIG_MACH_STM32F405 || CONFIG_MACH_STM32F407)
|
else if (CONFIG_MACH_STM32F4x5)
|
||||||
enable_clock_stm32f40x();
|
enable_clock_stm32f40x();
|
||||||
else
|
else
|
||||||
enable_clock_stm32f446();
|
enable_clock_stm32f446();
|
||||||
@ -227,26 +172,32 @@ clock_setup(void)
|
|||||||
;
|
;
|
||||||
|
|
||||||
// Switch system clock to PLL
|
// Switch system clock to PLL
|
||||||
RCC->CFGR = RCC_CFGR_PPRE1_DIV4 | RCC_CFGR_PPRE2_DIV4 | RCC_CFGR_SW_PLL;
|
if (FREQ_PERIPH_DIV == 2)
|
||||||
|
RCC->CFGR = RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_SW_PLL;
|
||||||
|
else
|
||||||
|
RCC->CFGR = RCC_CFGR_PPRE1_DIV4 | RCC_CFGR_PPRE2_DIV4 | RCC_CFGR_SW_PLL;
|
||||||
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL)
|
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Startup
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
// Main entry point - called from armcm_boot.c:ResetHandler()
|
// Main entry point - called from armcm_boot.c:ResetHandler()
|
||||||
void
|
void
|
||||||
armcm_main(void)
|
armcm_main(void)
|
||||||
{
|
{
|
||||||
if (CONFIG_USBSERIAL && *(uint64_t*)USB_BOOT_FLAG_ADDR == USB_BOOT_FLAG) {
|
|
||||||
*(uint64_t*)USB_BOOT_FLAG_ADDR = 0;
|
|
||||||
uint32_t *sysbase = (uint32_t*)0x1fff0000;
|
|
||||||
asm volatile("mov sp, %0\n bx %1"
|
|
||||||
: : "r"(sysbase[0]), "r"(sysbase[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run SystemInit() and then restore VTOR
|
// Run SystemInit() and then restore VTOR
|
||||||
SystemInit();
|
SystemInit();
|
||||||
SCB->VTOR = (uint32_t)VectorTable;
|
SCB->VTOR = (uint32_t)VectorTable;
|
||||||
|
|
||||||
|
// Reset peripheral clocks (for some bootloaders that don't)
|
||||||
|
RCC->AHB1ENR = 0x38000;
|
||||||
|
RCC->AHB2ENR = 0;
|
||||||
|
RCC->APB1ENR = 0;
|
||||||
|
RCC->APB2ENR = 0;
|
||||||
|
|
||||||
clock_setup();
|
clock_setup();
|
||||||
|
|
||||||
sched_main();
|
sched_main();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user