aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/stm32/Kconfig23
-rw-r--r--src/stm32/Makefile7
-rw-r--r--src/stm32/fdcan.c10
-rw-r--r--src/stm32/internal.h2
-rw-r--r--src/stm32/spi.c18
-rw-r--r--src/stm32/stm32f0_i2c.c27
-rw-r--r--src/stm32/stm32f0_serial.c21
-rw-r--r--src/stm32/stm32g4.c168
-rw-r--r--src/stm32/stm32h7_adc.c59
-rw-r--r--src/stm32/usbfs.c2
10 files changed, 318 insertions, 19 deletions
diff --git a/src/stm32/Kconfig b/src/stm32/Kconfig
index 9cdb3c31..2a251918 100644
--- a/src/stm32/Kconfig
+++ b/src/stm32/Kconfig
@@ -68,6 +68,9 @@ choice
config MACH_STM32G0B1
bool "STM32G0B1"
select MACH_STM32G0
+ config MACH_STM32G431
+ bool "STM32G431"
+ select MACH_STM32G4
config MACH_STM32H743
bool "STM32H743"
select MACH_STM32H7
@@ -93,6 +96,8 @@ config MACH_STM32F4
bool
config MACH_STM32G0
bool
+config MACH_STM32G4
+ bool
config MACH_STM32H7
bool
config MACH_STM32F0x2 # F042, F072 series
@@ -103,7 +108,7 @@ config MACH_STM32L4
bool
config HAVE_STM32_USBFS
bool
- default y if MACH_STM32F0x2 || MACH_STM32G0 || MACH_STM32L4
+ default y if MACH_STM32F0x2 || MACH_STM32G0 || MACH_STM32L4 || MACH_STM32G4
default y if (MACH_STM32F103 || MACH_STM32F070) && !STM32_CLOCK_REF_INTERNAL
config HAVE_STM32_USBOTG
bool
@@ -113,7 +118,7 @@ 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 || MACH_STM32H7
+ default y if MACH_STM32G0 || MACH_STM32H7 || MACH_STM32G4
config HAVE_STM32_USBCANBUS
bool
depends on HAVE_STM32_USBFS || HAVE_STM32_USBOTG
@@ -135,6 +140,7 @@ config MCU
default "stm32f429xx" if MACH_STM32F429
default "stm32f446xx" if MACH_STM32F446
default "stm32g0b1xx" if MACH_STM32G0B1
+ default "stm32g431xx" if MACH_STM32G431
default "stm32h743xx" if MACH_STM32H743
default "stm32h750xx" if MACH_STM32H750
default "stm32l412xx" if MACH_STM32L412
@@ -149,6 +155,7 @@ 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
default 80000000 if MACH_STM32L412
@@ -160,7 +167,7 @@ config FLASH_SIZE
default 0x10000 if MACH_STM32F103 || MACH_STM32L412 # Flash size of stm32f103x8 (64KiB)
default 0x40000 if MACH_STM32F2 || MACH_STM32F401
default 0x80000 if MACH_STM32F4x5 || MACH_STM32F446
- default 0x20000 if MACH_STM32G0B1
+ default 0x20000 if MACH_STM32G0B1 || MACH_STM32G431
default 0x20000 if MACH_STM32H750
default 0x200000 if MACH_STM32H743
@@ -179,6 +186,7 @@ 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
@@ -322,7 +330,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
@@ -347,6 +358,10 @@ choice
bool "CAN bus (on PA9/PA10)" if LOW_LEVEL_OPTIONS
depends on HAVE_STM32_CANBUS && MACH_STM32F042
select CANSERIAL
+ 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
diff --git a/src/stm32/Makefile b/src/stm32/Makefile
index 8514a8df..9642eabd 100644
--- a/src/stm32/Makefile
+++ b/src/stm32/Makefile
@@ -9,6 +9,7 @@ dirs-$(CONFIG_MACH_STM32F1) += lib/stm32f1
dirs-$(CONFIG_MACH_STM32F2) += lib/stm32f2
dirs-$(CONFIG_MACH_STM32F4) += lib/stm32f4
dirs-$(CONFIG_MACH_STM32G0) += lib/stm32g0
+dirs-$(CONFIG_MACH_STM32G4) += lib/stm32g4
dirs-$(CONFIG_MACH_STM32H7) += lib/stm32h7
dirs-$(CONFIG_MACH_STM32L4) += lib/stm32l4
@@ -20,6 +21,7 @@ CFLAGS-$(CONFIG_MACH_STM32F1) += -mcpu=cortex-m3 -Ilib/stm32f1/include
CFLAGS-$(CONFIG_MACH_STM32F2) += -mcpu=cortex-m3 -Ilib/stm32f2/include
CFLAGS-$(CONFIG_MACH_STM32F4) += -mcpu=cortex-m4 -Ilib/stm32f4/include
CFLAGS-$(CONFIG_MACH_STM32G0) += -mcpu=cortex-m0plus -Ilib/stm32g0/include
+CFLAGS-$(CONFIG_MACH_STM32G4) += -mcpu=cortex-m4 -Ilib/stm32g4/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
@@ -47,6 +49,10 @@ src-$(CONFIG_MACH_STM32F4) += stm32/gpioperiph.c stm32/adc.c stm32/i2c.c
src-$(CONFIG_MACH_STM32G0) += generic/timer_irq.c stm32/stm32f0_timer.c
src-$(CONFIG_MACH_STM32G0) += stm32/stm32g0.c stm32/gpioperiph.c
src-$(CONFIG_MACH_STM32G0) += stm32/stm32f0_adc.c stm32/stm32f0_i2c.c
+src-$(CONFIG_MACH_STM32G4) += ../lib/stm32g4/system_stm32g4xx.c
+src-$(CONFIG_MACH_STM32G4) += stm32/stm32g4.c generic/armcm_timer.c
+src-$(CONFIG_MACH_STM32G4) += stm32/gpioperiph.c stm32/stm32h7_adc.c
+src-$(CONFIG_MACH_STM32G4) += stm32/stm32f0_i2c.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/gpioperiph.c stm32/stm32h7_adc.c
@@ -63,6 +69,7 @@ src-$(CONFIG_USBSERIAL) += $(usb-src-y) stm32/chipid.c generic/usb_cdc.c
serial-src-y := stm32/serial.c
serial-src-$(CONFIG_MACH_STM32F0) := stm32/stm32f0_serial.c
serial-src-$(CONFIG_MACH_STM32G0) := stm32/stm32f0_serial.c
+serial-src-$(CONFIG_MACH_STM32G4) := stm32/stm32f0_serial.c
serial-src-$(CONFIG_MACH_STM32H7) := stm32/stm32f0_serial.c
src-$(CONFIG_SERIAL) += $(serial-src-y) generic/serial_irq.c
canbus-src-y := generic/canserial.c ../lib/fast-hash/fasthash.c
diff --git a/src/stm32/fdcan.c b/src/stm32/fdcan.c
index 7b81bb6f..9017ef85 100644
--- a/src/stm32/fdcan.c
+++ b/src/stm32/fdcan.c
@@ -22,6 +22,10 @@
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PA11,PA12");
#define GPIO_Rx GPIO('A', 11)
#define GPIO_Tx GPIO('A', 12)
+#elif CONFIG_STM32_CANBUS_PA11_PB9
+ DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PA11,PB9");
+ #define GPIO_Rx GPIO('A', 11)
+ #define GPIO_Tx GPIO('B', 9)
#elif CONFIG_STM32_CANBUS_PB8_PB9
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB8,PB9");
#define GPIO_Rx GPIO('B', 8)
@@ -55,7 +59,7 @@
#if CONFIG_MACH_STM32G0
#define CAN_IT0_IRQn TIM16_FDCAN_IT0_IRQn
#define CAN_FUNCTION GPIO_FUNCTION(3) // Alternative function mapping number
-#elif CONFIG_MACH_STM32H7
+#elif CONFIG_MACH_STM32H7 || CONFIG_MACH_STM32G4
#define CAN_IT0_IRQn FDCAN1_IT0_IRQn
#define CAN_FUNCTION GPIO_FUNCTION(9) // Alternative function mapping number
#endif
@@ -152,7 +156,7 @@ canbus_set_filter(uint32_t id)
#if CONFIG_MACH_STM32G0
SOC_CAN->RXGFC = ((id ? 3 : 1) << FDCAN_RXGFC_LSS_Pos
| 0x02 << FDCAN_RXGFC_ANFS_Pos);
-#elif CONFIG_MACH_STM32H7
+#elif CONFIG_MACH_STM32H7 || CONFIG_MAC_STM32G4
uint32_t flssa = (uint32_t)MSG_RAM.FLS - SRAMCAN_BASE;
SOC_CAN->SIDFC = flssa | ((id ? 3 : 1) << FDCAN_SIDFC_LSS_Pos);
SOC_CAN->GFC = 0x02 << FDCAN_GFC_ANFS_Pos;
@@ -280,7 +284,7 @@ can_init(void)
SOC_CAN->NBTP = btr;
-#if CONFIG_MACH_STM32H7
+#if CONFIG_MACH_STM32H7 || CONFIG_MAC_STM32G4
/* Setup message RAM addresses */
uint32_t f0sa = (uint32_t)MSG_RAM.RXF0 - SRAMCAN_BASE;
SOC_CAN->RXF0C = f0sa | (ARRAY_SIZE(MSG_RAM.RXF0) << FDCAN_RXF0C_F0S_Pos);
diff --git a/src/stm32/internal.h b/src/stm32/internal.h
index 38d005ae..2ba7abe2 100644
--- a/src/stm32/internal.h
+++ b/src/stm32/internal.h
@@ -14,6 +14,8 @@
#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
diff --git a/src/stm32/spi.c b/src/stm32/spi.c
index 52ec69e1..17a84232 100644
--- a/src/stm32/spi.c
+++ b/src/stm32/spi.c
@@ -21,14 +21,17 @@ DECL_ENUMERATION("spi_bus", "spi1", 1);
DECL_CONSTANT_STR("BUS_PINS_spi1", "PA6,PA7,PA5");
DECL_ENUMERATION("spi_bus", "spi1a", 2);
DECL_CONSTANT_STR("BUS_PINS_spi1a", "PB4,PB5,PB3");
-#if !CONFIG_MACH_STM32F1
+#if CONFIG_MACH_STM32G4
+ DECL_ENUMERATION("spi_bus", "spi2_PA10_PA11_PF1", 3);
+ DECL_CONSTANT_STR("BUS_PINS_spi2_PA10_PA11_PF1", "PA10,PA11,PF1");
+#elif !CONFIG_MACH_STM32F1
DECL_ENUMERATION("spi_bus", "spi2a", 3);
DECL_CONSTANT_STR("BUS_PINS_spi2a", "PC2,PC3,PB10");
#endif
#ifdef SPI3
DECL_ENUMERATION("spi_bus", "spi3", 4);
DECL_CONSTANT_STR("BUS_PINS_spi3", "PB4,PB5,PB3");
- #if CONFIG_MACH_STM32F4
+ #if CONFIG_MACH_STM32F4 || CONFIG_MACH_STM32G4
DECL_ENUMERATION("spi_bus", "spi3a", 5);
DECL_CONSTANT_STR("BUS_PINS_spi3a", "PC11,PC12,PC10");
#ifdef SPI4
@@ -51,10 +54,14 @@ static const struct spi_info spi_bus[] = {
{ SPI2, GPIO('B', 14), GPIO('B', 15), GPIO('B', 13), SPI_FUNCTION },
{ SPI1, GPIO('A', 6), GPIO('A', 7), GPIO('A', 5), SPI_FUNCTION },
{ SPI1, GPIO('B', 4), GPIO('B', 5), GPIO('B', 3), SPI_FUNCTION },
+#if CONFIG_MACH_STM32G4
+ { SPI2, GPIO('A', 10), GPIO('A', 11), GPIO('F', 1), SPI_FUNCTION },
+#else
{ SPI2, GPIO('C', 2), GPIO('C', 3), GPIO('B', 10), SPI_FUNCTION },
+#endif
#ifdef SPI3
{ SPI3, GPIO('B', 4), GPIO('B', 5), GPIO('B', 3), GPIO_FUNCTION(6) },
- #if CONFIG_MACH_STM32F4
+ #if CONFIG_MACH_STM32F4 || CONFIG_MACH_STM32G4
{ SPI3, GPIO('C', 11), GPIO('C', 12), GPIO('C', 10), GPIO_FUNCTION(6) },
#ifdef SPI4
{ SPI4, GPIO('E', 13), GPIO('E', 14), GPIO('E', 12), GPIO_FUNCTION(5) },
@@ -79,8 +86,9 @@ 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].sck_pin, spi_bus[bus].function, 0);
- // Configure CR2 on stm32 f0/g0/l4
-#if CONFIG_MACH_STM32F0 || CONFIG_MACH_STM32G0 || CONFIG_MACH_STM32L4
+ // Configure CR2 on stm32 f0/g0/l4/g4
+#if CONFIG_MACH_STM32F0 || CONFIG_MACH_STM32G0 || CONFIG_MACH_STM32L4 \
+ || CONFIG_MACH_STM32G4
spi->CR2 = SPI_CR2_FRXTH | (7 << SPI_CR2_DS_Pos);
#endif
}
diff --git a/src/stm32/stm32f0_i2c.c b/src/stm32/stm32f0_i2c.c
index 418e1c1e..6096b673 100644
--- a/src/stm32/stm32f0_i2c.c
+++ b/src/stm32/stm32f0_i2c.c
@@ -48,6 +48,23 @@ DECL_ENUMERATION("i2c_bus", "i2c2_PB13_PB14", 4);
DECL_CONSTANT_STR("BUS_PINS_i2c2_PB13_PB14", "PB13,PB14");
DECL_ENUMERATION("i2c_bus", "i2c1_PA9_PA10", 5);
DECL_CONSTANT_STR("BUS_PINS_i2c1_PA9_PA10", "PA9,PA10");
+#elif CONFIG_MACH_STM32G4
+DECL_ENUMERATION("i2c_bus", "i2c1_PA13_PA14", 0);
+DECL_CONSTANT_STR("BUS_PINS_i2c1_PA13_PA14", "PA13,PA14");
+DECL_ENUMERATION("i2c_bus", "i2c1_PA15_PA14", 1);
+DECL_CONSTANT_STR("BUS_PINS_i2c1_PA15_PA14", "PA15,PA14");
+DECL_ENUMERATION("i2c_bus", "i2c1_PB8_PB7", 2);
+DECL_CONSTANT_STR("BUS_PINS_i2c1_PB8_PB7", "PB8,PB7");
+DECL_ENUMERATION("i2c_bus", "i2c1_PB8_PB9", 3);
+DECL_CONSTANT_STR("BUS_PINS_i2c1_PB8_PB9", "PB8,PB9");
+DECL_ENUMERATION("i2c_bus", "i2c2_PA9_PA8", 4);
+DECL_CONSTANT_STR("BUS_PINS_i2c2_PA9_PA8", "PA9,PA8");
+DECL_ENUMERATION("i2c_bus", "i2c2_PC4_PF0", 5);
+DECL_CONSTANT_STR("BUS_PINS_i2c2_PC4_PF0", "PC4,PF0");
+DECL_ENUMERATION("i2c_bus", "i2c3_PC8_PC9", 6);
+DECL_CONSTANT_STR("BUS_PINS_i2c3_PC8_PC9", "PC8,PC9");
+DECL_ENUMERATION("i2c_bus", "i2c3_PC8_PC11", 7);
+DECL_CONSTANT_STR("BUS_PINS_i2c3_PC8_PC11", "PC8,PC11");
#endif
static const struct i2c_info i2c_bus[] = {
@@ -67,6 +84,16 @@ static const struct i2c_info i2c_bus[] = {
{ 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) },
+#elif CONFIG_MACH_STM32G4
+ { I2C1, GPIO('A', 13), GPIO('A', 14), GPIO_FUNCTION(4) },
+ { I2C1, GPIO('A', 15), GPIO('A', 14), GPIO_FUNCTION(4) },
+ { I2C1, GPIO('B', 8), GPIO('B', 7), GPIO_FUNCTION(4) },
+ { I2C1, GPIO('B', 8), GPIO('B', 9), GPIO_FUNCTION(4) },
+ { I2C2, GPIO('A', 9), GPIO('A', 8), GPIO_FUNCTION(4) },
+ { I2C2, GPIO('C', 4), GPIO('F', 0), GPIO_FUNCTION(4) },
+ { I2C3, GPIO('C', 8), GPIO('C', 9), GPIO_FUNCTION(8) },
+ { I2C3, GPIO('C', 8), GPIO('C', 11), GPIO_FUNCTION(8) },
+// { I2C3, GPIO('A', 8), GPIO('B', 5), GPIO_FUNCTION(4) },
#endif
};
diff --git a/src/stm32/stm32f0_serial.c b/src/stm32/stm32f0_serial.c
index f7f17dfc..bb4ec69a 100644
--- a/src/stm32/stm32f0_serial.c
+++ b/src/stm32/stm32f0_serial.c
@@ -16,28 +16,38 @@
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(CONFIG_MACH_STM32H7 ? 7 : 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(CONFIG_MACH_STM32H7 ? 7 : 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(CONFIG_MACH_STM32H7 ? 7 : 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
@@ -85,6 +95,9 @@
#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
diff --git a/src/stm32/stm32g4.c b/src/stm32/stm32g4.c
new file mode 100644
index 00000000..d75bcbe1
--- /dev/null
+++ b/src/stm32/stm32g4.c
@@ -0,0 +1,168 @@
+// Code to setup clocks and gpio on stm32g4
+//
+// 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 {
+ uint32_t pos = (periph_base - AHB2PERIPH_BASE) / 0x400;
+ return (struct cline){.en = &RCC->AHB2ENR,
+ .rst = &RCC->AHB2RSTR,
+ .bit = 1 << pos};
+ }
+}
+
+// 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
+bootloader_request(void)
+{
+ irq_disable();
+ // System DFU Bootloader
+ *(uint64_t*)USB_BOOT_FLAG_ADDR = USB_BOOT_FLAG;
+ NVIC_SystemReset();
+}
+
+#if !CONFIG_STM32_CLOCK_REF_INTERNAL
+DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PF0,PF1");
+#endif
+
+static void
+enable_clock_stm32g4(void)
+{
+ uint32_t pll_base = 4000000, pll_freq = CONFIG_CLOCK_FREQ * 2, pllcfgr;
+ if (!CONFIG_STM32_CLOCK_REF_INTERNAL) {
+ // Configure 150Mhz 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 150Mhz 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;
+ }
+}
+
+// Main clock setup called at chip startup
+static void
+clock_setup(void)
+{
+ enable_clock_stm32g4();
+
+ // Set flash latency
+ uint32_t latency = ((CONFIG_CLOCK_FREQ>150000000) ? FLASH_ACR_LATENCY_5WS :
+ ((CONFIG_CLOCK_FREQ>120000000) ? FLASH_ACR_LATENCY_4WS :
+ ((CONFIG_CLOCK_FREQ>90000000) ? FLASH_ACR_LATENCY_3WS :
+ ((CONFIG_CLOCK_FREQ>60000000) ? FLASH_ACR_LATENCY_2WS :
+ ((CONFIG_CLOCK_FREQ>30000000) ? FLASH_ACR_LATENCY_1WS :
+ FLASH_ACR_LATENCY_0WS)))));
+ FLASH->ACR = (latency | FLASH_ACR_ICEN | FLASH_ACR_DCEN
+ | FLASH_ACR_PRFTEN);
+
+ enable_pclock(PWR_BASE);
+ PWR->CR3 |= PWR_CR3_APC; // allow gpio pullup/down
+
+ // 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();
+}
diff --git a/src/stm32/stm32h7_adc.c b/src/stm32/stm32h7_adc.c
index d873dfb8..c44f291e 100644
--- a/src/stm32/stm32h7_adc.c
+++ b/src/stm32/stm32h7_adc.c
@@ -32,7 +32,7 @@
#define ADC_ISR_LDORDY_Msk (0x1UL << ADC_ISR_LDORDY_Pos)
#define ADC_ISR_LDORDY ADC_ISR_LDORDY_Msk
-#else // stm32l4
+#elif CONFIG_MACH_STM32L4
#define RCC_AHBENR_ADC (RCC->AHB2ENR)
#define RCC_AHBENR_ADCEN (RCC_AHB2ENR_ADCEN)
#define ADC_CKMODE (0)
@@ -42,6 +42,19 @@
#define OVERSAMPLES (0)
#define ADC_MEAS_DELAY (10)
+
+#elif CONFIG_MACH_STM32G4
+#define ADCIN_BANK_SIZE (19)
+#define RCC_AHBENR_ADC (RCC->AHB2ENR)
+#define RCC_AHBENR_ADCEN (RCC_AHB2ENR_ADC12EN)
+#define ADC_CKMODE (0b11)
+#define ADC_ATICKS (0b100)
+#define ADC_RES (0b00)
+#define ADC_TS (ADC12_COMMON)
+#define ADC_CCR_TSEN (ADC_CCR_VSENSESEL)
+
+#define OVERSAMPLES (0)
+#define ADC_MEAS_DELAY (10)
#endif
#define ADC_TEMPERATURE_PIN 0xfe
@@ -116,6 +129,45 @@ static const uint8_t adc_pins[] = {
0, // Vbat/4
ADC_TEMPERATURE_PIN,// VSENSE
0, // VREFINT
+#elif CONFIG_MACH_STM32G4
+ 0, // [0] vssa
+ GPIO('A', 0), // [1]
+ GPIO('A', 1), // [2]
+ GPIO('A', 2), // [3]
+ GPIO('A', 3), // [4]
+ GPIO('B', 14), // [5]
+ GPIO('C', 0), // [6]
+ GPIO('C', 1), // [7]
+ GPIO('C', 2), // [8]
+ GPIO('C', 3), // [9]
+ GPIO('F', 0), // [10]
+ GPIO('B', 12), // [11]
+ GPIO('B', 1), // [12]
+ 0, // [13] opamp
+ GPIO('B', 11), // [14]
+ GPIO('B', 0), // [15]
+ ADC_TEMPERATURE_PIN, // [16] vtemp
+ 0, // [17] vbat/3
+ 0, // [18] vref
+ 0, // [0] vssa ADC 2
+ GPIO('A', 0), // [1]
+ GPIO('A', 1), // [2]
+ GPIO('A', 6), // [3]
+ GPIO('A', 7), // [4]
+ GPIO('C', 4), // [5]
+ GPIO('C', 0), // [6]
+ GPIO('C', 1), // [7]
+ GPIO('C', 2), // [8]
+ GPIO('C', 3), // [9]
+ GPIO('F', 1), // [10]
+ GPIO('C', 5), // [11]
+ GPIO('B', 2), // [12]
+ GPIO('A', 5), // [13]
+ GPIO('B', 11), // [14]
+ GPIO('B', 15), // [15]
+ 0, // [16] opamp
+ GPIO('A', 4), // [17]
+ 0, // [18] opamp
#else // stm32l4
0, // vref
GPIO('C', 0), // ADC12_IN1 .. 16
@@ -168,7 +220,10 @@ gpio_adc_setup(uint32_t pin)
MODIFY_REG(ADC3_COMMON->CCR, ADC_CCR_CKMODE_Msk,
ADC_CKMODE << ADC_CCR_CKMODE_Pos);
chan -= 2 * ADCIN_BANK_SIZE;
- } else if (chan >= ADCIN_BANK_SIZE){
+ } else
+#endif
+#ifdef ADC2
+ if (chan >= ADCIN_BANK_SIZE){
adc = ADC2;
RCC_AHBENR_ADC |= RCC_AHBENR_ADCEN;
MODIFY_REG(ADC12_COMMON->CCR, ADC_CCR_CKMODE_Msk,
diff --git a/src/stm32/usbfs.c b/src/stm32/usbfs.c
index cfe70951..f144b2c9 100644
--- a/src/stm32/usbfs.c
+++ b/src/stm32/usbfs.c
@@ -15,7 +15,7 @@
#include "internal.h" // GPIO
#include "sched.h" // DECL_INIT
-#if CONFIG_MACH_STM32F103
+#if CONFIG_MACH_STM32F103 || CONFIG_MACH_STM32G4
// Transfer memory is accessed with 32bits, but contains only 16bits of data
typedef volatile uint32_t epmword_t;
#define WSIZE 2