stm32l4: add stm32l412 support with adc,i2c,spi,usb
Signed-off-by: Matt Baker <baker.matt.j@gmail.com>
This commit is contained in:
parent
57b0eb5d43
commit
d9c917b950
|
@ -72,6 +72,7 @@ class PrinterTemperatureMCU:
|
||||||
('stm32f070', self.config_stm32f070),
|
('stm32f070', self.config_stm32f070),
|
||||||
('stm32f072', self.config_stm32f0x2),
|
('stm32f072', self.config_stm32f0x2),
|
||||||
('stm32g0', self.config_stm32g0),
|
('stm32g0', self.config_stm32g0),
|
||||||
|
('stm32l4', self.config_stm32g0),
|
||||||
('stm32h7', self.config_stm32h7),
|
('stm32h7', self.config_stm32h7),
|
||||||
('', self.config_unknown)]
|
('', self.config_unknown)]
|
||||||
for name, func in cfg_funcs:
|
for name, func in cfg_funcs:
|
||||||
|
|
|
@ -68,6 +68,11 @@ The stm32g0 directory contains code from:
|
||||||
version v1.4.1 (5cb06333a6a43cefbe145f10a5aa98d3cc4cffee). Contents
|
version v1.4.1 (5cb06333a6a43cefbe145f10a5aa98d3cc4cffee). Contents
|
||||||
taken from the Drivers/CMSIS/Device/ST/STM32G0xx/ directory.
|
taken from the Drivers/CMSIS/Device/ST/STM32G0xx/ directory.
|
||||||
|
|
||||||
|
The stm32l4 directory contains code from:
|
||||||
|
https://github.com/STMicroelectronics/STM32CubeL4
|
||||||
|
version v1.17.0 (5e1553e07706491bd11f4edd304e093b6e4b83a4). Contents
|
||||||
|
taken from the Drivers/CMSIS/Device/ST/STM32L4xx/ directory.
|
||||||
|
|
||||||
The stm32h7 directory contains code from:
|
The stm32h7 directory contains code from:
|
||||||
https://github.com/STMicroelectronics/STM32CubeH7
|
https://github.com/STMicroelectronics/STM32CubeH7
|
||||||
version v1.7.0 (79196b09acfb720589f58e93ccf956401b18a191). Contents
|
version v1.7.0 (79196b09acfb720589f58e93ccf956401b18a191). Contents
|
||||||
|
|
|
@ -340,7 +340,8 @@ MCUTYPES = {
|
||||||
'same70': flash_atsam4, 'lpc176': flash_lpc176x, 'stm32f103': flash_stm32f1,
|
'same70': flash_atsam4, 'lpc176': flash_lpc176x, 'stm32f103': flash_stm32f1,
|
||||||
'stm32f4': flash_stm32f4, 'stm32f042': flash_stm32f4,
|
'stm32f4': flash_stm32f4, 'stm32f042': flash_stm32f4,
|
||||||
'stm32f072': flash_stm32f4, 'stm32g0b1': flash_stm32f4,
|
'stm32f072': flash_stm32f4, 'stm32g0b1': flash_stm32f4,
|
||||||
'stm32h7': flash_stm32f4, 'rp2040': flash_rp2040
|
'stm32h7': flash_stm32f4, 'rp2040': flash_rp2040,
|
||||||
|
'stm32l4': flash_stm32f4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,9 @@ choice
|
||||||
config MACH_STM32H750
|
config MACH_STM32H750
|
||||||
bool "STM32H750"
|
bool "STM32H750"
|
||||||
select MACH_STM32H7
|
select MACH_STM32H7
|
||||||
|
config MACH_STM32L412
|
||||||
|
bool "STM32L412"
|
||||||
|
select MACH_STM32L4
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config MACH_STM32F103x6
|
config MACH_STM32F103x6
|
||||||
|
@ -96,9 +99,11 @@ 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_STM32G0 || MACH_STM32L4
|
||||||
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
|
||||||
|
@ -132,6 +137,7 @@ config MCU
|
||||||
default "stm32g0b1xx" if MACH_STM32G0B1
|
default "stm32g0b1xx" if MACH_STM32G0B1
|
||||||
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
|
||||||
|
@ -144,13 +150,14 @@ config CLOCK_FREQ
|
||||||
default 180000000 if MACH_STM32F446
|
default 180000000 if MACH_STM32F446
|
||||||
default 64000000 if MACH_STM32G0
|
default 64000000 if MACH_STM32G0
|
||||||
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_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
|
||||||
default 0x80000 if MACH_STM32F4x5 || MACH_STM32F446
|
default 0x80000 if MACH_STM32F4x5 || MACH_STM32F446
|
||||||
default 0x20000 if MACH_STM32G0B1
|
default 0x20000 if MACH_STM32G0B1
|
||||||
|
@ -169,6 +176,7 @@ 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 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
|
||||||
|
@ -260,6 +268,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 +278,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
|
||||||
|
|
|
@ -10,6 +10,7 @@ dirs-$(CONFIG_MACH_STM32F2) += lib/stm32f2
|
||||||
dirs-$(CONFIG_MACH_STM32F4) += lib/stm32f4
|
dirs-$(CONFIG_MACH_STM32F4) += lib/stm32f4
|
||||||
dirs-$(CONFIG_MACH_STM32G0) += lib/stm32g0
|
dirs-$(CONFIG_MACH_STM32G0) += lib/stm32g0
|
||||||
dirs-$(CONFIG_MACH_STM32H7) += lib/stm32h7
|
dirs-$(CONFIG_MACH_STM32H7) += lib/stm32h7
|
||||||
|
dirs-$(CONFIG_MACH_STM32L4) += lib/stm32l4
|
||||||
|
|
||||||
MCU := $(shell echo $(CONFIG_MCU))
|
MCU := $(shell echo $(CONFIG_MCU))
|
||||||
MCU_UPPER := $(shell echo $(CONFIG_MCU) | tr a-z A-Z | tr X x)
|
MCU_UPPER := $(shell echo $(CONFIG_MCU) | tr a-z A-Z | tr X x)
|
||||||
|
@ -20,6 +21,7 @@ CFLAGS-$(CONFIG_MACH_STM32F2) += -mcpu=cortex-m3 -Ilib/stm32f2/include
|
||||||
CFLAGS-$(CONFIG_MACH_STM32F4) += -mcpu=cortex-m4 -Ilib/stm32f4/include
|
CFLAGS-$(CONFIG_MACH_STM32F4) += -mcpu=cortex-m4 -Ilib/stm32f4/include
|
||||||
CFLAGS-$(CONFIG_MACH_STM32G0) += -mcpu=cortex-m0plus -Ilib/stm32g0/include
|
CFLAGS-$(CONFIG_MACH_STM32G0) += -mcpu=cortex-m0plus -Ilib/stm32g0/include
|
||||||
CFLAGS-$(CONFIG_MACH_STM32H7) += -mcpu=cortex-m7 -Ilib/stm32h7/include
|
CFLAGS-$(CONFIG_MACH_STM32H7) += -mcpu=cortex-m7 -Ilib/stm32h7/include
|
||||||
|
CFLAGS-$(CONFIG_MACH_STM32L4) += -mcpu=cortex-m4 -Ilib/stm32l4/include
|
||||||
CFLAGS += $(CFLAGS-y) -D$(MCU_UPPER) -mthumb -Ilib/cmsis-core -Ilib/fast-hash
|
CFLAGS += $(CFLAGS-y) -D$(MCU_UPPER) -mthumb -Ilib/cmsis-core -Ilib/fast-hash
|
||||||
|
|
||||||
CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs
|
CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs
|
||||||
|
@ -48,6 +50,10 @@ src-$(CONFIG_MACH_STM32G0) += stm32/stm32f0_adc.c stm32/stm32f0_i2c.c
|
||||||
src-$(CONFIG_MACH_STM32H7) += ../lib/stm32h7/system_stm32h7xx.c
|
src-$(CONFIG_MACH_STM32H7) += ../lib/stm32h7/system_stm32h7xx.c
|
||||||
src-$(CONFIG_MACH_STM32H7) += stm32/stm32h7.c generic/armcm_timer.c
|
src-$(CONFIG_MACH_STM32H7) += stm32/stm32h7.c generic/armcm_timer.c
|
||||||
src-$(CONFIG_MACH_STM32H7) += stm32/gpioperiph.c stm32/stm32h7_adc.c
|
src-$(CONFIG_MACH_STM32H7) += stm32/gpioperiph.c stm32/stm32h7_adc.c
|
||||||
|
src-$(CONFIG_MACH_STM32L4) += ../lib/stm32l4/system_stm32l4xx.c
|
||||||
|
src-$(CONFIG_MACH_STM32L4) += stm32/stm32l4.c generic/armcm_timer.c
|
||||||
|
src-$(CONFIG_MACH_STM32L4) += stm32/gpioperiph.c
|
||||||
|
src-$(CONFIG_MACH_STM32L4) += stm32/stm32h7_adc.c stm32/stm32f0_i2c.c
|
||||||
spi-src-y := stm32/spi.c
|
spi-src-y := stm32/spi.c
|
||||||
spi-src-$(CONFIG_MACH_STM32H7) := stm32/stm32h7_spi.c
|
spi-src-$(CONFIG_MACH_STM32H7) := stm32/stm32h7_spi.c
|
||||||
src-$(CONFIG_HAVE_GPIO_SPI) += $(spi-src-y)
|
src-$(CONFIG_HAVE_GPIO_SPI) += $(spi-src-y)
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include "stm32g0xx.h"
|
#include "stm32g0xx.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
|
||||||
|
|
|
@ -79,8 +79,8 @@ spi_setup(uint32_t bus, uint8_t mode, uint32_t rate)
|
||||||
gpio_peripheral(spi_bus[bus].mosi_pin, spi_bus[bus].function, 0);
|
gpio_peripheral(spi_bus[bus].mosi_pin, spi_bus[bus].function, 0);
|
||||||
gpio_peripheral(spi_bus[bus].sck_pin, spi_bus[bus].function, 0);
|
gpio_peripheral(spi_bus[bus].sck_pin, spi_bus[bus].function, 0);
|
||||||
|
|
||||||
// Configure CR2 on stm32f0
|
// Configure CR2 on stm32 f0/g0/l4
|
||||||
#if CONFIG_MACH_STM32F0 || CONFIG_MACH_STM32G0
|
#if CONFIG_MACH_STM32F0 || CONFIG_MACH_STM32G0 || CONFIG_MACH_STM32L4
|
||||||
spi->CR2 = SPI_CR2_FRXTH | (7 << SPI_CR2_DS_Pos);
|
spi->CR2 = SPI_CR2_FRXTH | (7 << SPI_CR2_DS_Pos);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,21 @@ DECL_ENUMERATION("i2c_bus", "i2c1", 0);
|
||||||
DECL_CONSTANT_STR("BUS_PINS_i2c1", "PB6,PB7");
|
DECL_CONSTANT_STR("BUS_PINS_i2c1", "PB6,PB7");
|
||||||
DECL_ENUMERATION("i2c_bus", "i2c1a", 1);
|
DECL_ENUMERATION("i2c_bus", "i2c1a", 1);
|
||||||
DECL_CONSTANT_STR("BUS_PINS_i2c1a", "PF1,PF0");
|
DECL_CONSTANT_STR("BUS_PINS_i2c1a", "PF1,PF0");
|
||||||
#elif CONFIG_MACH_STM32G0
|
|
||||||
|
#elif CONFIG_MACH_STM32G0 || CONFIG_MACH_STM32L4
|
||||||
DECL_ENUMERATION("i2c_bus", "i2c1_PB6_PB7", 0);
|
DECL_ENUMERATION("i2c_bus", "i2c1_PB6_PB7", 0);
|
||||||
DECL_CONSTANT_STR("BUS_PINS_i2c1_PB6_PB7", "PB6,PB7");
|
DECL_CONSTANT_STR("BUS_PINS_i2c1_PB6_PB7", "PB6,PB7");
|
||||||
DECL_ENUMERATION("i2c_bus", "i2c1_PB8_PB9", 1);
|
DECL_ENUMERATION("i2c_bus", "i2c1_PB8_PB9", 1);
|
||||||
DECL_CONSTANT_STR("BUS_PINS_i2c1_PB8_PB9", "PB8,PB9");
|
DECL_CONSTANT_STR("BUS_PINS_i2c1_PB8_PB9", "PB8,PB9");
|
||||||
|
#if CONFIG_MACH_STM32G0
|
||||||
|
#define GPIO_AF_INDEX 6
|
||||||
DECL_ENUMERATION("i2c_bus", "i2c3_PB3_PB4", 2);
|
DECL_ENUMERATION("i2c_bus", "i2c3_PB3_PB4", 2);
|
||||||
DECL_CONSTANT_STR("BUS_PINS_i2c3_PB3_PB4", "PB3,PB4");
|
DECL_CONSTANT_STR("BUS_PINS_i2c3_PB3_PB4", "PB3,PB4");
|
||||||
|
#elif CONFIG_MACH_STM32L4
|
||||||
|
#define GPIO_AF_INDEX 4
|
||||||
|
DECL_ENUMERATION("i2c_bus", "i2c3_PA7_PB4", 2);
|
||||||
|
DECL_CONSTANT_STR("BUS_PINS_i2c3_PA7_PB4", "PA7,PB4");
|
||||||
|
#endif
|
||||||
DECL_ENUMERATION("i2c_bus", "i2c2_PB10_PB11", 3);
|
DECL_ENUMERATION("i2c_bus", "i2c2_PB10_PB11", 3);
|
||||||
DECL_CONSTANT_STR("BUS_PINS_i2c2_PB10_PB11", "PB10,PB11");
|
DECL_CONSTANT_STR("BUS_PINS_i2c2_PB10_PB11", "PB10,PB11");
|
||||||
DECL_ENUMERATION("i2c_bus", "i2c2_PB13_PB14", 4);
|
DECL_ENUMERATION("i2c_bus", "i2c2_PB13_PB14", 4);
|
||||||
|
@ -47,13 +55,18 @@ static const struct i2c_info i2c_bus[] = {
|
||||||
{ I2C1, GPIO('B', 6), GPIO('B', 7), GPIO_FUNCTION(1) },
|
{ I2C1, GPIO('B', 6), GPIO('B', 7), GPIO_FUNCTION(1) },
|
||||||
{ I2C1, GPIO('F', 1), GPIO('F', 0), GPIO_FUNCTION(1) },
|
{ I2C1, GPIO('F', 1), GPIO('F', 0), GPIO_FUNCTION(1) },
|
||||||
{ I2C1, GPIO('B', 8), GPIO('B', 9), GPIO_FUNCTION(1) },
|
{ I2C1, GPIO('B', 8), GPIO('B', 9), GPIO_FUNCTION(1) },
|
||||||
#elif CONFIG_MACH_STM32G0
|
|
||||||
{ I2C1, GPIO('B', 6), GPIO('B', 7), GPIO_FUNCTION(6) },
|
#elif CONFIG_MACH_STM32G0 || CONFIG_MACH_STM32L4
|
||||||
{ I2C1, GPIO('B', 8), GPIO('B', 9), GPIO_FUNCTION(6) },
|
{ I2C1, GPIO('B', 6), GPIO('B', 7), GPIO_FUNCTION(GPIO_AF_INDEX) },
|
||||||
{ I2C3, GPIO('B', 3), GPIO('B', 4), GPIO_FUNCTION(6) },
|
{ I2C1, GPIO('B', 8), GPIO('B', 9), GPIO_FUNCTION(GPIO_AF_INDEX) },
|
||||||
{ I2C2, GPIO('B', 10), GPIO('B', 11), GPIO_FUNCTION(6) },
|
#if CONFIG_MACH_STM32G0
|
||||||
{ I2C2, GPIO('B', 13), GPIO('B', 14), GPIO_FUNCTION(6) },
|
{ I2C3, GPIO('B', 3), GPIO('B', 4), GPIO_FUNCTION(GPIO_AF_INDEX) },
|
||||||
{ I2C1, GPIO('A', 9), GPIO('A', 10), GPIO_FUNCTION(6) },
|
#elif CONFIG_MACH_STM32L4
|
||||||
|
{ I2C3, GPIO('A', 7), GPIO('B', 4), GPIO_FUNCTION(GPIO_AF_INDEX) },
|
||||||
|
#endif
|
||||||
|
{ I2C2, GPIO('B', 10), GPIO('B', 11), GPIO_FUNCTION(GPIO_AF_INDEX) },
|
||||||
|
{ I2C2, GPIO('B', 13), GPIO('B', 14), GPIO_FUNCTION(GPIO_AF_INDEX) },
|
||||||
|
{ I2C1, GPIO('A', 9), GPIO('A', 10), GPIO_FUNCTION(GPIO_AF_INDEX) },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,15 +13,37 @@
|
||||||
#include "internal.h" // GPIO
|
#include "internal.h" // GPIO
|
||||||
#include "sched.h" // sched_shutdown
|
#include "sched.h" // sched_shutdown
|
||||||
|
|
||||||
|
#if CONFIG_MACH_STM32H7
|
||||||
|
#define ADCIN_BANK_SIZE (20)
|
||||||
|
#define RCC_AHBENR_ADC (RCC->AHB1ENR)
|
||||||
|
#define RCC_AHBENR_ADCEN (RCC_AHB1ENR_ADC12EN)
|
||||||
|
#define ADC_CKMODE (0b11)
|
||||||
|
#define ADC_ATICKS (0b101)
|
||||||
|
#define ADC_RES (0b110)
|
||||||
|
#define ADC_TS (ADC3_COMMON)
|
||||||
|
|
||||||
// Number of samples is 2^OVERSAMPLES_EXPONENT (exponent can be 0-10)
|
// Number of samples is 2^OVERSAMPLES_EXPONENT (exponent can be 0-10)
|
||||||
#define OVERSAMPLES_EXPONENT 3
|
#define OVERSAMPLES_EXPONENT 3
|
||||||
#define OVERSAMPLES (1 << OVERSAMPLES_EXPONENT)
|
#define OVERSAMPLES (1 << OVERSAMPLES_EXPONENT)
|
||||||
|
#define ADC_MEAS_DELAY (1 + 2.3666*OVERSAMPLES)
|
||||||
|
|
||||||
// LDORDY registers are missing from CMSIS (only available on revision V!)
|
// LDORDY registers are missing from CMSIS (only available on revision V!)
|
||||||
#define ADC_ISR_LDORDY_Pos (12U)
|
#define ADC_ISR_LDORDY_Pos (12U)
|
||||||
#define ADC_ISR_LDORDY_Msk (0x1UL << ADC_ISR_LDORDY_Pos)
|
#define ADC_ISR_LDORDY_Msk (0x1UL << ADC_ISR_LDORDY_Pos)
|
||||||
#define ADC_ISR_LDORDY ADC_ISR_LDORDY_Msk
|
#define ADC_ISR_LDORDY ADC_ISR_LDORDY_Msk
|
||||||
|
|
||||||
|
#else // stm32l4
|
||||||
|
#define RCC_AHBENR_ADC (RCC->AHB2ENR)
|
||||||
|
#define RCC_AHBENR_ADCEN (RCC_AHB2ENR_ADCEN)
|
||||||
|
#define ADC_CKMODE (0)
|
||||||
|
#define ADC_ATICKS (0b100)
|
||||||
|
#define ADC_RES (0b00)
|
||||||
|
#define ADC_TS (ADC12_COMMON)
|
||||||
|
|
||||||
|
#define OVERSAMPLES (0)
|
||||||
|
#define ADC_MEAS_DELAY (10)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ADC_TEMPERATURE_PIN 0xfe
|
#define ADC_TEMPERATURE_PIN 0xfe
|
||||||
DECL_ENUMERATION("pin", "ADC_TEMPERATURE", ADC_TEMPERATURE_PIN);
|
DECL_ENUMERATION("pin", "ADC_TEMPERATURE", ADC_TEMPERATURE_PIN);
|
||||||
|
|
||||||
|
@ -30,6 +52,7 @@ DECL_CONSTANT("ADC_MAX", 4095);
|
||||||
// GPIOs like A0_C are not covered!
|
// GPIOs like A0_C are not covered!
|
||||||
// This always gives the pin connected to the positive channel
|
// This always gives the pin connected to the positive channel
|
||||||
static const uint8_t adc_pins[] = {
|
static const uint8_t adc_pins[] = {
|
||||||
|
#if CONFIG_MACH_STM32H7
|
||||||
// ADC1
|
// ADC1
|
||||||
0, // PA0_C ADC12_INP0
|
0, // PA0_C ADC12_INP0
|
||||||
0, // PA1_C ADC12_INP1
|
0, // PA1_C ADC12_INP1
|
||||||
|
@ -93,6 +116,27 @@ static const uint8_t adc_pins[] = {
|
||||||
0, // Vbat/4
|
0, // Vbat/4
|
||||||
ADC_TEMPERATURE_PIN,// VSENSE
|
ADC_TEMPERATURE_PIN,// VSENSE
|
||||||
0, // VREFINT
|
0, // VREFINT
|
||||||
|
#else // stm32l4
|
||||||
|
0, // vref
|
||||||
|
GPIO('C', 0), // ADC12_IN1 .. 16
|
||||||
|
GPIO('C', 1),
|
||||||
|
GPIO('C', 2),
|
||||||
|
GPIO('C', 3),
|
||||||
|
GPIO('A', 0),
|
||||||
|
GPIO('A', 1),
|
||||||
|
GPIO('A', 2),
|
||||||
|
GPIO('A', 3),
|
||||||
|
GPIO('A', 4),
|
||||||
|
GPIO('A', 5),
|
||||||
|
GPIO('A', 6),
|
||||||
|
GPIO('A', 7),
|
||||||
|
GPIO('C', 4),
|
||||||
|
GPIO('C', 5),
|
||||||
|
GPIO('B', 0),
|
||||||
|
GPIO('B', 1),
|
||||||
|
ADC_TEMPERATURE_PIN, // temp
|
||||||
|
0, // vbat
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,25 +159,29 @@ gpio_adc_setup(uint32_t pin)
|
||||||
// (SYSCLK 480Mhz) /HPRE(2) /CKMODE divider(4) /additional divider(2)
|
// (SYSCLK 480Mhz) /HPRE(2) /CKMODE divider(4) /additional divider(2)
|
||||||
// (ADC clock 30Mhz)
|
// (ADC clock 30Mhz)
|
||||||
ADC_TypeDef *adc;
|
ADC_TypeDef *adc;
|
||||||
if (chan >= 40){
|
#ifdef ADC3
|
||||||
|
if (chan >= 2 * ADCIN_BANK_SIZE){
|
||||||
adc = ADC3;
|
adc = ADC3;
|
||||||
if (!is_enabled_pclock(ADC3_BASE)) {
|
if (!is_enabled_pclock(ADC3_BASE)) {
|
||||||
enable_pclock(ADC3_BASE);
|
enable_pclock(ADC3_BASE);
|
||||||
}
|
}
|
||||||
MODIFY_REG(ADC3_COMMON->CCR, ADC_CCR_CKMODE_Msk,
|
MODIFY_REG(ADC3_COMMON->CCR, ADC_CCR_CKMODE_Msk,
|
||||||
0b11 << ADC_CCR_CKMODE_Pos);
|
ADC_CKMODE << ADC_CCR_CKMODE_Pos);
|
||||||
} else if (chan >= 20){
|
chan -= 2 * ADCIN_BANK_SIZE;
|
||||||
|
} else if (chan >= ADCIN_BANK_SIZE){
|
||||||
adc = ADC2;
|
adc = ADC2;
|
||||||
RCC->AHB1ENR |= RCC_AHB1ENR_ADC12EN;
|
RCC_AHBENR_ADC |= RCC_AHBENR_ADCEN;
|
||||||
MODIFY_REG(ADC12_COMMON->CCR, ADC_CCR_CKMODE_Msk,
|
MODIFY_REG(ADC12_COMMON->CCR, ADC_CCR_CKMODE_Msk,
|
||||||
0b11 << ADC_CCR_CKMODE_Pos);
|
ADC_CKMODE << ADC_CCR_CKMODE_Pos);
|
||||||
} else{
|
chan -= ADCIN_BANK_SIZE;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
adc = ADC1;
|
adc = ADC1;
|
||||||
RCC->AHB1ENR |= RCC_AHB1ENR_ADC12EN;
|
RCC_AHBENR_ADC |= RCC_AHBENR_ADCEN;
|
||||||
MODIFY_REG(ADC12_COMMON->CCR, ADC_CCR_CKMODE_Msk,
|
MODIFY_REG(ADC12_COMMON->CCR, ADC_CCR_CKMODE_Msk,
|
||||||
0b11 << ADC_CCR_CKMODE_Pos);
|
ADC_CKMODE << ADC_CCR_CKMODE_Pos);
|
||||||
}
|
}
|
||||||
chan %= 20;
|
|
||||||
|
|
||||||
// Enable the ADC
|
// Enable the ADC
|
||||||
if (!(adc->CR & ADC_CR_ADEN)){
|
if (!(adc->CR & ADC_CR_ADEN)){
|
||||||
|
@ -142,16 +190,27 @@ gpio_adc_setup(uint32_t pin)
|
||||||
MODIFY_REG(adc->CR, ADC_CR_DEEPPWD_Msk, 0);
|
MODIFY_REG(adc->CR, ADC_CR_DEEPPWD_Msk, 0);
|
||||||
// Switch on voltage regulator
|
// Switch on voltage regulator
|
||||||
adc->CR |= ADC_CR_ADVREGEN;
|
adc->CR |= ADC_CR_ADVREGEN;
|
||||||
|
#ifdef ADC_ISR_LDORDY
|
||||||
while(!(adc->ISR & ADC_ISR_LDORDY))
|
while(!(adc->ISR & ADC_ISR_LDORDY))
|
||||||
;
|
;
|
||||||
|
#else // stm32l4 lacks ldordy, delay to spec instead
|
||||||
|
uint32_t end = timer_read_time() + timer_from_us(20);
|
||||||
|
while (timer_is_before(timer_read_time(), end))
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set Boost mode for 25Mhz < ADC clock <= 50Mhz
|
// Set Boost mode for 25Mhz < ADC clock <= 50Mhz
|
||||||
|
#ifdef ADC_CR_BOOST
|
||||||
MODIFY_REG(adc->CR, ADC_CR_BOOST_Msk, 0b11 << ADC_CR_BOOST_Pos);
|
MODIFY_REG(adc->CR, ADC_CR_BOOST_Msk, 0b11 << ADC_CR_BOOST_Pos);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Calibration
|
// Calibration
|
||||||
// Set calibration mode to Single ended (not differential)
|
// Set calibration mode to Single ended (not differential)
|
||||||
MODIFY_REG(adc->CR, ADC_CR_ADCALDIF_Msk, 0);
|
MODIFY_REG(adc->CR, ADC_CR_ADCALDIF_Msk, 0);
|
||||||
// Enable linearity calibration
|
// Enable linearity calibration
|
||||||
|
#ifdef ADC_CR_ADCALLIN
|
||||||
MODIFY_REG(adc->CR, ADC_CR_ADCALLIN_Msk, ADC_CR_ADCALLIN);
|
MODIFY_REG(adc->CR, ADC_CR_ADCALLIN_Msk, ADC_CR_ADCALLIN);
|
||||||
|
#endif
|
||||||
// Start the calibration
|
// Start the calibration
|
||||||
MODIFY_REG(adc->CR, ADC_CR_ADCAL_Msk, ADC_CR_ADCAL);
|
MODIFY_REG(adc->CR, ADC_CR_ADCAL_Msk, ADC_CR_ADCAL);
|
||||||
while(adc->CR & ADC_CR_ADCAL)
|
while(adc->CR & ADC_CR_ADCAL)
|
||||||
|
@ -160,13 +219,14 @@ gpio_adc_setup(uint32_t pin)
|
||||||
// Enable ADC
|
// Enable ADC
|
||||||
// "Clear the ADRDY bit in the ADC_ISR register by writing ‘1’"
|
// "Clear the ADRDY bit in the ADC_ISR register by writing ‘1’"
|
||||||
adc->ISR |= ADC_ISR_ADRDY;
|
adc->ISR |= ADC_ISR_ADRDY;
|
||||||
|
adc->ISR; // Dummy read to make sure write is flushed
|
||||||
adc->CR |= ADC_CR_ADEN;
|
adc->CR |= ADC_CR_ADEN;
|
||||||
while(!(adc->ISR & ADC_ISR_ADRDY))
|
while(!(adc->ISR & ADC_ISR_ADRDY))
|
||||||
;
|
;
|
||||||
|
|
||||||
// Set 64.5 ADC clock cycles sample time for every channel
|
// Set 64.5 ADC clock cycles sample time for every channel
|
||||||
// (Reference manual pg.940)
|
// (Reference manual pg.940)
|
||||||
uint32_t aticks = 0b101;
|
uint32_t aticks = ADC_ATICKS;
|
||||||
// Channel 0-9
|
// Channel 0-9
|
||||||
adc->SMPR1 = (aticks | (aticks << 3) | (aticks << 6)
|
adc->SMPR1 = (aticks | (aticks << 3) | (aticks << 6)
|
||||||
| (aticks << 9) | (aticks << 12) | (aticks << 15)
|
| (aticks << 9) | (aticks << 12) | (aticks << 15)
|
||||||
|
@ -180,23 +240,29 @@ gpio_adc_setup(uint32_t pin)
|
||||||
// Disable Continuous Mode
|
// Disable Continuous Mode
|
||||||
MODIFY_REG(adc->CFGR, ADC_CFGR_CONT_Msk, 0);
|
MODIFY_REG(adc->CFGR, ADC_CFGR_CONT_Msk, 0);
|
||||||
// Set to 12 bit
|
// Set to 12 bit
|
||||||
MODIFY_REG(adc->CFGR, ADC_CFGR_RES_Msk, 0b110 << ADC_CFGR_RES_Pos);
|
MODIFY_REG(adc->CFGR, ADC_CFGR_RES_Msk, ADC_RES << ADC_CFGR_RES_Pos);
|
||||||
|
#if CONFIG_MACH_STM32H7
|
||||||
// Set hardware oversampling
|
// Set hardware oversampling
|
||||||
MODIFY_REG(adc->CFGR2, ADC_CFGR2_ROVSE_Msk, ADC_CFGR2_ROVSE);
|
MODIFY_REG(adc->CFGR2, ADC_CFGR2_ROVSE_Msk, ADC_CFGR2_ROVSE);
|
||||||
MODIFY_REG(adc->CFGR2, ADC_CFGR2_OVSR_Msk,
|
MODIFY_REG(adc->CFGR2, ADC_CFGR2_OVSR_Msk,
|
||||||
(OVERSAMPLES - 1) << ADC_CFGR2_OVSR_Pos);
|
(OVERSAMPLES - 1) << ADC_CFGR2_OVSR_Pos);
|
||||||
MODIFY_REG(adc->CFGR2, ADC_CFGR2_OVSS_Msk,
|
MODIFY_REG(adc->CFGR2, ADC_CFGR2_OVSS_Msk,
|
||||||
OVERSAMPLES_EXPONENT << ADC_CFGR2_OVSS_Pos);
|
OVERSAMPLES_EXPONENT << ADC_CFGR2_OVSS_Pos);
|
||||||
|
#else // stm32l4
|
||||||
|
adc->CFGR |= ADC_CFGR_JQDIS | ADC_CFGR_OVRMOD;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pin == ADC_TEMPERATURE_PIN) {
|
if (pin == ADC_TEMPERATURE_PIN) {
|
||||||
ADC3_COMMON->CCR |= ADC_CCR_TSEN;
|
ADC_TS->CCR |= ADC_CCR_TSEN;
|
||||||
} else {
|
} else {
|
||||||
gpio_peripheral(pin, GPIO_ANALOG, 0);
|
gpio_peripheral(pin, GPIO_ANALOG, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preselect (connect) channel
|
// Preselect (connect) channel
|
||||||
|
#ifdef ADC_PCSEL_PCSEL
|
||||||
adc->PCSEL |= (1 << chan);
|
adc->PCSEL |= (1 << chan);
|
||||||
|
#endif
|
||||||
return (struct gpio_adc){ .adc = adc, .chan = chan };
|
return (struct gpio_adc){ .adc = adc, .chan = chan };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,16 +277,16 @@ gpio_adc_sample(struct gpio_adc g)
|
||||||
// EOC flag is cleared by hardware when reading DR
|
// EOC flag is cleared by hardware when reading DR
|
||||||
// the channel condition only works if this ist the only channel
|
// the channel condition only works if this ist the only channel
|
||||||
// on the sequence and length set to 1 (ADC_SQR1_L = 0000)
|
// on the sequence and length set to 1 (ADC_SQR1_L = 0000)
|
||||||
if (adc->ISR & ADC_ISR_EOC && adc->SQR1 == (g.chan << 6))
|
if (adc->ISR & ADC_ISR_EOC && adc->SQR1 == (g.chan << ADC_SQR1_SQ1_Pos))
|
||||||
return 0;
|
return 0;
|
||||||
// Conversion started but not ready or wrong channel
|
// Conversion started but not ready or wrong channel
|
||||||
if (adc->CR & ADC_CR_ADSTART)
|
if (adc->CR & ADC_CR_ADSTART)
|
||||||
return timer_from_us(10);
|
return timer_from_us(10);
|
||||||
// Start sample
|
// Start sample
|
||||||
adc->SQR1 = (g.chan << 6);
|
adc->SQR1 = (g.chan << ADC_SQR1_SQ1_Pos);
|
||||||
adc->CR |= ADC_CR_ADSTART;
|
adc->CR |= ADC_CR_ADSTART;
|
||||||
// Should take 2.3666us, add 1us for clock synchronisation etc.
|
// Should take 2.3666us, add 1us for clock synchronisation etc.
|
||||||
return timer_from_us(1 + 2.3666*OVERSAMPLES);
|
return timer_from_us(ADC_MEAS_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a value; use only after gpio_adc_sample() returns zero
|
// Read a value; use only after gpio_adc_sample() returns zero
|
||||||
|
@ -239,7 +305,7 @@ gpio_adc_cancel_sample(struct gpio_adc g)
|
||||||
irqstatus_t flag = irq_save();
|
irqstatus_t flag = irq_save();
|
||||||
// ADSTART is not as long true as SR_STRT on stm32f4
|
// ADSTART is not as long true as SR_STRT on stm32f4
|
||||||
if ((adc->CR & ADC_CR_ADSTART || adc->ISR & ADC_ISR_EOC)
|
if ((adc->CR & ADC_CR_ADSTART || adc->ISR & ADC_ISR_EOC)
|
||||||
&& adc->SQR1 == (g.chan << 6))
|
&& adc->SQR1 == (g.chan << ADC_SQR1_SQ1_Pos))
|
||||||
gpio_adc_read(g);
|
gpio_adc_read(g);
|
||||||
irq_restore(flag);
|
irq_restore(flag);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
// Code to setup clocks and gpio on stm32l4
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 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/irq.h" // irq_disable
|
||||||
|
#include "board/usb_cdc.h" // usb_request_bootloader
|
||||||
|
#include "command.h" // DECL_CONSTANT_STR
|
||||||
|
#include "internal.h" // enable_pclock
|
||||||
|
#include "sched.h" // sched_main
|
||||||
|
|
||||||
|
#define FREQ_PERIPH_DIV 1
|
||||||
|
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / FREQ_PERIPH_DIV)
|
||||||
|
|
||||||
|
// Map a peripheral address to its enable bits
|
||||||
|
struct cline
|
||||||
|
lookup_clock_line(uint32_t periph_base)
|
||||||
|
{
|
||||||
|
if (periph_base < APB2PERIPH_BASE) {
|
||||||
|
uint32_t pos = (periph_base - APB1PERIPH_BASE) / 0x400;
|
||||||
|
if (pos < 32) {
|
||||||
|
return (struct cline){.en = &RCC->APB1ENR1,
|
||||||
|
.rst = &RCC->APB1RSTR1,
|
||||||
|
.bit = 1 << pos};
|
||||||
|
} else {
|
||||||
|
return (struct cline){.en = &RCC->APB1ENR2,
|
||||||
|
.rst = &RCC->APB1RSTR2,
|
||||||
|
.bit = 1 << (pos - 32)};
|
||||||
|
}
|
||||||
|
} else if (periph_base < AHB1PERIPH_BASE) {
|
||||||
|
uint32_t pos = (periph_base - APB2PERIPH_BASE) / 0x400;
|
||||||
|
return (struct cline){.en = &RCC->APB2ENR,
|
||||||
|
.rst = &RCC->APB2RSTR,
|
||||||
|
.bit = 1 << pos};
|
||||||
|
|
||||||
|
} else if (periph_base < AHB2PERIPH_BASE) {
|
||||||
|
uint32_t pos = (periph_base - AHB1PERIPH_BASE) / 0x400;
|
||||||
|
return (struct cline){.en = &RCC->AHB1ENR,
|
||||||
|
.rst = &RCC->AHB1RSTR,
|
||||||
|
.bit = 1 << pos};
|
||||||
|
|
||||||
|
} else if (periph_base == ADC1_BASE) {
|
||||||
|
return (struct cline){.en = &RCC->AHB2ENR,
|
||||||
|
.rst = &RCC->AHB2RSTR,
|
||||||
|
.bit = RCC_AHB2ENR_ADCEN};
|
||||||
|
}
|
||||||
|
return (struct cline){.en = &RCC->AHB2ENR,
|
||||||
|
.rst = &RCC->AHB2RSTR,
|
||||||
|
.bit = 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the frequency of the given peripheral clock
|
||||||
|
uint32_t
|
||||||
|
get_pclock_frequency(uint32_t periph_base)
|
||||||
|
{
|
||||||
|
return FREQ_PERIPH;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable a GPIO peripheral clock
|
||||||
|
void
|
||||||
|
gpio_clock_enable(GPIO_TypeDef *regs)
|
||||||
|
{
|
||||||
|
uint32_t rcc_pos = ((uint32_t)regs - GPIOA_BASE) / 0x400;
|
||||||
|
RCC->AHB2ENR |= 1 << rcc_pos;
|
||||||
|
RCC->AHB2ENR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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();
|
||||||
|
// System DFU Bootloader
|
||||||
|
*(uint64_t*)USB_BOOT_FLAG_ADDR = USB_BOOT_FLAG;
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bootloader_request(void)
|
||||||
|
{
|
||||||
|
usb_request_bootloader();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !CONFIG_STM32_CLOCK_REF_INTERNAL
|
||||||
|
DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PC14,PC15");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
enable_clock_stm32l4(void)
|
||||||
|
{
|
||||||
|
uint32_t pll_base = 4000000, pll_freq = CONFIG_CLOCK_FREQ * 2, pllcfgr;
|
||||||
|
if (!CONFIG_STM32_CLOCK_REF_INTERNAL) {
|
||||||
|
// Configure 80Mhz PLL from external crystal (HSE)
|
||||||
|
uint32_t div = CONFIG_CLOCK_REF_FREQ / pll_base - 1;
|
||||||
|
RCC->CR |= RCC_CR_HSEON;
|
||||||
|
while (!(RCC->CR & RCC_CR_HSERDY))
|
||||||
|
;
|
||||||
|
pllcfgr = RCC_PLLCFGR_PLLSRC_HSE | (div << RCC_PLLCFGR_PLLM_Pos);
|
||||||
|
} else {
|
||||||
|
// Configure 80Mhz PLL from internal 16Mhz oscillator (HSI)
|
||||||
|
uint32_t div = 16000000 / pll_base - 1;
|
||||||
|
pllcfgr = RCC_PLLCFGR_PLLSRC_HSI | (div << RCC_PLLCFGR_PLLM_Pos);
|
||||||
|
RCC->CR |= RCC_CR_HSION;
|
||||||
|
while (!(RCC->CR & RCC_CR_HSIRDY))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
RCC->PLLCFGR = (pllcfgr | ((pll_freq/pll_base) << RCC_PLLCFGR_PLLN_Pos)
|
||||||
|
| (0 << RCC_PLLCFGR_PLLR_Pos));
|
||||||
|
RCC->CR |= RCC_CR_PLLON;
|
||||||
|
|
||||||
|
// Enable 48Mhz USB clock using clock recovery
|
||||||
|
if (CONFIG_USBSERIAL) {
|
||||||
|
RCC->CRRCR |= RCC_CRRCR_HSI48ON;
|
||||||
|
while (!(RCC->CRRCR & RCC_CRRCR_HSI48RDY))
|
||||||
|
;
|
||||||
|
enable_pclock(CRS_BASE);
|
||||||
|
CRS->CR |= CRS_CR_AUTOTRIMEN | CRS_CR_CEN;
|
||||||
|
enable_pclock(PWR_BASE);
|
||||||
|
PWR->CR2 |= PWR_CR2_USV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main clock setup called at chip startup
|
||||||
|
static void
|
||||||
|
clock_setup(void)
|
||||||
|
{
|
||||||
|
enable_clock_stm32l4();
|
||||||
|
|
||||||
|
// Set flash latency
|
||||||
|
uint32_t latency = ((CONFIG_CLOCK_FREQ>64000000) ? FLASH_ACR_LATENCY_4WS :
|
||||||
|
((CONFIG_CLOCK_FREQ>48000000) ? FLASH_ACR_LATENCY_3WS :
|
||||||
|
((CONFIG_CLOCK_FREQ>32000000) ? FLASH_ACR_LATENCY_2WS :
|
||||||
|
((CONFIG_CLOCK_FREQ>16000000) ? FLASH_ACR_LATENCY_1WS :
|
||||||
|
FLASH_ACR_LATENCY_0WS))));
|
||||||
|
FLASH->ACR = (latency | FLASH_ACR_ICEN | FLASH_ACR_DCEN
|
||||||
|
| FLASH_ACR_PRFTEN);
|
||||||
|
|
||||||
|
// Wait for PLL lock
|
||||||
|
while (!(RCC->CR & RCC_CR_PLLRDY))
|
||||||
|
;
|
||||||
|
|
||||||
|
RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN;
|
||||||
|
|
||||||
|
// Switch system clock to PLL
|
||||||
|
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE1_DIV1 | RCC_CFGR_PPRE2_DIV1
|
||||||
|
| RCC_CFGR_SW_PLL;
|
||||||
|
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main entry point - called from armcm_boot.c:ResetHandler()
|
||||||
|
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
|
||||||
|
SystemInit();
|
||||||
|
SCB->VTOR = (uint32_t)VectorTable;
|
||||||
|
|
||||||
|
clock_setup();
|
||||||
|
|
||||||
|
sched_main();
|
||||||
|
}
|
|
@ -20,7 +20,7 @@
|
||||||
typedef volatile uint32_t epmword_t;
|
typedef volatile uint32_t epmword_t;
|
||||||
#define WSIZE 2
|
#define WSIZE 2
|
||||||
#define USBx_IRQn USB_LP_IRQn
|
#define USBx_IRQn USB_LP_IRQn
|
||||||
#elif CONFIG_MACH_STM32F0
|
#elif CONFIG_MACH_STM32F0 || CONFIG_MACH_STM32L4
|
||||||
// Transfer memory is accessed with 16bits and contains 16bits of data
|
// Transfer memory is accessed with 16bits and contains 16bits of data
|
||||||
typedef volatile uint16_t epmword_t;
|
typedef volatile uint16_t epmword_t;
|
||||||
#define WSIZE 2
|
#define WSIZE 2
|
||||||
|
|
Loading…
Reference in New Issue