aboutsummaryrefslogtreecommitdiff
path: root/platforms/chibios
diff options
context:
space:
mode:
Diffstat (limited to 'platforms/chibios')
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F401/board/board.mk (renamed from platforms/chibios/BLACKPILL_STM32_F401/board/board.mk)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F401/configs/board.h (renamed from platforms/chibios/BLACKPILL_STM32_F401/configs/board.h)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F401/configs/bootloader_defs.h (renamed from platforms/chibios/BLACKPILL_STM32_F401/configs/bootloader_defs.h)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F401/configs/config.h (renamed from platforms/chibios/BLACKPILL_STM32_F401/configs/config.h)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F401/configs/mcuconf.h (renamed from platforms/chibios/BLACKPILL_STM32_F401/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F411/board/board.mk (renamed from platforms/chibios/BLACKPILL_STM32_F411/board/board.mk)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F411/configs/board.h (renamed from platforms/chibios/BLACKPILL_STM32_F411/configs/board.h)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F411/configs/bootloader_defs.h (renamed from platforms/chibios/BLACKPILL_STM32_F411/configs/bootloader_defs.h)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F411/configs/config.h (renamed from platforms/chibios/BLACKPILL_STM32_F411/configs/config.h)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F411/configs/mcuconf.h (renamed from platforms/chibios/BLACKPILL_STM32_F411/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F411/ld/STM32F411xC_tinyuf2.ld (renamed from platforms/chibios/BLACKPILL_STM32_F411/ld/STM32F411xC_tinyuf2.ld)0
-rw-r--r--platforms/chibios/boards/BLACKPILL_STM32_F411/ld/STM32F411xE_tinyuf2.ld (renamed from platforms/chibios/BLACKPILL_STM32_F411/ld/STM32F411xE_tinyuf2.ld)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F042X6/board/board.c (renamed from platforms/chibios/GENERIC_STM32_F042X6/board/board.c)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F042X6/board/board.h (renamed from platforms/chibios/GENERIC_STM32_F042X6/board/board.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F042X6/board/board.mk (renamed from platforms/chibios/GENERIC_STM32_F042X6/board/board.mk)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F042X6/configs/bootloader_defs.h (renamed from platforms/chibios/GENERIC_STM32_F042X6/configs/bootloader_defs.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F042X6/configs/config.h (renamed from platforms/chibios/GENERIC_STM32_F042X6/configs/config.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F042X6/configs/mcuconf.h (renamed from platforms/chibios/GENERIC_STM32_F042X6/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F072XB/board/board.mk (renamed from platforms/chibios/GENERIC_STM32_F072XB/board/board.mk)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F072XB/configs/board.h (renamed from platforms/chibios/GENERIC_STM32_F072XB/configs/board.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F072XB/configs/bootloader_defs.h (renamed from platforms/chibios/GENERIC_STM32_F072XB/configs/bootloader_defs.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F072XB/configs/config.h (renamed from platforms/chibios/GENERIC_STM32_F072XB/configs/config.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F072XB/configs/mcuconf.h (renamed from platforms/chibios/GENERIC_STM32_F072XB/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F303XC/board/board.mk (renamed from platforms/chibios/GENERIC_STM32_F303XC/board/board.mk)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F303XC/configs/board.h (renamed from platforms/chibios/GENERIC_STM32_F303XC/configs/board.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F303XC/configs/bootloader_defs.h (renamed from platforms/chibios/GENERIC_STM32_F303XC/configs/bootloader_defs.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F303XC/configs/config.h (renamed from platforms/chibios/GENERIC_STM32_F303XC/configs/config.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F303XC/configs/mcuconf.h (renamed from platforms/chibios/GENERIC_STM32_F303XC/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F407XE/board/board.mk9
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F407XE/configs/board.h24
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h (renamed from platforms/chibios/GENERIC_STM32_F446XE/configs/config.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F407XE/configs/mcuconf.h355
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F446XE/board/board.mk (renamed from platforms/chibios/GENERIC_STM32_F446XE/board/board.mk)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F446XE/configs/board.h (renamed from platforms/chibios/GENERIC_STM32_F446XE/configs/board.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h23
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_F446XE/configs/mcuconf.h (renamed from platforms/chibios/GENERIC_STM32_F446XE/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_G431XB/board/board.mk (renamed from platforms/chibios/GENERIC_STM32_G431XB/board/board.mk)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_G431XB/configs/config.h (renamed from platforms/chibios/GENERIC_STM32_G431XB/configs/config.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_G431XB/configs/mcuconf.h (renamed from platforms/chibios/GENERIC_STM32_G431XB/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_G474XE/board/board.mk (renamed from platforms/chibios/GENERIC_STM32_G474XE/board/board.mk)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_G474XE/configs/config.h (renamed from platforms/chibios/GENERIC_STM32_G474XE/configs/config.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_G474XE/configs/mcuconf.h (renamed from platforms/chibios/GENERIC_STM32_G474XE/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_L412XB/board/board.mk (renamed from platforms/chibios/GENERIC_STM32_L433XC/board/board.mk)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_L412XB/configs/board.h (renamed from platforms/chibios/GENERIC_STM32_L433XC/configs/board.h)2
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h (renamed from platforms/chibios/GENERIC_STM32_L433XC/configs/config.h)0
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_L412XB/configs/mcuconf.h282
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_L433XC/board/board.mk9
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_L433XC/configs/board.h24
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h26
-rw-r--r--platforms/chibios/boards/GENERIC_STM32_L433XC/configs/mcuconf.h (renamed from platforms/chibios/GENERIC_STM32_L433XC/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/IC_TEENSY_3_1/board/board.c (renamed from platforms/chibios/IC_TEENSY_3_1/board/board.c)5
-rw-r--r--platforms/chibios/boards/IC_TEENSY_3_1/board/board.h (renamed from platforms/chibios/IC_TEENSY_3_1/board/board.h)0
-rw-r--r--platforms/chibios/boards/IC_TEENSY_3_1/board/board.mk (renamed from platforms/chibios/IC_TEENSY_3_1/board/board.mk)0
-rw-r--r--platforms/chibios/boards/IC_TEENSY_4_1/board/board.mk1
-rw-r--r--platforms/chibios/boards/IC_TEENSY_4_1/rules.mk1
-rw-r--r--platforms/chibios/boards/QMK_PROTON_C/board/board.mk (renamed from platforms/chibios/QMK_PROTON_C/board/board.mk)0
-rw-r--r--platforms/chibios/boards/QMK_PROTON_C/configs/board.h (renamed from platforms/chibios/QMK_PROTON_C/configs/board.h)0
-rw-r--r--platforms/chibios/boards/QMK_PROTON_C/configs/bootloader_defs.h (renamed from platforms/chibios/QMK_PROTON_C/configs/bootloader_defs.h)0
-rw-r--r--platforms/chibios/boards/QMK_PROTON_C/configs/chconf.h (renamed from platforms/chibios/QMK_PROTON_C/configs/chconf.h)0
-rw-r--r--platforms/chibios/boards/QMK_PROTON_C/configs/config.h (renamed from platforms/chibios/QMK_PROTON_C/configs/config.h)0
-rw-r--r--platforms/chibios/boards/QMK_PROTON_C/configs/halconf.h (renamed from platforms/chibios/QMK_PROTON_C/configs/halconf.h)2
-rw-r--r--platforms/chibios/boards/QMK_PROTON_C/configs/mcuconf.h (renamed from platforms/chibios/QMK_PROTON_C/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/QMK_PROTON_C/convert_to_proton_c.mk (renamed from platforms/chibios/QMK_PROTON_C/convert_to_proton_c.mk)0
-rw-r--r--platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.c (renamed from platforms/chibios/STM32_F103_STM32DUINO/board/board.c)0
-rw-r--r--platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.h (renamed from platforms/chibios/STM32_F103_STM32DUINO/board/board.h)0
-rw-r--r--platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.mk (renamed from platforms/chibios/STM32_F103_STM32DUINO/board/board.mk)0
-rw-r--r--platforms/chibios/boards/STM32_F103_STM32DUINO/configs/mcuconf.h (renamed from platforms/chibios/STM32_F103_STM32DUINO/configs/mcuconf.h)0
-rw-r--r--platforms/chibios/boards/STM32_F103_STM32DUINO/ld/STM32F103x8_stm32duino_bootloader.ld22
-rw-r--r--platforms/chibios/boards/STM32_F103_STM32DUINO/ld/STM32F103xB_stm32duino_bootloader.ld22
-rw-r--r--platforms/chibios/boards/STM32_F103_STM32DUINO/ld/stm32duino_bootloader_common.ld (renamed from platforms/chibios/common/ld/STM32F103x8_stm32duino_bootloader.ld)4
-rw-r--r--platforms/chibios/boards/common/configs/chconf.h (renamed from platforms/chibios/common/configs/chconf.h)0
-rw-r--r--platforms/chibios/boards/common/configs/halconf.h (renamed from platforms/chibios/common/configs/halconf.h)2
-rw-r--r--platforms/chibios/boards/common/ld/MKL26Z64.ld (renamed from platforms/chibios/common/ld/MKL26Z64.ld)0
-rw-r--r--platforms/chibios/boards/common/ld/STM32L412xB.ld85
-rw-r--r--platforms/chibios/boards/keyboard-config-templates/board.h (renamed from platforms/chibios/keyboard-config-templates/board.h)0
-rw-r--r--platforms/chibios/boards/keyboard-config-templates/chconf.h (renamed from platforms/chibios/keyboard-config-templates/chconf.h)0
-rw-r--r--platforms/chibios/boards/keyboard-config-templates/halconf.h (renamed from platforms/chibios/keyboard-config-templates/halconf.h)0
-rw-r--r--platforms/chibios/boards/keyboard-config-templates/mcuconf.h (renamed from platforms/chibios/keyboard-config-templates/mcuconf.h)0
-rw-r--r--platforms/chibios/drivers/analog.c321
-rw-r--r--platforms/chibios/drivers/analog.h41
-rw-r--r--platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.c96
-rw-r--r--platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h33
-rw-r--r--platforms/chibios/drivers/i2c_master.c121
-rw-r--r--platforms/chibios/drivers/i2c_master.h113
-rw-r--r--platforms/chibios/drivers/serial.c278
-rw-r--r--platforms/chibios/drivers/serial_usart.c318
-rw-r--r--platforms/chibios/drivers/serial_usart.h116
-rw-r--r--platforms/chibios/drivers/spi_master.c202
-rw-r--r--platforms/chibios/drivers/spi_master.h93
-rw-r--r--platforms/chibios/drivers/uart.c50
-rw-r--r--platforms/chibios/drivers/uart.h77
-rw-r--r--platforms/chibios/drivers/usbpd_stm32g4.c76
-rw-r--r--platforms/chibios/drivers/ws2812.c114
-rw-r--r--platforms/chibios/drivers/ws2812_pwm.c311
-rw-r--r--platforms/chibios/drivers/ws2812_spi.c159
-rw-r--r--platforms/chibios/flash.mk87
96 files changed, 3499 insertions, 5 deletions
diff --git a/platforms/chibios/BLACKPILL_STM32_F401/board/board.mk b/platforms/chibios/boards/BLACKPILL_STM32_F401/board/board.mk
index fddf7dace..fddf7dace 100644
--- a/platforms/chibios/BLACKPILL_STM32_F401/board/board.mk
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F401/board/board.mk
diff --git a/platforms/chibios/BLACKPILL_STM32_F401/configs/board.h b/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/board.h
index 30af6b0c8..30af6b0c8 100644
--- a/platforms/chibios/BLACKPILL_STM32_F401/configs/board.h
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/board.h
diff --git a/platforms/chibios/BLACKPILL_STM32_F401/configs/bootloader_defs.h b/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/bootloader_defs.h
index 4da3d39a3..4da3d39a3 100644
--- a/platforms/chibios/BLACKPILL_STM32_F401/configs/bootloader_defs.h
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/bootloader_defs.h
diff --git a/platforms/chibios/BLACKPILL_STM32_F401/configs/config.h b/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/config.h
index e181422eb..e181422eb 100644
--- a/platforms/chibios/BLACKPILL_STM32_F401/configs/config.h
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/config.h
diff --git a/platforms/chibios/BLACKPILL_STM32_F401/configs/mcuconf.h b/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/mcuconf.h
index ba6e934fe..ba6e934fe 100644
--- a/platforms/chibios/BLACKPILL_STM32_F401/configs/mcuconf.h
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/mcuconf.h
diff --git a/platforms/chibios/BLACKPILL_STM32_F411/board/board.mk b/platforms/chibios/boards/BLACKPILL_STM32_F411/board/board.mk
index bb00b1a2b..bb00b1a2b 100644
--- a/platforms/chibios/BLACKPILL_STM32_F411/board/board.mk
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F411/board/board.mk
diff --git a/platforms/chibios/BLACKPILL_STM32_F411/configs/board.h b/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/board.h
index 30af6b0c8..30af6b0c8 100644
--- a/platforms/chibios/BLACKPILL_STM32_F411/configs/board.h
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/board.h
diff --git a/platforms/chibios/BLACKPILL_STM32_F411/configs/bootloader_defs.h b/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/bootloader_defs.h
index 4da3d39a3..4da3d39a3 100644
--- a/platforms/chibios/BLACKPILL_STM32_F411/configs/bootloader_defs.h
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/bootloader_defs.h
diff --git a/platforms/chibios/BLACKPILL_STM32_F411/configs/config.h b/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/config.h
index e181422eb..e181422eb 100644
--- a/platforms/chibios/BLACKPILL_STM32_F411/configs/config.h
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/config.h
diff --git a/platforms/chibios/BLACKPILL_STM32_F411/configs/mcuconf.h b/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/mcuconf.h
index 0394ff56b..0394ff56b 100644
--- a/platforms/chibios/BLACKPILL_STM32_F411/configs/mcuconf.h
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/mcuconf.h
diff --git a/platforms/chibios/BLACKPILL_STM32_F411/ld/STM32F411xC_tinyuf2.ld b/platforms/chibios/boards/BLACKPILL_STM32_F411/ld/STM32F411xC_tinyuf2.ld
index 82253d3de..82253d3de 100644
--- a/platforms/chibios/BLACKPILL_STM32_F411/ld/STM32F411xC_tinyuf2.ld
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F411/ld/STM32F411xC_tinyuf2.ld
diff --git a/platforms/chibios/BLACKPILL_STM32_F411/ld/STM32F411xE_tinyuf2.ld b/platforms/chibios/boards/BLACKPILL_STM32_F411/ld/STM32F411xE_tinyuf2.ld
index 1656c67bf..1656c67bf 100644
--- a/platforms/chibios/BLACKPILL_STM32_F411/ld/STM32F411xE_tinyuf2.ld
+++ b/platforms/chibios/boards/BLACKPILL_STM32_F411/ld/STM32F411xE_tinyuf2.ld
diff --git a/platforms/chibios/GENERIC_STM32_F042X6/board/board.c b/platforms/chibios/boards/GENERIC_STM32_F042X6/board/board.c
index 0d7c88756..0d7c88756 100644
--- a/platforms/chibios/GENERIC_STM32_F042X6/board/board.c
+++ b/platforms/chibios/boards/GENERIC_STM32_F042X6/board/board.c
diff --git a/platforms/chibios/GENERIC_STM32_F042X6/board/board.h b/platforms/chibios/boards/GENERIC_STM32_F042X6/board/board.h
index ee9d31e04..ee9d31e04 100644
--- a/platforms/chibios/GENERIC_STM32_F042X6/board/board.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F042X6/board/board.h
diff --git a/platforms/chibios/GENERIC_STM32_F042X6/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_F042X6/board/board.mk
index 842e33590..842e33590 100644
--- a/platforms/chibios/GENERIC_STM32_F042X6/board/board.mk
+++ b/platforms/chibios/boards/GENERIC_STM32_F042X6/board/board.mk
diff --git a/platforms/chibios/GENERIC_STM32_F042X6/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/bootloader_defs.h
index 25113425a..25113425a 100644
--- a/platforms/chibios/GENERIC_STM32_F042X6/configs/bootloader_defs.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/bootloader_defs.h
diff --git a/platforms/chibios/GENERIC_STM32_F042X6/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/config.h
index a73f0c0b4..a73f0c0b4 100644
--- a/platforms/chibios/GENERIC_STM32_F042X6/configs/config.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/config.h
diff --git a/platforms/chibios/GENERIC_STM32_F042X6/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/mcuconf.h
index 286e1230c..286e1230c 100644
--- a/platforms/chibios/GENERIC_STM32_F042X6/configs/mcuconf.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/mcuconf.h
diff --git a/platforms/chibios/GENERIC_STM32_F072XB/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_F072XB/board/board.mk
index 3f0e6c46e..3f0e6c46e 100644
--- a/platforms/chibios/GENERIC_STM32_F072XB/board/board.mk
+++ b/platforms/chibios/boards/GENERIC_STM32_F072XB/board/board.mk
diff --git a/platforms/chibios/GENERIC_STM32_F072XB/configs/board.h b/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/board.h
index 30af6b0c8..30af6b0c8 100644
--- a/platforms/chibios/GENERIC_STM32_F072XB/configs/board.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/board.h
diff --git a/platforms/chibios/GENERIC_STM32_F072XB/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/bootloader_defs.h
index dccd0fa5d..dccd0fa5d 100644
--- a/platforms/chibios/GENERIC_STM32_F072XB/configs/bootloader_defs.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/bootloader_defs.h
diff --git a/platforms/chibios/GENERIC_STM32_F072XB/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/config.h
index a73f0c0b4..a73f0c0b4 100644
--- a/platforms/chibios/GENERIC_STM32_F072XB/configs/config.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/config.h
diff --git a/platforms/chibios/GENERIC_STM32_F072XB/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/mcuconf.h
index 32b2777a8..32b2777a8 100644
--- a/platforms/chibios/GENERIC_STM32_F072XB/configs/mcuconf.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/mcuconf.h
diff --git a/platforms/chibios/GENERIC_STM32_F303XC/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_F303XC/board/board.mk
index f891e6524..f891e6524 100644
--- a/platforms/chibios/GENERIC_STM32_F303XC/board/board.mk
+++ b/platforms/chibios/boards/GENERIC_STM32_F303XC/board/board.mk
diff --git a/platforms/chibios/GENERIC_STM32_F303XC/configs/board.h b/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/board.h
index 97159964d..97159964d 100644
--- a/platforms/chibios/GENERIC_STM32_F303XC/configs/board.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/board.h
diff --git a/platforms/chibios/GENERIC_STM32_F303XC/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/bootloader_defs.h
index 87ac7b10d..87ac7b10d 100644
--- a/platforms/chibios/GENERIC_STM32_F303XC/configs/bootloader_defs.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/bootloader_defs.h
diff --git a/platforms/chibios/GENERIC_STM32_F303XC/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/config.h
index a73f0c0b4..a73f0c0b4 100644
--- a/platforms/chibios/GENERIC_STM32_F303XC/configs/config.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/config.h
diff --git a/platforms/chibios/GENERIC_STM32_F303XC/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/mcuconf.h
index c6f5a8ac5..c6f5a8ac5 100644
--- a/platforms/chibios/GENERIC_STM32_F303XC/configs/mcuconf.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/mcuconf.h
diff --git a/platforms/chibios/boards/GENERIC_STM32_F407XE/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_F407XE/board/board.mk
new file mode 100644
index 000000000..6c837bb8e
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_STM32_F407XE/board/board.mk
@@ -0,0 +1,9 @@
1# List of all the board related files.
2BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_STM32F4_DISCOVERY/board.c
3
4# Required include directories
5BOARDINC = $(CHIBIOS)/os/hal/boards/ST_STM32F4_DISCOVERY
6
7# Shared variables
8ALLCSRC += $(BOARDSRC)
9ALLINC += $(BOARDINC) \ No newline at end of file
diff --git a/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/board.h b/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/board.h
new file mode 100644
index 000000000..22c4e4cd7
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/board.h
@@ -0,0 +1,24 @@
1/* Copyright 2020 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <https://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#define STM32_HSECLK 8000000
19// The following is required to disable the pull-down on PA9, when PA9 is used for the keyboard matrix:
20#define BOARD_OTG_NOVBUSSENS
21
22#include_next "board.h"
23
24#undef STM32_HSE_BYPASS \ No newline at end of file
diff --git a/platforms/chibios/GENERIC_STM32_F446XE/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h
index cc52a953e..cc52a953e 100644
--- a/platforms/chibios/GENERIC_STM32_F446XE/configs/config.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h
diff --git a/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/mcuconf.h
new file mode 100644
index 000000000..4be47fe1b
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/mcuconf.h
@@ -0,0 +1,355 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17#ifndef MCUCONF_H
18#define MCUCONF_H
19
20/*
21 * STM32F4xx drivers configuration.
22 * The following settings override the default settings present in
23 * the various device driver implementation headers.
24 * Note that the settings for each driver only have effect if the whole
25 * driver is enabled in halconf.h.
26 *
27 * IRQ priorities:
28 * 15...0 Lowest...Highest.
29 *
30 * DMA priorities:
31 * 0...3 Lowest...Highest.
32 */
33
34#define STM32F4xx_MCUCONF
35#define STM32F405_MCUCONF
36#define STM32F415_MCUCONF
37#define STM32F407_MCUCONF
38#define STM32F417_MCUCONF
39
40/*
41 * HAL driver system settings.
42 */
43#define STM32_NO_INIT FALSE
44#define STM32_PVD_ENABLE FALSE
45#define STM32_PLS STM32_PLS_LEV0
46#define STM32_BKPRAM_ENABLE FALSE
47#define STM32_HSI_ENABLED TRUE
48#define STM32_LSI_ENABLED TRUE
49#define STM32_HSE_ENABLED TRUE
50#define STM32_LSE_ENABLED FALSE
51#define STM32_CLOCK48_REQUIRED TRUE
52#define STM32_SW STM32_SW_PLL
53#define STM32_PLLSRC STM32_PLLSRC_HSE
54#define STM32_PLLM_VALUE 8
55#define STM32_PLLN_VALUE 336
56#define STM32_PLLP_VALUE 2
57#define STM32_PLLQ_VALUE 7
58#define STM32_HPRE STM32_HPRE_DIV1
59#define STM32_PPRE1 STM32_PPRE1_DIV4
60#define STM32_PPRE2 STM32_PPRE2_DIV2
61#define STM32_RTCSEL STM32_RTCSEL_LSI
62#define STM32_RTCPRE_VALUE 8
63#define STM32_MCO1SEL STM32_MCO1SEL_HSI
64#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
65#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
66#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
67#define STM32_I2SSRC STM32_I2SSRC_CKIN
68#define STM32_PLLI2SN_VALUE 192
69#define STM32_PLLI2SR_VALUE 5
70
71/*
72 * IRQ system settings.
73 */
74#define STM32_IRQ_EXTI0_PRIORITY 6
75#define STM32_IRQ_EXTI1_PRIORITY 6
76#define STM32_IRQ_EXTI2_PRIORITY 6
77#define STM32_IRQ_EXTI3_PRIORITY 6
78#define STM32_IRQ_EXTI4_PRIORITY 6
79#define STM32_IRQ_EXTI5_9_PRIORITY 6
80#define STM32_IRQ_EXTI10_15_PRIORITY 6
81#define STM32_IRQ_EXTI16_PRIORITY 6
82#define STM32_IRQ_EXTI17_PRIORITY 15
83#define STM32_IRQ_EXTI18_PRIORITY 6
84#define STM32_IRQ_EXTI19_PRIORITY 6
85#define STM32_IRQ_EXTI20_PRIORITY 6
86#define STM32_IRQ_EXTI21_PRIORITY 15
87#define STM32_IRQ_EXTI22_PRIORITY 15
88
89/*
90 * ADC driver system settings.
91 */
92#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV4
93#define STM32_ADC_USE_ADC1 FALSE
94#define STM32_ADC_USE_ADC2 FALSE
95#define STM32_ADC_USE_ADC3 FALSE
96#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
97#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
98#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
99#define STM32_ADC_ADC1_DMA_PRIORITY 2
100#define STM32_ADC_ADC2_DMA_PRIORITY 2
101#define STM32_ADC_ADC3_DMA_PRIORITY 2
102#define STM32_ADC_IRQ_PRIORITY 6
103#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6
104#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 6
105#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 6
106
107/*
108 * CAN driver system settings.
109 */
110#define STM32_CAN_USE_CAN1 FALSE
111#define STM32_CAN_USE_CAN2 FALSE
112#define STM32_CAN_CAN1_IRQ_PRIORITY 11
113#define STM32_CAN_CAN2_IRQ_PRIORITY 11
114
115/*
116 * DAC driver system settings.
117 */
118#define STM32_DAC_DUAL_MODE FALSE
119#define STM32_DAC_USE_DAC1_CH1 FALSE
120#define STM32_DAC_USE_DAC1_CH2 FALSE
121#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10
122#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10
123#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2
124#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2
125#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
126#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
127
128/*
129 * GPT driver system settings.
130 */
131#define STM32_GPT_USE_TIM1 FALSE
132#define STM32_GPT_USE_TIM2 FALSE
133#define STM32_GPT_USE_TIM3 FALSE
134#define STM32_GPT_USE_TIM4 FALSE
135#define STM32_GPT_USE_TIM5 FALSE
136#define STM32_GPT_USE_TIM6 FALSE
137#define STM32_GPT_USE_TIM7 FALSE
138#define STM32_GPT_USE_TIM8 FALSE
139#define STM32_GPT_USE_TIM9 FALSE
140#define STM32_GPT_USE_TIM11 FALSE
141#define STM32_GPT_USE_TIM12 FALSE
142#define STM32_GPT_USE_TIM14 FALSE
143#define STM32_GPT_TIM1_IRQ_PRIORITY 7
144#define STM32_GPT_TIM2_IRQ_PRIORITY 7
145#define STM32_GPT_TIM3_IRQ_PRIORITY 7
146#define STM32_GPT_TIM4_IRQ_PRIORITY 7
147#define STM32_GPT_TIM5_IRQ_PRIORITY 7
148#define STM32_GPT_TIM6_IRQ_PRIORITY 7
149#define STM32_GPT_TIM7_IRQ_PRIORITY 7
150#define STM32_GPT_TIM8_IRQ_PRIORITY 7
151#define STM32_GPT_TIM9_IRQ_PRIORITY 7
152#define STM32_GPT_TIM11_IRQ_PRIORITY 7
153#define STM32_GPT_TIM12_IRQ_PRIORITY 7
154#define STM32_GPT_TIM14_IRQ_PRIORITY 7
155
156/*
157 * I2C driver system settings.
158 */
159#define STM32_I2C_USE_I2C1 FALSE
160#define STM32_I2C_USE_I2C2 FALSE
161#define STM32_I2C_USE_I2C3 FALSE
162#define STM32_I2C_BUSY_TIMEOUT 50
163#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
164#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
165#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
166#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
167#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
168#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
169#define STM32_I2C_I2C1_IRQ_PRIORITY 5
170#define STM32_I2C_I2C2_IRQ_PRIORITY 5
171#define STM32_I2C_I2C3_IRQ_PRIORITY 5
172#define STM32_I2C_I2C1_DMA_PRIORITY 3
173#define STM32_I2C_I2C2_DMA_PRIORITY 3
174#define STM32_I2C_I2C3_DMA_PRIORITY 3
175#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
176
177/*
178 * I2S driver system settings.
179 */
180#define STM32_I2S_USE_SPI2 FALSE
181#define STM32_I2S_USE_SPI3 FALSE
182#define STM32_I2S_SPI2_IRQ_PRIORITY 10
183#define STM32_I2S_SPI3_IRQ_PRIORITY 10
184#define STM32_I2S_SPI2_DMA_PRIORITY 1
185#define STM32_I2S_SPI3_DMA_PRIORITY 1
186#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
187#define STM32_I2S_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
188#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
189#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
190#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure")
191
192/*
193 * ICU driver system settings.
194 */
195#define STM32_ICU_USE_TIM1 FALSE
196#define STM32_ICU_USE_TIM2 FALSE
197#define STM32_ICU_USE_TIM3 FALSE
198#define STM32_ICU_USE_TIM4 FALSE
199#define STM32_ICU_USE_TIM5 FALSE
200#define STM32_ICU_USE_TIM8 FALSE
201#define STM32_ICU_USE_TIM9 FALSE
202#define STM32_ICU_TIM1_IRQ_PRIORITY 7
203#define STM32_ICU_TIM2_IRQ_PRIORITY 7
204#define STM32_ICU_TIM3_IRQ_PRIORITY 7
205#define STM32_ICU_TIM4_IRQ_PRIORITY 7
206#define STM32_ICU_TIM5_IRQ_PRIORITY 7
207#define STM32_ICU_TIM8_IRQ_PRIORITY 7
208#define STM32_ICU_TIM9_IRQ_PRIORITY 7
209
210/*
211 * MAC driver system settings.
212 */
213#define STM32_MAC_TRANSMIT_BUFFERS 2
214#define STM32_MAC_RECEIVE_BUFFERS 4
215#define STM32_MAC_BUFFERS_SIZE 1522
216#define STM32_MAC_PHY_TIMEOUT 100
217#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE
218#define STM32_MAC_ETH1_IRQ_PRIORITY 13
219#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0
220
221/*
222 * PWM driver system settings.
223 */
224#define STM32_PWM_USE_ADVANCED FALSE
225#define STM32_PWM_USE_TIM1 FALSE
226#define STM32_PWM_USE_TIM2 FALSE
227#define STM32_PWM_USE_TIM3 FALSE
228#define STM32_PWM_USE_TIM4 FALSE
229#define STM32_PWM_USE_TIM5 FALSE
230#define STM32_PWM_USE_TIM8 FALSE
231#define STM32_PWM_USE_TIM9 FALSE
232#define STM32_PWM_TIM1_IRQ_PRIORITY 7
233#define STM32_PWM_TIM2_IRQ_PRIORITY 7
234#define STM32_PWM_TIM3_IRQ_PRIORITY 7
235#define STM32_PWM_TIM4_IRQ_PRIORITY 7
236#define STM32_PWM_TIM5_IRQ_PRIORITY 7
237#define STM32_PWM_TIM8_IRQ_PRIORITY 7
238#define STM32_PWM_TIM9_IRQ_PRIORITY 7
239
240/*
241 * RTC driver system settings.
242 */
243#define STM32_RTC_PRESA_VALUE 32
244#define STM32_RTC_PRESS_VALUE 1024
245#define STM32_RTC_CR_INIT 0
246#define STM32_RTC_TAMPCR_INIT 0
247
248/*
249 * SDC driver system settings.
250 */
251#define STM32_SDC_SDIO_DMA_PRIORITY 3
252#define STM32_SDC_SDIO_IRQ_PRIORITY 9
253#define STM32_SDC_WRITE_TIMEOUT_MS 1000
254#define STM32_SDC_READ_TIMEOUT_MS 1000
255#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10
256#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE
257#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
258
259/*
260 * SERIAL driver system settings.
261 */
262#define STM32_SERIAL_USE_USART1 FALSE
263#define STM32_SERIAL_USE_USART2 FALSE
264#define STM32_SERIAL_USE_USART3 FALSE
265#define STM32_SERIAL_USE_UART4 FALSE
266#define STM32_SERIAL_USE_UART5 FALSE
267#define STM32_SERIAL_USE_USART6 FALSE
268#define STM32_SERIAL_USART1_PRIORITY 12
269#define STM32_SERIAL_USART2_PRIORITY 12
270#define STM32_SERIAL_USART3_PRIORITY 12
271#define STM32_SERIAL_UART4_PRIORITY 12
272#define STM32_SERIAL_UART5_PRIORITY 12
273#define STM32_SERIAL_USART6_PRIORITY 12
274
275/*
276 * SPI driver system settings.
277 */
278#define STM32_SPI_USE_SPI1 FALSE
279#define STM32_SPI_USE_SPI2 FALSE
280#define STM32_SPI_USE_SPI3 FALSE
281#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0)
282#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
283#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
284#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
285#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
286#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
287#define STM32_SPI_SPI1_DMA_PRIORITY 1
288#define STM32_SPI_SPI2_DMA_PRIORITY 1
289#define STM32_SPI_SPI3_DMA_PRIORITY 1
290#define STM32_SPI_SPI1_IRQ_PRIORITY 10
291#define STM32_SPI_SPI2_IRQ_PRIORITY 10
292#define STM32_SPI_SPI3_IRQ_PRIORITY 10
293#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
294
295/*
296 * ST driver system settings.
297 */
298#define STM32_ST_IRQ_PRIORITY 8
299#define STM32_ST_USE_TIMER 2
300
301/*
302 * UART driver system settings.
303 */
304#define STM32_UART_USE_USART1 FALSE
305#define STM32_UART_USE_USART2 FALSE
306#define STM32_UART_USE_USART3 FALSE
307#define STM32_UART_USE_UART4 FALSE
308#define STM32_UART_USE_UART5 FALSE
309#define STM32_UART_USE_USART6 FALSE
310#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
311#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
312#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
313#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
314#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
315#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
316#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
317#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
318#define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
319#define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
320#define STM32_UART_USART6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
321#define STM32_UART_USART6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
322#define STM32_UART_USART1_IRQ_PRIORITY 12
323#define STM32_UART_USART2_IRQ_PRIORITY 12
324#define STM32_UART_USART3_IRQ_PRIORITY 12
325#define STM32_UART_UART4_IRQ_PRIORITY 12
326#define STM32_UART_UART5_IRQ_PRIORITY 12
327#define STM32_UART_USART6_IRQ_PRIORITY 12
328#define STM32_UART_USART1_DMA_PRIORITY 0
329#define STM32_UART_USART2_DMA_PRIORITY 0
330#define STM32_UART_USART3_DMA_PRIORITY 0
331#define STM32_UART_UART4_DMA_PRIORITY 0
332#define STM32_UART_UART5_DMA_PRIORITY 0
333#define STM32_UART_USART6_DMA_PRIORITY 0
334#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
335
336/*
337 * USB driver system settings.
338 */
339#define STM32_USB_USE_OTG1 TRUE
340#define STM32_USB_USE_OTG2 FALSE
341#define STM32_USB_OTG1_IRQ_PRIORITY 14
342#define STM32_USB_OTG2_IRQ_PRIORITY 14
343#define STM32_USB_OTG1_RX_FIFO_SIZE 512
344#define STM32_USB_OTG2_RX_FIFO_SIZE 1024
345#define STM32_USB_HOST_WAKEUP_DURATION 2
346
347#define STM32_USB_OTG_THREAD_PRIO NORMALPRIO+1
348#define STM32_USB_OTG_THREAD_STACK_SIZE 128
349
350/*
351 * WDG driver system settings.
352 */
353#define STM32_WDG_USE_IWDG FALSE
354
355#endif /* MCUCONF_H */
diff --git a/platforms/chibios/GENERIC_STM32_F446XE/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_F446XE/board/board.mk
index 57897941c..57897941c 100644
--- a/platforms/chibios/GENERIC_STM32_F446XE/board/board.mk
+++ b/platforms/chibios/boards/GENERIC_STM32_F446XE/board/board.mk
diff --git a/platforms/chibios/GENERIC_STM32_F446XE/configs/board.h b/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/board.h
index 80dfcffa9..80dfcffa9 100644
--- a/platforms/chibios/GENERIC_STM32_F446XE/configs/board.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/board.h
diff --git a/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h
new file mode 100644
index 000000000..cc52a953e
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h
@@ -0,0 +1,23 @@
1/* Copyright 2021 Andrei Purdea
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17/* Address for jumping to bootloader on STM32 chips. */
18/* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606.
19 */
20#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000
21#ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP
22# define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE
23#endif
diff --git a/platforms/chibios/GENERIC_STM32_F446XE/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/mcuconf.h
index d2de75590..d2de75590 100644
--- a/platforms/chibios/GENERIC_STM32_F446XE/configs/mcuconf.h
+++ b/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/mcuconf.h
diff --git a/platforms/chibios/GENERIC_STM32_G431XB/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_G431XB/board/board.mk
index 0acbcd83c..0acbcd83c 100644
--- a/platforms/chibios/GENERIC_STM32_G431XB/board/board.mk
+++ b/platforms/chibios/boards/GENERIC_STM32_G431XB/board/board.mk
diff --git a/platforms/chibios/GENERIC_STM32_G431XB/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_G431XB/configs/config.h
index 39ce627e7..39ce627e7 100644
--- a/platforms/chibios/GENERIC_STM32_G431XB/configs/config.h
+++ b/platforms/chibios/boards/GENERIC_STM32_G431XB/configs/config.h
diff --git a/platforms/chibios/GENERIC_STM32_G431XB/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_G431XB/configs/mcuconf.h
index 182d4885d..182d4885d 100644
--- a/platforms/chibios/GENERIC_STM32_G431XB/configs/mcuconf.h
+++ b/platforms/chibios/boards/GENERIC_STM32_G431XB/configs/mcuconf.h
diff --git a/platforms/chibios/GENERIC_STM32_G474XE/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_G474XE/board/board.mk
index 957adf509..957adf509 100644
--- a/platforms/chibios/GENERIC_STM32_G474XE/board/board.mk
+++ b/platforms/chibios/boards/GENERIC_STM32_G474XE/board/board.mk
diff --git a/platforms/chibios/GENERIC_STM32_G474XE/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_G474XE/configs/config.h
index eb74d68e8..eb74d68e8 100644
--- a/platforms/chibios/GENERIC_STM32_G474XE/configs/config.h
+++ b/platforms/chibios/boards/GENERIC_STM32_G474XE/configs/config.h
diff --git a/platforms/chibios/GENERIC_STM32_G474XE/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_G474XE/configs/mcuconf.h
index 117e920e3..117e920e3 100644
--- a/platforms/chibios/GENERIC_STM32_G474XE/configs/mcuconf.h
+++ b/platforms/chibios/boards/GENERIC_STM32_G474XE/configs/mcuconf.h
diff --git a/platforms/chibios/GENERIC_STM32_L433XC/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_L412XB/board/board.mk
index 1250385eb..1250385eb 100644
--- a/platforms/chibios/GENERIC_STM32_L433XC/board/board.mk
+++ b/platforms/chibios/boards/GENERIC_STM32_L412XB/board/board.mk
diff --git a/platforms/chibios/GENERIC_STM32_L433XC/configs/board.h b/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/board.h
index 51f9724f9..2e37d95fe 100644
--- a/platforms/chibios/GENERIC_STM32_L433XC/configs/board.h
+++ b/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/board.h
@@ -19,6 +19,6 @@
19 19
20#undef STM32L432xx 20#undef STM32L432xx
21 21
22// Pretend that we're an L443xx as the ChibiOS definitions for L432/L433 mistakenly don't enable GPIOH, I2C2, or SPI2. 22// Pretend that we're an L443xx as the ChibiOS definitions for L4x2/L4x3 mistakenly don't enable GPIOH, I2C2, or SPI2.
23// Until ChibiOS upstream is fixed, this should be kept at L443, as nothing in QMK currently utilises the crypto peripheral on the L443. 23// Until ChibiOS upstream is fixed, this should be kept at L443, as nothing in QMK currently utilises the crypto peripheral on the L443.
24#define STM32L443xx 24#define STM32L443xx
diff --git a/platforms/chibios/GENERIC_STM32_L433XC/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h
index c27c61b19..c27c61b19 100644
--- a/platforms/chibios/GENERIC_STM32_L433XC/configs/config.h
+++ b/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h
diff --git a/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/mcuconf.h
new file mode 100644
index 000000000..8ad5a8da2
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/mcuconf.h
@@ -0,0 +1,282 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/*
18 * STM32L4xx drivers configuration.
19 * The following settings override the default settings present in
20 * the various device driver implementation headers.
21 * Note that the settings for each driver only have effect if the whole
22 * driver is enabled in halconf.h.
23 *
24 * IRQ priorities:
25 * 15...0 Lowest...Highest.
26 *
27 * DMA priorities:
28 * 0...3 Lowest...Highest.
29 */
30
31#ifndef MCUCONF_H
32#define MCUCONF_H
33
34#define STM32L4xx_MCUCONF
35#define STM32L412_MCUCONF
36#define STM32L422_MCUCONF
37#define STM32L432_MCUCONF
38#define STM32L433_MCUCONF
39#define STM32L442_MCUCONF
40#define STM32L443_MCUCONF
41
42/*
43 * HAL driver system settings.
44 */
45#define STM32_NO_INIT FALSE
46#define STM32_VOS STM32_VOS_RANGE1
47#define STM32_PVD_ENABLE FALSE
48#define STM32_PLS STM32_PLS_LEV0
49#define STM32_HSI16_ENABLED TRUE
50#define STM32_HSI48_ENABLED TRUE
51#define STM32_LSI_ENABLED FALSE
52#define STM32_HSE_ENABLED FALSE
53#define STM32_LSE_ENABLED FALSE
54#define STM32_MSIPLL_ENABLED FALSE
55#define STM32_ADC_CLOCK_ENABLED TRUE
56#define STM32_USB_CLOCK_ENABLED TRUE
57#define STM32_SAI1_CLOCK_ENABLED TRUE
58#define STM32_SAI2_CLOCK_ENABLED TRUE
59#define STM32_MSIRANGE STM32_MSIRANGE_4M
60#define STM32_MSISRANGE STM32_MSISRANGE_4M
61#define STM32_SW STM32_SW_PLL
62#define STM32_PLLSRC STM32_PLLSRC_HSI16
63#define STM32_PLLM_VALUE 4
64#define STM32_PLLN_VALUE 80
65#define STM32_PLLP_VALUE 7
66#define STM32_PLLQ_VALUE 4
67#define STM32_PLLR_VALUE 4
68#define STM32_HPRE STM32_HPRE_DIV1
69#define STM32_PPRE1 STM32_PPRE1_DIV1
70#define STM32_PPRE2 STM32_PPRE2_DIV1
71#define STM32_STOPWUCK STM32_STOPWUCK_MSI
72#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
73#define STM32_MCOPRE STM32_MCOPRE_DIV1
74#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK
75#define STM32_PLLSAI1N_VALUE 72
76#define STM32_PLLSAI1P_VALUE 7
77#define STM32_PLLSAI1Q_VALUE 6
78#define STM32_PLLSAI1R_VALUE 6
79#define STM32_PLLSAI2N_VALUE 72
80#define STM32_PLLSAI2P_VALUE 7
81#define STM32_PLLSAI2R_VALUE 6
82
83/*
84 * Peripherals clock sources.
85 */
86#define STM32_USART1SEL STM32_USART1SEL_SYSCLK
87#define STM32_USART2SEL STM32_USART2SEL_SYSCLK
88#define STM32_USART3SEL STM32_USART3SEL_SYSCLK
89#define STM32_UART4SEL STM32_UART4SEL_SYSCLK
90#define STM32_UART5SEL STM32_UART5SEL_SYSCLK
91#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK
92#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK
93#define STM32_I2C2SEL STM32_I2C2SEL_SYSCLK
94#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK
95#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1
96#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1
97#define STM32_SAI1SEL STM32_SAI1SEL_OFF
98#define STM32_SAI2SEL STM32_SAI2SEL_OFF
99#define STM32_CLK48SEL STM32_CLK48SEL_HSI48
100#define STM32_ADCSEL STM32_ADCSEL_SYSCLK
101#define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1
102#define STM32_RTCSEL STM32_RTCSEL_LSI
103
104/*
105 * IRQ system settings.
106 */
107#define STM32_IRQ_EXTI0_PRIORITY 6
108#define STM32_IRQ_EXTI1_PRIORITY 6
109#define STM32_IRQ_EXTI2_PRIORITY 6
110#define STM32_IRQ_EXTI3_PRIORITY 6
111#define STM32_IRQ_EXTI4_PRIORITY 6
112#define STM32_IRQ_EXTI5_9_PRIORITY 6
113#define STM32_IRQ_EXTI10_15_PRIORITY 6
114#define STM32_IRQ_EXTI1635_38_PRIORITY 6
115#define STM32_IRQ_EXTI18_PRIORITY 6
116#define STM32_IRQ_EXTI19_PRIORITY 6
117#define STM32_IRQ_EXTI20_PRIORITY 6
118#define STM32_IRQ_EXTI21_22_PRIORITY 15
119
120#define STM32_IRQ_TIM1_BRK_TIM15_PRIORITY 7
121#define STM32_IRQ_TIM1_UP_TIM16_PRIORITY 7
122#define STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY 7
123#define STM32_IRQ_TIM1_CC_PRIORITY 7
124#define STM32_IRQ_TIM2_PRIORITY 7
125#define STM32_IRQ_TIM6_PRIORITY 7
126#define STM32_IRQ_TIM7_PRIORITY 7
127
128#define STM32_IRQ_USART1_PRIORITY 12
129#define STM32_IRQ_USART2_PRIORITY 12
130#define STM32_IRQ_USART3_PRIORITY 12
131#define STM32_IRQ_LPUART1_PRIORITY 12
132
133/*
134 * ADC driver system settings.
135 */
136#define STM32_ADC_COMPACT_SAMPLES FALSE
137#define STM32_ADC_USE_ADC1 FALSE
138#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
139#define STM32_ADC_ADC1_DMA_PRIORITY 2
140#define STM32_ADC_ADC12_IRQ_PRIORITY 5
141#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
142#define STM32_ADC_ADC123_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1
143#define STM32_ADC_ADC123_PRESC ADC_CCR_PRESC_DIV2
144
145/*
146 * CAN driver system settings.
147 */
148#define STM32_CAN_USE_CAN1 FALSE
149#define STM32_CAN_CAN1_IRQ_PRIORITY 11
150
151/*
152 * DAC driver system settings.
153 */
154#define STM32_DAC_DUAL_MODE FALSE
155#define STM32_DAC_USE_DAC1_CH1 FALSE
156#define STM32_DAC_USE_DAC1_CH2 FALSE
157#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10
158#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10
159#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2
160#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2
161#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
162#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
163
164/*
165 * GPT driver system settings.
166 */
167#define STM32_GPT_USE_TIM1 FALSE
168#define STM32_GPT_USE_TIM2 FALSE
169#define STM32_GPT_USE_TIM6 FALSE
170#define STM32_GPT_USE_TIM7 FALSE
171#define STM32_GPT_USE_TIM15 FALSE
172#define STM32_GPT_USE_TIM16 FALSE
173
174/*
175 * I2C driver system settings.
176 */
177#define STM32_I2C_USE_I2C1 FALSE
178#define STM32_I2C_USE_I2C3 FALSE
179#define STM32_I2C_BUSY_TIMEOUT 50
180#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
181#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
182#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
183#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
184#define STM32_I2C_I2C1_IRQ_PRIORITY 5
185#define STM32_I2C_I2C3_IRQ_PRIORITY 5
186#define STM32_I2C_I2C1_DMA_PRIORITY 3
187#define STM32_I2C_I2C3_DMA_PRIORITY 3
188#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
189
190/*
191 * ICU driver system settings.
192 */
193#define STM32_ICU_USE_TIM1 FALSE
194#define STM32_ICU_USE_TIM2 FALSE
195#define STM32_ICU_USE_TIM15 FALSE
196#define STM32_ICU_USE_TIM16 FALSE
197
198/*
199 * PWM driver system settings.
200 */
201#define STM32_PWM_USE_ADVANCED FALSE
202#define STM32_PWM_USE_TIM1 FALSE
203#define STM32_PWM_USE_TIM2 FALSE
204#define STM32_PWM_USE_TIM15 FALSE
205#define STM32_PWM_USE_TIM16 FALSE
206
207/*
208 * RTC driver system settings.
209 */
210#define STM32_RTC_PRESA_VALUE 32
211#define STM32_RTC_PRESS_VALUE 1024
212#define STM32_RTC_CR_INIT 0
213#define STM32_RTC_TAMPCR_INIT 0
214
215/*
216 * SERIAL driver system settings.
217 */
218#define STM32_SERIAL_USE_USART1 FALSE
219#define STM32_SERIAL_USE_USART2 FALSE
220#define STM32_SERIAL_USE_LPUART1 FALSE
221#define STM32_SERIAL_USART1_PRIORITY 12
222#define STM32_SERIAL_USART2_PRIORITY 12
223#define STM32_SERIAL_LPUART1_PRIORITY 12
224
225/*
226 * SPI driver system settings.
227 */
228#define STM32_SPI_USE_SPI1 FALSE
229#define STM32_SPI_USE_SPI3 FALSE
230#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
231#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
232#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
233#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
234#define STM32_SPI_SPI1_DMA_PRIORITY 1
235#define STM32_SPI_SPI3_DMA_PRIORITY 1
236#define STM32_SPI_SPI1_IRQ_PRIORITY 10
237#define STM32_SPI_SPI3_IRQ_PRIORITY 10
238#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
239
240/*
241 * ST driver system settings.
242 */
243#define STM32_ST_IRQ_PRIORITY 8
244#define STM32_ST_USE_TIMER 2
245
246/*
247 * TRNG driver system settings.
248 */
249#define STM32_TRNG_USE_RNG1 FALSE
250
251/*
252 * UART driver system settings.
253 */
254#define STM32_UART_USE_USART1 FALSE
255#define STM32_UART_USE_USART2 FALSE
256#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
257#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6)
258#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
259#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
260#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
261
262/*
263 * USB driver system settings.
264 */
265#define STM32_USB_USE_USB1 TRUE
266#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
267#define STM32_USB_USB1_HP_IRQ_PRIORITY 13
268#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
269
270/*
271 * WDG driver system settings.
272 */
273#define STM32_WDG_USE_IWDG FALSE
274
275/*
276 * WSPI driver system settings.
277 */
278#define STM32_WSPI_USE_QUADSPI1 FALSE
279#define STM32_WSPI_QUADSPI1_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
280#define STM32_WSPI_QUADSPI1_PRESCALER_VALUE 1
281
282#endif /* MCUCONF_H */
diff --git a/platforms/chibios/boards/GENERIC_STM32_L433XC/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_L433XC/board/board.mk
new file mode 100644
index 000000000..1250385eb
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_STM32_L433XC/board/board.mk
@@ -0,0 +1,9 @@
1# List of all the board related files.
2BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC/board.c
3
4# Required include directories
5BOARDINC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC
6
7# Shared variables
8ALLCSRC += $(BOARDSRC)
9ALLINC += $(BOARDINC)
diff --git a/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/board.h b/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/board.h
new file mode 100644
index 000000000..2e37d95fe
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/board.h
@@ -0,0 +1,24 @@
1/* Copyright 2018-2021 Harrison Chan (@Xelus)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <https://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#include_next "board.h"
19
20#undef STM32L432xx
21
22// Pretend that we're an L443xx as the ChibiOS definitions for L4x2/L4x3 mistakenly don't enable GPIOH, I2C2, or SPI2.
23// Until ChibiOS upstream is fixed, this should be kept at L443, as nothing in QMK currently utilises the crypto peripheral on the L443.
24#define STM32L443xx
diff --git a/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h
new file mode 100644
index 000000000..c27c61b19
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h
@@ -0,0 +1,26 @@
1/* Copyright 2018-2021 Harrison Chan (@Xelus)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17/* Address for jumping to bootloader on STM32 chips. */
18/* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606.
19 */
20#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000
21
22#define PAL_STM32_OSPEED_HIGHEST PAL_STM32_OSPEED_HIGH
23
24#ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP
25# define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE
26#endif
diff --git a/platforms/chibios/GENERIC_STM32_L433XC/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/mcuconf.h
index 948c740f6..948c740f6 100644
--- a/platforms/chibios/GENERIC_STM32_L433XC/configs/mcuconf.h
+++ b/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/mcuconf.h
diff --git a/platforms/chibios/IC_TEENSY_3_1/board/board.c b/platforms/chibios/boards/IC_TEENSY_3_1/board/board.c
index 36ae8051e..424e0c975 100644
--- a/platforms/chibios/IC_TEENSY_3_1/board/board.c
+++ b/platforms/chibios/boards/IC_TEENSY_3_1/board/board.c
@@ -144,3 +144,8 @@ void __early_init(void) {
144 * @todo Add your board-specific code, if any. 144 * @todo Add your board-specific code, if any.
145 */ 145 */
146void boardInit(void) {} 146void boardInit(void) {}
147
148
149void restart_usb_driver(USBDriver *usbp) {
150 // Do nothing. Restarting the USB driver on these boards breaks it.
151}
diff --git a/platforms/chibios/IC_TEENSY_3_1/board/board.h b/platforms/chibios/boards/IC_TEENSY_3_1/board/board.h
index c8259ab0c..c8259ab0c 100644
--- a/platforms/chibios/IC_TEENSY_3_1/board/board.h
+++ b/platforms/chibios/boards/IC_TEENSY_3_1/board/board.h
diff --git a/platforms/chibios/IC_TEENSY_3_1/board/board.mk b/platforms/chibios/boards/IC_TEENSY_3_1/board/board.mk
index 842e33590..842e33590 100644
--- a/platforms/chibios/IC_TEENSY_3_1/board/board.mk
+++ b/platforms/chibios/boards/IC_TEENSY_3_1/board/board.mk
diff --git a/platforms/chibios/boards/IC_TEENSY_4_1/board/board.mk b/platforms/chibios/boards/IC_TEENSY_4_1/board/board.mk
new file mode 100644
index 000000000..bc242ac3c
--- /dev/null
+++ b/platforms/chibios/boards/IC_TEENSY_4_1/board/board.mk
@@ -0,0 +1 @@
include $(CHIBIOS_CONTRIB)/os/hal/boards/PJRC_TEENSY_4_1/board.mk
diff --git a/platforms/chibios/boards/IC_TEENSY_4_1/rules.mk b/platforms/chibios/boards/IC_TEENSY_4_1/rules.mk
new file mode 100644
index 000000000..0c62d209c
--- /dev/null
+++ b/platforms/chibios/boards/IC_TEENSY_4_1/rules.mk
@@ -0,0 +1 @@
TEENSY_LOADER_CLI_MCU = imxrt1062
diff --git a/platforms/chibios/QMK_PROTON_C/board/board.mk b/platforms/chibios/boards/QMK_PROTON_C/board/board.mk
index f891e6524..f891e6524 100644
--- a/platforms/chibios/QMK_PROTON_C/board/board.mk
+++ b/platforms/chibios/boards/QMK_PROTON_C/board/board.mk
diff --git a/platforms/chibios/QMK_PROTON_C/configs/board.h b/platforms/chibios/boards/QMK_PROTON_C/configs/board.h
index 97159964d..97159964d 100644
--- a/platforms/chibios/QMK_PROTON_C/configs/board.h
+++ b/platforms/chibios/boards/QMK_PROTON_C/configs/board.h
diff --git a/platforms/chibios/QMK_PROTON_C/configs/bootloader_defs.h b/platforms/chibios/boards/QMK_PROTON_C/configs/bootloader_defs.h
index 3b0e9d20a..3b0e9d20a 100644
--- a/platforms/chibios/QMK_PROTON_C/configs/bootloader_defs.h
+++ b/platforms/chibios/boards/QMK_PROTON_C/configs/bootloader_defs.h
diff --git a/platforms/chibios/QMK_PROTON_C/configs/chconf.h b/platforms/chibios/boards/QMK_PROTON_C/configs/chconf.h
index a1cbf6808..a1cbf6808 100644
--- a/platforms/chibios/QMK_PROTON_C/configs/chconf.h
+++ b/platforms/chibios/boards/QMK_PROTON_C/configs/chconf.h
diff --git a/platforms/chibios/QMK_PROTON_C/configs/config.h b/platforms/chibios/boards/QMK_PROTON_C/configs/config.h
index a73f0c0b4..a73f0c0b4 100644
--- a/platforms/chibios/QMK_PROTON_C/configs/config.h
+++ b/platforms/chibios/boards/QMK_PROTON_C/configs/config.h
diff --git a/platforms/chibios/QMK_PROTON_C/configs/halconf.h b/platforms/chibios/boards/QMK_PROTON_C/configs/halconf.h
index 41fbac29e..d7a639a6d 100644
--- a/platforms/chibios/QMK_PROTON_C/configs/halconf.h
+++ b/platforms/chibios/boards/QMK_PROTON_C/configs/halconf.h
@@ -412,7 +412,7 @@
412 * buffers. 412 * buffers.
413 */ 413 */
414#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) 414#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
415#define SERIAL_BUFFERS_SIZE 16 415#define SERIAL_BUFFERS_SIZE 128
416#endif 416#endif
417 417
418/*===========================================================================*/ 418/*===========================================================================*/
diff --git a/platforms/chibios/QMK_PROTON_C/configs/mcuconf.h b/platforms/chibios/boards/QMK_PROTON_C/configs/mcuconf.h
index 4d7b586c0..4d7b586c0 100644
--- a/platforms/chibios/QMK_PROTON_C/configs/mcuconf.h
+++ b/platforms/chibios/boards/QMK_PROTON_C/configs/mcuconf.h
diff --git a/platforms/chibios/QMK_PROTON_C/convert_to_proton_c.mk b/platforms/chibios/boards/QMK_PROTON_C/convert_to_proton_c.mk
index 061815467..061815467 100644
--- a/platforms/chibios/QMK_PROTON_C/convert_to_proton_c.mk
+++ b/platforms/chibios/boards/QMK_PROTON_C/convert_to_proton_c.mk
diff --git a/platforms/chibios/STM32_F103_STM32DUINO/board/board.c b/platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.c
index 8a34e81f2..8a34e81f2 100644
--- a/platforms/chibios/STM32_F103_STM32DUINO/board/board.c
+++ b/platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.c
diff --git a/platforms/chibios/STM32_F103_STM32DUINO/board/board.h b/platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.h
index 09d182d6c..09d182d6c 100644
--- a/platforms/chibios/STM32_F103_STM32DUINO/board/board.h
+++ b/platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.h
diff --git a/platforms/chibios/STM32_F103_STM32DUINO/board/board.mk b/platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.mk
index 842e33590..842e33590 100644
--- a/platforms/chibios/STM32_F103_STM32DUINO/board/board.mk
+++ b/platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.mk
diff --git a/platforms/chibios/STM32_F103_STM32DUINO/configs/mcuconf.h b/platforms/chibios/boards/STM32_F103_STM32DUINO/configs/mcuconf.h
index 9945e7408..9945e7408 100644
--- a/platforms/chibios/STM32_F103_STM32DUINO/configs/mcuconf.h
+++ b/platforms/chibios/boards/STM32_F103_STM32DUINO/configs/mcuconf.h
diff --git a/platforms/chibios/boards/STM32_F103_STM32DUINO/ld/STM32F103x8_stm32duino_bootloader.ld b/platforms/chibios/boards/STM32_F103_STM32DUINO/ld/STM32F103x8_stm32duino_bootloader.ld
new file mode 100644
index 000000000..a4bd566b5
--- /dev/null
+++ b/platforms/chibios/boards/STM32_F103_STM32DUINO/ld/STM32F103x8_stm32duino_bootloader.ld
@@ -0,0 +1,22 @@
1/*
2 ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/*
18 * STM32F103x8 memory setup for use with the STM32Duino bootloader.
19 */
20f103_flash_size = 64k;
21
22INCLUDE stm32duino_bootloader_common.ld
diff --git a/platforms/chibios/boards/STM32_F103_STM32DUINO/ld/STM32F103xB_stm32duino_bootloader.ld b/platforms/chibios/boards/STM32_F103_STM32DUINO/ld/STM32F103xB_stm32duino_bootloader.ld
new file mode 100644
index 000000000..dc47400dc
--- /dev/null
+++ b/platforms/chibios/boards/STM32_F103_STM32DUINO/ld/STM32F103xB_stm32duino_bootloader.ld
@@ -0,0 +1,22 @@
1/*
2 ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/*
18 * STM32F103xB memory setup for use with the STM32Duino bootloader.
19 */
20f103_flash_size = 128k;
21
22INCLUDE stm32duino_bootloader_common.ld
diff --git a/platforms/chibios/common/ld/STM32F103x8_stm32duino_bootloader.ld b/platforms/chibios/boards/STM32_F103_STM32DUINO/ld/stm32duino_bootloader_common.ld
index bb852422a..76cd3153b 100644
--- a/platforms/chibios/common/ld/STM32F103x8_stm32duino_bootloader.ld
+++ b/platforms/chibios/boards/STM32_F103_STM32DUINO/ld/stm32duino_bootloader_common.ld
@@ -15,11 +15,11 @@
15*/ 15*/
16 16
17/* 17/*
18 * ST32F103xB memory setup for use with the maplemini bootloader. 18 * STM32Duino bootloader common memory setup.
19 */ 19 */
20MEMORY 20MEMORY
21{ 21{
22 flash0 : org = 0x08002000, len = 64k - 0x2000 22 flash0 : org = 0x08002000, len = f103_flash_size - 0x2000
23 flash1 : org = 0x00000000, len = 0 23 flash1 : org = 0x00000000, len = 0
24 flash2 : org = 0x00000000, len = 0 24 flash2 : org = 0x00000000, len = 0
25 flash3 : org = 0x00000000, len = 0 25 flash3 : org = 0x00000000, len = 0
diff --git a/platforms/chibios/common/configs/chconf.h b/platforms/chibios/boards/common/configs/chconf.h
index 44327a82d..44327a82d 100644
--- a/platforms/chibios/common/configs/chconf.h
+++ b/platforms/chibios/boards/common/configs/chconf.h
diff --git a/platforms/chibios/common/configs/halconf.h b/platforms/chibios/boards/common/configs/halconf.h
index 264ae4e6c..c80f67ee2 100644
--- a/platforms/chibios/common/configs/halconf.h
+++ b/platforms/chibios/boards/common/configs/halconf.h
@@ -412,7 +412,7 @@
412 * buffers. 412 * buffers.
413 */ 413 */
414#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) 414#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
415#define SERIAL_BUFFERS_SIZE 16 415#define SERIAL_BUFFERS_SIZE 128
416#endif 416#endif
417 417
418/*===========================================================================*/ 418/*===========================================================================*/
diff --git a/platforms/chibios/common/ld/MKL26Z64.ld b/platforms/chibios/boards/common/ld/MKL26Z64.ld
index c4ca8b874..c4ca8b874 100644
--- a/platforms/chibios/common/ld/MKL26Z64.ld
+++ b/platforms/chibios/boards/common/ld/MKL26Z64.ld
diff --git a/platforms/chibios/boards/common/ld/STM32L412xB.ld b/platforms/chibios/boards/common/ld/STM32L412xB.ld
new file mode 100644
index 000000000..5718d6bc7
--- /dev/null
+++ b/platforms/chibios/boards/common/ld/STM32L412xB.ld
@@ -0,0 +1,85 @@
1/*
2 ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/*
18 * STM32L412xB memory setup.
19 */
20MEMORY
21{
22 flash0 : org = 0x08000000, len = 128k
23 flash1 : org = 0x00000000, len = 0
24 flash2 : org = 0x00000000, len = 0
25 flash3 : org = 0x00000000, len = 0
26 flash4 : org = 0x00000000, len = 0
27 flash5 : org = 0x00000000, len = 0
28 flash6 : org = 0x00000000, len = 0
29 flash7 : org = 0x00000000, len = 0
30 ram0 : org = 0x20000000, len = 32k
31 ram1 : org = 0x00000000, len = 0
32 ram2 : org = 0x00000000, len = 0
33 ram3 : org = 0x00000000, len = 0
34 ram4 : org = 0x00000000, len = 0
35 ram5 : org = 0x00000000, len = 0
36 ram6 : org = 0x00000000, len = 0
37 ram7 : org = 0x00000000, len = 0
38}
39
40/* For each data/text section two region are defined, a virtual region
41 and a load region (_LMA suffix).*/
42
43/* Flash region to be used for exception vectors.*/
44REGION_ALIAS("VECTORS_FLASH", flash0);
45REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
46
47/* Flash region to be used for constructors and destructors.*/
48REGION_ALIAS("XTORS_FLASH", flash0);
49REGION_ALIAS("XTORS_FLASH_LMA", flash0);
50
51/* Flash region to be used for code text.*/
52REGION_ALIAS("TEXT_FLASH", flash0);
53REGION_ALIAS("TEXT_FLASH_LMA", flash0);
54
55/* Flash region to be used for read only data.*/
56REGION_ALIAS("RODATA_FLASH", flash0);
57REGION_ALIAS("RODATA_FLASH_LMA", flash0);
58
59/* Flash region to be used for various.*/
60REGION_ALIAS("VARIOUS_FLASH", flash0);
61REGION_ALIAS("VARIOUS_FLASH_LMA", flash0);
62
63/* Flash region to be used for RAM(n) initialization data.*/
64REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0);
65
66/* RAM region to be used for Main stack. This stack accommodates the processing
67 of all exceptions and interrupts.*/
68REGION_ALIAS("MAIN_STACK_RAM", ram0);
69
70/* RAM region to be used for the process stack. This is the stack used by
71 the main() function.*/
72REGION_ALIAS("PROCESS_STACK_RAM", ram0);
73
74/* RAM region to be used for data segment.*/
75REGION_ALIAS("DATA_RAM", ram0);
76REGION_ALIAS("DATA_RAM_LMA", flash0);
77
78/* RAM region to be used for BSS segment.*/
79REGION_ALIAS("BSS_RAM", ram0);
80
81/* RAM region to be used for the default heap.*/
82REGION_ALIAS("HEAP_RAM", ram0);
83
84/* Generic rules inclusion.*/
85INCLUDE rules.ld
diff --git a/platforms/chibios/keyboard-config-templates/board.h b/platforms/chibios/boards/keyboard-config-templates/board.h
index 5b840c389..5b840c389 100644
--- a/platforms/chibios/keyboard-config-templates/board.h
+++ b/platforms/chibios/boards/keyboard-config-templates/board.h
diff --git a/platforms/chibios/keyboard-config-templates/chconf.h b/platforms/chibios/boards/keyboard-config-templates/chconf.h
index fca444747..fca444747 100644
--- a/platforms/chibios/keyboard-config-templates/chconf.h
+++ b/platforms/chibios/boards/keyboard-config-templates/chconf.h
diff --git a/platforms/chibios/keyboard-config-templates/halconf.h b/platforms/chibios/boards/keyboard-config-templates/halconf.h
index 456020f16..456020f16 100644
--- a/platforms/chibios/keyboard-config-templates/halconf.h
+++ b/platforms/chibios/boards/keyboard-config-templates/halconf.h
diff --git a/platforms/chibios/keyboard-config-templates/mcuconf.h b/platforms/chibios/boards/keyboard-config-templates/mcuconf.h
index c690b02f4..c690b02f4 100644
--- a/platforms/chibios/keyboard-config-templates/mcuconf.h
+++ b/platforms/chibios/boards/keyboard-config-templates/mcuconf.h
diff --git a/platforms/chibios/drivers/analog.c b/platforms/chibios/drivers/analog.c
new file mode 100644
index 000000000..8c476fcac
--- /dev/null
+++ b/platforms/chibios/drivers/analog.c
@@ -0,0 +1,321 @@
1/* Copyright 2019 Drew Mills
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "quantum.h"
18#include "analog.h"
19#include <ch.h>
20#include <hal.h>
21
22#if !HAL_USE_ADC
23# error "You need to set HAL_USE_ADC to TRUE in your halconf.h to use the ADC."
24#endif
25
26#if !STM32_ADC_USE_ADC1 && !STM32_ADC_USE_ADC2 && !STM32_ADC_USE_ADC3 && !STM32_ADC_USE_ADC4
27# error "You need to set one of the 'STM32_ADC_USE_ADCx' settings to TRUE in your mcuconf.h to use the ADC."
28#endif
29
30#if STM32_ADC_DUAL_MODE
31# error "STM32 ADC Dual Mode is not supported at this time."
32#endif
33
34#if STM32_ADCV3_OVERSAMPLING
35# error "STM32 ADCV3 Oversampling is not supported at this time."
36#endif
37
38// Otherwise assume V3
39#if defined(STM32F0XX) || defined(STM32L0XX)
40# define USE_ADCV1
41#elif defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX)
42# define USE_ADCV2
43#endif
44
45// BODGE to make v2 look like v1,3 and 4
46#ifdef USE_ADCV2
47# if !defined(ADC_SMPR_SMP_1P5) && defined(ADC_SAMPLE_3)
48# define ADC_SMPR_SMP_1P5 ADC_SAMPLE_3
49# define ADC_SMPR_SMP_7P5 ADC_SAMPLE_15
50# define ADC_SMPR_SMP_13P5 ADC_SAMPLE_28
51# define ADC_SMPR_SMP_28P5 ADC_SAMPLE_56
52# define ADC_SMPR_SMP_41P5 ADC_SAMPLE_84
53# define ADC_SMPR_SMP_55P5 ADC_SAMPLE_112
54# define ADC_SMPR_SMP_71P5 ADC_SAMPLE_144
55# define ADC_SMPR_SMP_239P5 ADC_SAMPLE_480
56# endif
57
58# if !defined(ADC_SMPR_SMP_1P5) && defined(ADC_SAMPLE_1P5)
59# define ADC_SMPR_SMP_1P5 ADC_SAMPLE_1P5
60# define ADC_SMPR_SMP_7P5 ADC_SAMPLE_7P5
61# define ADC_SMPR_SMP_13P5 ADC_SAMPLE_13P5
62# define ADC_SMPR_SMP_28P5 ADC_SAMPLE_28P5
63# define ADC_SMPR_SMP_41P5 ADC_SAMPLE_41P5
64# define ADC_SMPR_SMP_55P5 ADC_SAMPLE_55P5
65# define ADC_SMPR_SMP_71P5 ADC_SAMPLE_71P5
66# define ADC_SMPR_SMP_239P5 ADC_SAMPLE_239P5
67# endif
68
69// we still sample at 12bit, but scale down to the requested bit range
70# define ADC_CFGR1_RES_12BIT 12
71# define ADC_CFGR1_RES_10BIT 10
72# define ADC_CFGR1_RES_8BIT 8
73# define ADC_CFGR1_RES_6BIT 6
74#endif
75
76/* User configurable ADC options */
77#ifndef ADC_COUNT
78# if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F4XX)
79# define ADC_COUNT 1
80# elif defined(STM32F3XX)
81# define ADC_COUNT 4
82# else
83# error "ADC_COUNT has not been set for this ARM microcontroller."
84# endif
85#endif
86
87#ifndef ADC_NUM_CHANNELS
88# define ADC_NUM_CHANNELS 1
89#elif ADC_NUM_CHANNELS != 1
90# error "The ARM ADC implementation currently only supports reading one channel at a time."
91#endif
92
93#ifndef ADC_BUFFER_DEPTH
94# define ADC_BUFFER_DEPTH 1
95#endif
96
97// For more sampling rate options, look at hal_adc_lld.h in ChibiOS
98#ifndef ADC_SAMPLING_RATE
99# define ADC_SAMPLING_RATE ADC_SMPR_SMP_1P5
100#endif
101
102// Options are 12, 10, 8, and 6 bit.
103#ifndef ADC_RESOLUTION
104# ifdef ADC_CFGR_RES_10BITS // ADCv3, ADCv4
105# define ADC_RESOLUTION ADC_CFGR_RES_10BITS
106# else // ADCv1, ADCv5, or the bodge for ADCv2 above
107# define ADC_RESOLUTION ADC_CFGR1_RES_10BIT
108# endif
109#endif
110
111static ADCConfig adcCfg = {};
112static adcsample_t sampleBuffer[ADC_NUM_CHANNELS * ADC_BUFFER_DEPTH];
113
114// Initialize to max number of ADCs, set to empty object to initialize all to false.
115static bool adcInitialized[ADC_COUNT] = {};
116
117// TODO: add back TR handling???
118static ADCConversionGroup adcConversionGroup = {
119 .circular = FALSE,
120 .num_channels = (uint16_t)(ADC_NUM_CHANNELS),
121#if defined(USE_ADCV1)
122 .cfgr1 = ADC_CFGR1_CONT | ADC_RESOLUTION,
123 .smpr = ADC_SAMPLING_RATE,
124#elif defined(USE_ADCV2)
125# if !defined(STM32F1XX)
126 .cr2 = ADC_CR2_SWSTART, // F103 seem very unhappy with, F401 seems very unhappy without...
127# endif
128 .smpr2 = ADC_SMPR2_SMP_AN0(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN1(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN2(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN3(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN4(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN5(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN6(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN7(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN8(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN9(ADC_SAMPLING_RATE),
129 .smpr1 = ADC_SMPR1_SMP_AN10(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN11(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN12(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN13(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN14(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN15(ADC_SAMPLING_RATE),
130#else
131 .cfgr = ADC_CFGR_CONT | ADC_RESOLUTION,
132 .smpr = {ADC_SMPR1_SMP_AN0(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN1(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN2(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN3(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN4(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN5(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN6(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN7(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN8(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN9(ADC_SAMPLING_RATE), ADC_SMPR2_SMP_AN10(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN11(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN12(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN13(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN14(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN15(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN16(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN17(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN18(ADC_SAMPLING_RATE)},
133#endif
134};
135
136// clang-format off
137__attribute__((weak)) adc_mux pinToMux(pin_t pin) {
138 switch (pin) {
139#if defined(STM32F0XX)
140 case A0: return TO_MUX( ADC_CHSELR_CHSEL0, 0 );
141 case A1: return TO_MUX( ADC_CHSELR_CHSEL1, 0 );
142 case A2: return TO_MUX( ADC_CHSELR_CHSEL2, 0 );
143 case A3: return TO_MUX( ADC_CHSELR_CHSEL3, 0 );
144 case A4: return TO_MUX( ADC_CHSELR_CHSEL4, 0 );
145 case A5: return TO_MUX( ADC_CHSELR_CHSEL5, 0 );
146 case A6: return TO_MUX( ADC_CHSELR_CHSEL6, 0 );
147 case A7: return TO_MUX( ADC_CHSELR_CHSEL7, 0 );
148 case B0: return TO_MUX( ADC_CHSELR_CHSEL8, 0 );
149 case B1: return TO_MUX( ADC_CHSELR_CHSEL9, 0 );
150 case C0: return TO_MUX( ADC_CHSELR_CHSEL10, 0 );
151 case C1: return TO_MUX( ADC_CHSELR_CHSEL11, 0 );
152 case C2: return TO_MUX( ADC_CHSELR_CHSEL12, 0 );
153 case C3: return TO_MUX( ADC_CHSELR_CHSEL13, 0 );
154 case C4: return TO_MUX( ADC_CHSELR_CHSEL14, 0 );
155 case C5: return TO_MUX( ADC_CHSELR_CHSEL15, 0 );
156#elif defined(STM32F3XX)
157 case A0: return TO_MUX( ADC_CHANNEL_IN1, 0 );
158 case A1: return TO_MUX( ADC_CHANNEL_IN2, 0 );
159 case A2: return TO_MUX( ADC_CHANNEL_IN3, 0 );
160 case A3: return TO_MUX( ADC_CHANNEL_IN4, 0 );
161 case A4: return TO_MUX( ADC_CHANNEL_IN1, 1 );
162 case A5: return TO_MUX( ADC_CHANNEL_IN2, 1 );
163 case A6: return TO_MUX( ADC_CHANNEL_IN3, 1 );
164 case A7: return TO_MUX( ADC_CHANNEL_IN4, 1 );
165 case B0: return TO_MUX( ADC_CHANNEL_IN12, 2 );
166 case B1: return TO_MUX( ADC_CHANNEL_IN1, 2 );
167 case B2: return TO_MUX( ADC_CHANNEL_IN12, 1 );
168 case B12: return TO_MUX( ADC_CHANNEL_IN3, 3 );
169 case B13: return TO_MUX( ADC_CHANNEL_IN5, 2 );
170 case B14: return TO_MUX( ADC_CHANNEL_IN4, 3 );
171 case B15: return TO_MUX( ADC_CHANNEL_IN5, 3 );
172 case C0: return TO_MUX( ADC_CHANNEL_IN6, 0 ); // Can also be ADC2
173 case C1: return TO_MUX( ADC_CHANNEL_IN7, 0 ); // Can also be ADC2
174 case C2: return TO_MUX( ADC_CHANNEL_IN8, 0 ); // Can also be ADC2
175 case C3: return TO_MUX( ADC_CHANNEL_IN9, 0 ); // Can also be ADC2
176 case C4: return TO_MUX( ADC_CHANNEL_IN5, 1 );
177 case C5: return TO_MUX( ADC_CHANNEL_IN11, 1 );
178 case D8: return TO_MUX( ADC_CHANNEL_IN12, 3 );
179 case D9: return TO_MUX( ADC_CHANNEL_IN13, 3 );
180 case D10: return TO_MUX( ADC_CHANNEL_IN7, 2 ); // Can also be ADC4
181 case D11: return TO_MUX( ADC_CHANNEL_IN8, 2 ); // Can also be ADC4
182 case D12: return TO_MUX( ADC_CHANNEL_IN9, 2 ); // Can also be ADC4
183 case D13: return TO_MUX( ADC_CHANNEL_IN10, 2 ); // Can also be ADC4
184 case D14: return TO_MUX( ADC_CHANNEL_IN11, 2 ); // Can also be ADC4
185 case E7: return TO_MUX( ADC_CHANNEL_IN13, 2 );
186 case E8: return TO_MUX( ADC_CHANNEL_IN6, 2 ); // Can also be ADC4
187 case E9: return TO_MUX( ADC_CHANNEL_IN2, 2 );
188 case E10: return TO_MUX( ADC_CHANNEL_IN14, 2 );
189 case E11: return TO_MUX( ADC_CHANNEL_IN15, 2 );
190 case E12: return TO_MUX( ADC_CHANNEL_IN16, 2 );
191 case E13: return TO_MUX( ADC_CHANNEL_IN3, 2 );
192 case E14: return TO_MUX( ADC_CHANNEL_IN1, 3 );
193 case E15: return TO_MUX( ADC_CHANNEL_IN2, 3 );
194 case F2: return TO_MUX( ADC_CHANNEL_IN10, 0 ); // Can also be ADC2
195 case F4: return TO_MUX( ADC_CHANNEL_IN5, 0 );
196#elif defined(STM32F4XX)
197 case A0: return TO_MUX( ADC_CHANNEL_IN0, 0 );
198 case A1: return TO_MUX( ADC_CHANNEL_IN1, 0 );
199 case A2: return TO_MUX( ADC_CHANNEL_IN2, 0 );
200 case A3: return TO_MUX( ADC_CHANNEL_IN3, 0 );
201 case A4: return TO_MUX( ADC_CHANNEL_IN4, 0 );
202 case A5: return TO_MUX( ADC_CHANNEL_IN5, 0 );
203 case A6: return TO_MUX( ADC_CHANNEL_IN6, 0 );
204 case A7: return TO_MUX( ADC_CHANNEL_IN7, 0 );
205 case B0: return TO_MUX( ADC_CHANNEL_IN8, 0 );
206 case B1: return TO_MUX( ADC_CHANNEL_IN9, 0 );
207 case C0: return TO_MUX( ADC_CHANNEL_IN10, 0 );
208 case C1: return TO_MUX( ADC_CHANNEL_IN11, 0 );
209 case C2: return TO_MUX( ADC_CHANNEL_IN12, 0 );
210 case C3: return TO_MUX( ADC_CHANNEL_IN13, 0 );
211 case C4: return TO_MUX( ADC_CHANNEL_IN14, 0 );
212 case C5: return TO_MUX( ADC_CHANNEL_IN15, 0 );
213# if STM32_ADC_USE_ADC3
214 case F3: return TO_MUX( ADC_CHANNEL_IN9, 2 );
215 case F4: return TO_MUX( ADC_CHANNEL_IN14, 2 );
216 case F5: return TO_MUX( ADC_CHANNEL_IN15, 2 );
217 case F6: return TO_MUX( ADC_CHANNEL_IN4, 2 );
218 case F7: return TO_MUX( ADC_CHANNEL_IN5, 2 );
219 case F8: return TO_MUX( ADC_CHANNEL_IN6, 2 );
220 case F9: return TO_MUX( ADC_CHANNEL_IN7, 2 );
221 case F10: return TO_MUX( ADC_CHANNEL_IN8, 2 );
222# endif
223#elif defined(STM32F1XX)
224 case A0: return TO_MUX( ADC_CHANNEL_IN0, 0 );
225 case A1: return TO_MUX( ADC_CHANNEL_IN1, 0 );
226 case A2: return TO_MUX( ADC_CHANNEL_IN2, 0 );
227 case A3: return TO_MUX( ADC_CHANNEL_IN3, 0 );
228 case A4: return TO_MUX( ADC_CHANNEL_IN4, 0 );
229 case A5: return TO_MUX( ADC_CHANNEL_IN5, 0 );
230 case A6: return TO_MUX( ADC_CHANNEL_IN6, 0 );
231 case A7: return TO_MUX( ADC_CHANNEL_IN7, 0 );
232 case B0: return TO_MUX( ADC_CHANNEL_IN8, 0 );
233 case B1: return TO_MUX( ADC_CHANNEL_IN9, 0 );
234 case C0: return TO_MUX( ADC_CHANNEL_IN10, 0 );
235 case C1: return TO_MUX( ADC_CHANNEL_IN11, 0 );
236 case C2: return TO_MUX( ADC_CHANNEL_IN12, 0 );
237 case C3: return TO_MUX( ADC_CHANNEL_IN13, 0 );
238 case C4: return TO_MUX( ADC_CHANNEL_IN14, 0 );
239 case C5: return TO_MUX( ADC_CHANNEL_IN15, 0 );
240 // STM32F103x[C-G] in 144-pin packages also have analog inputs on F6...F10, but they are on ADC3, and the
241 // ChibiOS ADC driver for STM32F1xx currently supports only ADC1, therefore these pins are not usable.
242#endif
243 }
244
245 // return an adc that would never be used so intToADCDriver will bail out
246 return TO_MUX(0, 0xFF);
247}
248// clang-format on
249
250static inline ADCDriver* intToADCDriver(uint8_t adcInt) {
251 switch (adcInt) {
252#if STM32_ADC_USE_ADC1
253 case 0:
254 return &ADCD1;
255#endif
256#if STM32_ADC_USE_ADC2
257 case 1:
258 return &ADCD2;
259#endif
260#if STM32_ADC_USE_ADC3
261 case 2:
262 return &ADCD3;
263#endif
264#if STM32_ADC_USE_ADC4
265 case 3:
266 return &ADCD4;
267#endif
268 }
269
270 return NULL;
271}
272
273static inline void manageAdcInitializationDriver(uint8_t adc, ADCDriver* adcDriver) {
274 if (!adcInitialized[adc]) {
275 adcStart(adcDriver, &adcCfg);
276 adcInitialized[adc] = true;
277 }
278}
279
280int16_t analogReadPin(pin_t pin) {
281 palSetLineMode(pin, PAL_MODE_INPUT_ANALOG);
282
283 return adc_read(pinToMux(pin));
284}
285
286int16_t analogReadPinAdc(pin_t pin, uint8_t adc) {
287 palSetLineMode(pin, PAL_MODE_INPUT_ANALOG);
288
289 adc_mux target = pinToMux(pin);
290 target.adc = adc;
291 return adc_read(target);
292}
293
294int16_t adc_read(adc_mux mux) {
295#if defined(USE_ADCV1)
296 // TODO: fix previous assumption of only 1 input...
297 adcConversionGroup.chselr = 1 << mux.input; /*no macro to convert N to ADC_CHSELR_CHSEL1*/
298#elif defined(USE_ADCV2)
299 adcConversionGroup.sqr3 = ADC_SQR3_SQ1_N(mux.input);
300#else
301 adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(mux.input);
302#endif
303
304 ADCDriver* targetDriver = intToADCDriver(mux.adc);
305 if (!targetDriver) {
306 return 0;
307 }
308
309 manageAdcInitializationDriver(mux.adc, targetDriver);
310 if (adcConvert(targetDriver, &adcConversionGroup, &sampleBuffer[0], ADC_BUFFER_DEPTH) != MSG_OK) {
311 return 0;
312 }
313
314#ifdef USE_ADCV2
315 // fake 12-bit -> N-bit scale
316 return (*sampleBuffer) >> (12 - ADC_RESOLUTION);
317#else
318 // already handled as part of adcConvert
319 return *sampleBuffer;
320#endif
321}
diff --git a/platforms/chibios/drivers/analog.h b/platforms/chibios/drivers/analog.h
new file mode 100644
index 000000000..e61c39426
--- /dev/null
+++ b/platforms/chibios/drivers/analog.h
@@ -0,0 +1,41 @@
1/* Copyright 2019 Drew Mills
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include <stdint.h>
20#include "quantum.h"
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26typedef struct {
27 uint16_t input;
28 uint8_t adc;
29} adc_mux;
30#define TO_MUX(i, a) \
31 (adc_mux) { i, a }
32
33int16_t analogReadPin(pin_t pin);
34int16_t analogReadPinAdc(pin_t pin, uint8_t adc);
35adc_mux pinToMux(pin_t pin);
36
37int16_t adc_read(adc_mux mux);
38
39#ifdef __cplusplus
40}
41#endif
diff --git a/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.c b/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.c
new file mode 100644
index 000000000..ed26cc714
--- /dev/null
+++ b/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.c
@@ -0,0 +1,96 @@
1/* Copyright 2020 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <stdint.h>
18#include <string.h>
19
20#include <hal.h>
21#include "eeprom_driver.h"
22#include "eeprom_stm32_L0_L1.h"
23
24#define EEPROM_BASE_ADDR 0x08080000
25#define EEPROM_ADDR(offset) (EEPROM_BASE_ADDR + (offset))
26#define EEPROM_PTR(offset) ((__IO uint8_t *)EEPROM_ADDR(offset))
27#define EEPROM_BYTE(location, offset) (*(EEPROM_PTR(((uint32_t)location) + ((uint32_t)offset))))
28
29#define BUFFER_BYTE(buffer, offset) (*(((uint8_t *)buffer) + offset))
30
31#define FLASH_PEKEY1 0x89ABCDEF
32#define FLASH_PEKEY2 0x02030405
33
34static inline void STM32_L0_L1_EEPROM_WaitNotBusy(void) {
35 while (FLASH->SR & FLASH_SR_BSY) {
36 __WFI();
37 }
38}
39
40static inline void STM32_L0_L1_EEPROM_Unlock(void) {
41 STM32_L0_L1_EEPROM_WaitNotBusy();
42 if (FLASH->PECR & FLASH_PECR_PELOCK) {
43 FLASH->PEKEYR = FLASH_PEKEY1;
44 FLASH->PEKEYR = FLASH_PEKEY2;
45 }
46}
47
48static inline void STM32_L0_L1_EEPROM_Lock(void) {
49 STM32_L0_L1_EEPROM_WaitNotBusy();
50 FLASH->PECR |= FLASH_PECR_PELOCK;
51}
52
53void eeprom_driver_init(void) {}
54
55void eeprom_driver_erase(void) {
56 STM32_L0_L1_EEPROM_Unlock();
57
58 for (size_t offset = 0; offset < STM32_ONBOARD_EEPROM_SIZE; offset += sizeof(uint32_t)) {
59 FLASH->PECR |= FLASH_PECR_ERASE | FLASH_PECR_DATA;
60
61 *(__IO uint32_t *)EEPROM_ADDR(offset) = (uint32_t)0;
62
63 STM32_L0_L1_EEPROM_WaitNotBusy();
64 FLASH->PECR &= ~(FLASH_PECR_ERASE | FLASH_PECR_DATA);
65 }
66
67 STM32_L0_L1_EEPROM_Lock();
68}
69
70void eeprom_read_block(void *buf, const void *addr, size_t len) {
71 for (size_t offset = 0; offset < len; ++offset) {
72 // Drop out if we've hit the limit of the EEPROM
73 if ((((uint32_t)addr) + offset) >= STM32_ONBOARD_EEPROM_SIZE) {
74 break;
75 }
76
77 STM32_L0_L1_EEPROM_WaitNotBusy();
78 BUFFER_BYTE(buf, offset) = EEPROM_BYTE(addr, offset);
79 }
80}
81
82void eeprom_write_block(const void *buf, void *addr, size_t len) {
83 STM32_L0_L1_EEPROM_Unlock();
84
85 for (size_t offset = 0; offset < len; ++offset) {
86 // Drop out if we've hit the limit of the EEPROM
87 if ((((uint32_t)addr) + offset) >= STM32_ONBOARD_EEPROM_SIZE) {
88 break;
89 }
90
91 STM32_L0_L1_EEPROM_WaitNotBusy();
92 EEPROM_BYTE(addr, offset) = BUFFER_BYTE(buf, offset);
93 }
94
95 STM32_L0_L1_EEPROM_Lock();
96}
diff --git a/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h b/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h
new file mode 100644
index 000000000..a35defca8
--- /dev/null
+++ b/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h
@@ -0,0 +1,33 @@
1/* Copyright 2020 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19/*
20 The size used by the STM32 L0/L1 EEPROM driver.
21*/
22#ifndef STM32_ONBOARD_EEPROM_SIZE
23# ifdef VIA_ENABLE
24# define STM32_ONBOARD_EEPROM_SIZE 1024
25# else
26# include "eeconfig.h"
27# define STM32_ONBOARD_EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO and EEPROM page sizing
28# endif
29#endif
30
31#if STM32_ONBOARD_EEPROM_SIZE > 128
32# pragma message("Please note: resetting EEPROM using an STM32L0/L1 device takes up to 1 second for every 1kB of internal EEPROM used.")
33#endif
diff --git a/platforms/chibios/drivers/i2c_master.c b/platforms/chibios/drivers/i2c_master.c
new file mode 100644
index 000000000..fc4bb2ab3
--- /dev/null
+++ b/platforms/chibios/drivers/i2c_master.c
@@ -0,0 +1,121 @@
1/* Copyright 2018 Jack Humbert
2 * Copyright 2018 Yiancar
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* This library is only valid for STM32 processors.
19 * This library follows the convention of the AVR i2c_master library.
20 * As a result addresses are expected to be already shifted (addr << 1).
21 * I2CD1 is the default driver which corresponds to pins B6 and B7. This
22 * can be changed.
23 * Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
24 * STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file. Pins B6 and B7 are used
25 * but using any other I2C pins should be trivial.
26 */
27#include "quantum.h"
28#include "i2c_master.h"
29#include <string.h>
30#include <hal.h>
31
32static uint8_t i2c_address;
33
34static const I2CConfig i2cconfig = {
35#if defined(USE_I2CV1_CONTRIB)
36 I2C1_CLOCK_SPEED,
37#elif defined(USE_I2CV1)
38 I2C1_OPMODE,
39 I2C1_CLOCK_SPEED,
40 I2C1_DUTY_CYCLE,
41#else
42 // This configures the I2C clock to 400khz assuming a 72Mhz clock
43 // For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
44 STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) | STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) | STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH) | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL), 0, 0
45#endif
46};
47
48static i2c_status_t chibios_to_qmk(const msg_t* status) {
49 switch (*status) {
50 case I2C_NO_ERROR:
51 return I2C_STATUS_SUCCESS;
52 case I2C_TIMEOUT:
53 return I2C_STATUS_TIMEOUT;
54 // I2C_BUS_ERROR, I2C_ARBITRATION_LOST, I2C_ACK_FAILURE, I2C_OVERRUN, I2C_PEC_ERROR, I2C_SMB_ALERT
55 default:
56 return I2C_STATUS_ERROR;
57 }
58}
59
60__attribute__((weak)) void i2c_init(void) {
61 static bool is_initialised = false;
62 if (!is_initialised) {
63 is_initialised = true;
64
65 // Try releasing special pins for a short time
66 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_INPUT);
67 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_INPUT);
68
69 chThdSleepMilliseconds(10);
70#if defined(USE_GPIOV1)
71 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, I2C1_SCL_PAL_MODE);
72 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, I2C1_SDA_PAL_MODE);
73#else
74 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
75 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
76#endif
77 }
78}
79
80i2c_status_t i2c_start(uint8_t address) {
81 i2c_address = address;
82 i2cStart(&I2C_DRIVER, &i2cconfig);
83 return I2C_STATUS_SUCCESS;
84}
85
86i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) {
87 i2c_address = address;
88 i2cStart(&I2C_DRIVER, &i2cconfig);
89 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, TIME_MS2I(timeout));
90 return chibios_to_qmk(&status);
91}
92
93i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) {
94 i2c_address = address;
95 i2cStart(&I2C_DRIVER, &i2cconfig);
96 msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, TIME_MS2I(timeout));
97 return chibios_to_qmk(&status);
98}
99
100i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) {
101 i2c_address = devaddr;
102 i2cStart(&I2C_DRIVER, &i2cconfig);
103
104 uint8_t complete_packet[length + 1];
105 for (uint8_t i = 0; i < length; i++) {
106 complete_packet[i + 1] = data[i];
107 }
108 complete_packet[0] = regaddr;
109
110 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, TIME_MS2I(timeout));
111 return chibios_to_qmk(&status);
112}
113
114i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
115 i2c_address = devaddr;
116 i2cStart(&I2C_DRIVER, &i2cconfig);
117 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), &regaddr, 1, data, length, TIME_MS2I(timeout));
118 return chibios_to_qmk(&status);
119}
120
121void i2c_stop(void) { i2cStop(&I2C_DRIVER); }
diff --git a/platforms/chibios/drivers/i2c_master.h b/platforms/chibios/drivers/i2c_master.h
new file mode 100644
index 000000000..c68109acb
--- /dev/null
+++ b/platforms/chibios/drivers/i2c_master.h
@@ -0,0 +1,113 @@
1/* Copyright 2018 Jack Humbert
2 * Copyright 2018 Yiancar
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* This library follows the convention of the AVR i2c_master library.
19 * As a result addresses are expected to be already shifted (addr << 1).
20 * I2CD1 is the default driver which corresponds to pins B6 and B7. This
21 * can be changed.
22 * Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
23 * STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file.
24 */
25#pragma once
26
27#include <ch.h>
28#include <hal.h>
29
30#ifdef I2C1_BANK
31# define I2C1_SCL_BANK I2C1_BANK
32# define I2C1_SDA_BANK I2C1_BANK
33#endif
34
35#ifndef I2C1_SCL_BANK
36# define I2C1_SCL_BANK GPIOB
37#endif
38
39#ifndef I2C1_SDA_BANK
40# define I2C1_SDA_BANK GPIOB
41#endif
42
43#ifndef I2C1_SCL
44# define I2C1_SCL 6
45#endif
46#ifndef I2C1_SDA
47# define I2C1_SDA 7
48#endif
49
50#ifdef USE_I2CV1
51# ifndef I2C1_OPMODE
52# define I2C1_OPMODE OPMODE_I2C
53# endif
54# ifndef I2C1_CLOCK_SPEED
55# define I2C1_CLOCK_SPEED 100000 /* 400000 */
56# endif
57# ifndef I2C1_DUTY_CYCLE
58# define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */
59# endif
60#else
61// The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock
62// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
63# ifndef I2C1_TIMINGR_PRESC
64# define I2C1_TIMINGR_PRESC 0U
65# endif
66# ifndef I2C1_TIMINGR_SCLDEL
67# define I2C1_TIMINGR_SCLDEL 7U
68# endif
69# ifndef I2C1_TIMINGR_SDADEL
70# define I2C1_TIMINGR_SDADEL 0U
71# endif
72# ifndef I2C1_TIMINGR_SCLH
73# define I2C1_TIMINGR_SCLH 38U
74# endif
75# ifndef I2C1_TIMINGR_SCLL
76# define I2C1_TIMINGR_SCLL 129U
77# endif
78#endif
79
80#ifndef I2C_DRIVER
81# define I2C_DRIVER I2CD1
82#endif
83
84#ifdef USE_GPIOV1
85# ifndef I2C1_SCL_PAL_MODE
86# define I2C1_SCL_PAL_MODE PAL_MODE_STM32_ALTERNATE_OPENDRAIN
87# endif
88# ifndef I2C1_SDA_PAL_MODE
89# define I2C1_SDA_PAL_MODE PAL_MODE_STM32_ALTERNATE_OPENDRAIN
90# endif
91#else
92// The default PAL alternate modes are used to signal that the pins are used for I2C
93# ifndef I2C1_SCL_PAL_MODE
94# define I2C1_SCL_PAL_MODE 4
95# endif
96# ifndef I2C1_SDA_PAL_MODE
97# define I2C1_SDA_PAL_MODE 4
98# endif
99#endif
100
101typedef int16_t i2c_status_t;
102
103#define I2C_STATUS_SUCCESS (0)
104#define I2C_STATUS_ERROR (-1)
105#define I2C_STATUS_TIMEOUT (-2)
106
107void i2c_init(void);
108i2c_status_t i2c_start(uint8_t address);
109i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
110i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
111i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
112i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
113void i2c_stop(void);
diff --git a/platforms/chibios/drivers/serial.c b/platforms/chibios/drivers/serial.c
new file mode 100644
index 000000000..f54fbcee4
--- /dev/null
+++ b/platforms/chibios/drivers/serial.c
@@ -0,0 +1,278 @@
1/*
2 * WARNING: be careful changing this code, it is very timing dependent
3 */
4
5#include "quantum.h"
6#include "serial.h"
7#include "wait.h"
8
9#include <hal.h>
10
11// TODO: resolve/remove build warnings
12#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT) && defined(PROTOCOL_CHIBIOS) && defined(WS2812_DRIVER_BITBANG)
13# warning "RGBLED_SPLIT not supported with bitbang WS2812 driver"
14#endif
15
16// default wait implementation cannot be called within interrupt
17// this method seems to be more accurate than GPT timers
18#if PORT_SUPPORTS_RT == FALSE
19# error "chSysPolledDelayX method not supported on this platform"
20#else
21# undef wait_us
22# define wait_us(x) chSysPolledDelayX(US2RTC(STM32_SYSCLK, x))
23#endif
24
25#ifndef SELECT_SOFT_SERIAL_SPEED
26# define SELECT_SOFT_SERIAL_SPEED 1
27// TODO: correct speeds...
28// 0: about 189kbps (Experimental only)
29// 1: about 137kbps (default)
30// 2: about 75kbps
31// 3: about 39kbps
32// 4: about 26kbps
33// 5: about 20kbps
34#endif
35
36// Serial pulse period in microseconds. At the moment, going lower than 12 causes communication failure
37#if SELECT_SOFT_SERIAL_SPEED == 0
38# define SERIAL_DELAY 12
39#elif SELECT_SOFT_SERIAL_SPEED == 1
40# define SERIAL_DELAY 16
41#elif SELECT_SOFT_SERIAL_SPEED == 2
42# define SERIAL_DELAY 24
43#elif SELECT_SOFT_SERIAL_SPEED == 3
44# define SERIAL_DELAY 32
45#elif SELECT_SOFT_SERIAL_SPEED == 4
46# define SERIAL_DELAY 48
47#elif SELECT_SOFT_SERIAL_SPEED == 5
48# define SERIAL_DELAY 64
49#else
50# error invalid SELECT_SOFT_SERIAL_SPEED value
51#endif
52
53inline static void serial_delay(void) { wait_us(SERIAL_DELAY); }
54inline static void serial_delay_half(void) { wait_us(SERIAL_DELAY / 2); }
55inline static void serial_delay_blip(void) { wait_us(1); }
56inline static void serial_output(void) { setPinOutput(SOFT_SERIAL_PIN); }
57inline static void serial_input(void) { setPinInputHigh(SOFT_SERIAL_PIN); }
58inline static bool serial_read_pin(void) { return !!readPin(SOFT_SERIAL_PIN); }
59inline static void serial_low(void) { writePinLow(SOFT_SERIAL_PIN); }
60inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); }
61
62void interrupt_handler(void *arg);
63
64// Use thread + palWaitLineTimeout instead of palSetLineCallback
65// - Methods like setPinOutput and palEnableLineEvent/palDisableLineEvent
66// cause the interrupt to lock up, which would limit to only receiving data...
67static THD_WORKING_AREA(waThread1, 128);
68static THD_FUNCTION(Thread1, arg) {
69 (void)arg;
70 chRegSetThreadName("blinker");
71 while (true) {
72 palWaitLineTimeout(SOFT_SERIAL_PIN, TIME_INFINITE);
73 interrupt_handler(NULL);
74 }
75}
76
77void soft_serial_initiator_init(void) {
78 serial_output();
79 serial_high();
80}
81
82void soft_serial_target_init(void) {
83 serial_input();
84
85 palEnablePadEvent(PAL_PORT(SOFT_SERIAL_PIN), PAL_PAD(SOFT_SERIAL_PIN), PAL_EVENT_MODE_FALLING_EDGE);
86 chThdCreateStatic(waThread1, sizeof(waThread1), HIGHPRIO, Thread1, NULL);
87}
88
89// Used by the master to synchronize timing with the slave.
90static void __attribute__((noinline)) sync_recv(void) {
91 serial_input();
92 // This shouldn't hang if the slave disconnects because the
93 // serial line will float to high if the slave does disconnect.
94 while (!serial_read_pin()) {
95 }
96
97 serial_delay();
98}
99
100// Used by the slave to send a synchronization signal to the master.
101static void __attribute__((noinline)) sync_send(void) {
102 serial_output();
103
104 serial_low();
105 serial_delay();
106
107 serial_high();
108}
109
110// Reads a byte from the serial line
111static uint8_t __attribute__((noinline)) serial_read_byte(void) {
112 uint8_t byte = 0;
113 serial_input();
114 for (uint8_t i = 0; i < 8; ++i) {
115 byte = (byte << 1) | serial_read_pin();
116 serial_delay();
117 }
118
119 return byte;
120}
121
122// Sends a byte with MSB ordering
123static void __attribute__((noinline)) serial_write_byte(uint8_t data) {
124 uint8_t b = 8;
125 serial_output();
126 while (b--) {
127 if (data & (1 << b)) {
128 serial_high();
129 } else {
130 serial_low();
131 }
132 serial_delay();
133 }
134}
135
136// interrupt handle to be used by the slave device
137void interrupt_handler(void *arg) {
138 chSysLockFromISR();
139
140 sync_send();
141
142 // read mid pulses
143 serial_delay_blip();
144
145 uint8_t checksum_computed = 0;
146 int sstd_index = 0;
147
148 sstd_index = serial_read_byte();
149 sync_send();
150
151 split_transaction_desc_t *trans = &split_transaction_table[sstd_index];
152 for (int i = 0; i < trans->initiator2target_buffer_size; ++i) {
153 split_trans_initiator2target_buffer(trans)[i] = serial_read_byte();
154 sync_send();
155 checksum_computed += split_trans_initiator2target_buffer(trans)[i];
156 }
157 checksum_computed ^= 7;
158 uint8_t checksum_received = serial_read_byte();
159 sync_send();
160
161 // wait for the sync to finish sending
162 serial_delay();
163
164 // Allow any slave processing to occur
165 if (trans->slave_callback) {
166 trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->target2initiator_buffer_size, split_trans_target2initiator_buffer(trans));
167 }
168
169 uint8_t checksum = 0;
170 for (int i = 0; i < trans->target2initiator_buffer_size; ++i) {
171 serial_write_byte(split_trans_target2initiator_buffer(trans)[i]);
172 sync_send();
173 serial_delay_half();
174 checksum += split_trans_target2initiator_buffer(trans)[i];
175 }
176 serial_write_byte(checksum ^ 7);
177 sync_send();
178
179 // wait for the sync to finish sending
180 serial_delay();
181
182 *trans->status = (checksum_computed == checksum_received) ? TRANSACTION_ACCEPTED : TRANSACTION_DATA_ERROR;
183
184 // end transaction
185 serial_input();
186
187 // TODO: remove extra delay between transactions
188 serial_delay();
189
190 chSysUnlockFromISR();
191}
192
193/////////
194// start transaction by initiator
195//
196// int soft_serial_transaction(int sstd_index)
197//
198// Returns:
199// TRANSACTION_END
200// TRANSACTION_NO_RESPONSE
201// TRANSACTION_DATA_ERROR
202// this code is very time dependent, so we need to disable interrupts
203int soft_serial_transaction(int sstd_index) {
204 if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR;
205 split_transaction_desc_t *trans = &split_transaction_table[sstd_index];
206 if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered
207
208 // TODO: remove extra delay between transactions
209 serial_delay();
210
211 // this code is very time dependent, so we need to disable interrupts
212 chSysLock();
213
214 // signal to the slave that we want to start a transaction
215 serial_output();
216 serial_low();
217 serial_delay_blip();
218
219 // wait for the slaves response
220 serial_input();
221 serial_high();
222 serial_delay();
223
224 // check if the slave is present
225 if (serial_read_pin()) {
226 // slave failed to pull the line low, assume not present
227 dprintf("serial::NO_RESPONSE\n");
228 chSysUnlock();
229 return TRANSACTION_NO_RESPONSE;
230 }
231
232 // if the slave is present syncronize with it
233
234 uint8_t checksum = 0;
235 // send data to the slave
236 serial_write_byte(sstd_index); // first chunk is transaction id
237 sync_recv();
238
239 for (int i = 0; i < trans->initiator2target_buffer_size; ++i) {
240 serial_write_byte(split_trans_initiator2target_buffer(trans)[i]);
241 sync_recv();
242 checksum += split_trans_initiator2target_buffer(trans)[i];
243 }
244 serial_write_byte(checksum ^ 7);
245 sync_recv();
246
247 serial_delay();
248 serial_delay(); // read mid pulses
249
250 // receive data from the slave
251 uint8_t checksum_computed = 0;
252 for (int i = 0; i < trans->target2initiator_buffer_size; ++i) {
253 split_trans_target2initiator_buffer(trans)[i] = serial_read_byte();
254 sync_recv();
255 checksum_computed += split_trans_target2initiator_buffer(trans)[i];
256 }
257 checksum_computed ^= 7;
258 uint8_t checksum_received = serial_read_byte();
259
260 sync_recv();
261 serial_delay();
262
263 if ((checksum_computed) != (checksum_received)) {
264 dprintf("serial::FAIL[%u,%u,%u]\n", checksum_computed, checksum_received, sstd_index);
265 serial_output();
266 serial_high();
267
268 chSysUnlock();
269 return TRANSACTION_DATA_ERROR;
270 }
271
272 // always, release the line when not in use
273 serial_high();
274 serial_output();
275
276 chSysUnlock();
277 return TRANSACTION_END;
278}
diff --git a/platforms/chibios/drivers/serial_usart.c b/platforms/chibios/drivers/serial_usart.c
new file mode 100644
index 000000000..ea4473791
--- /dev/null
+++ b/platforms/chibios/drivers/serial_usart.c
@@ -0,0 +1,318 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "serial_usart.h"
18
19#if defined(SERIAL_USART_CONFIG)
20static SerialConfig serial_config = SERIAL_USART_CONFIG;
21#else
22static SerialConfig serial_config = {
23 .speed = (SERIAL_USART_SPEED), /* speed - mandatory */
24 .cr1 = (SERIAL_USART_CR1),
25 .cr2 = (SERIAL_USART_CR2),
26# if !defined(SERIAL_USART_FULL_DUPLEX)
27 .cr3 = ((SERIAL_USART_CR3) | USART_CR3_HDSEL) /* activate half-duplex mode */
28# else
29 .cr3 = (SERIAL_USART_CR3)
30# endif
31};
32#endif
33
34static SerialDriver* serial_driver = &SERIAL_USART_DRIVER;
35
36static inline bool react_to_transactions(void);
37static inline bool __attribute__((nonnull)) receive(uint8_t* destination, const size_t size);
38static inline bool __attribute__((nonnull)) send(const uint8_t* source, const size_t size);
39static inline int initiate_transaction(uint8_t sstd_index);
40static inline void usart_clear(void);
41
42/**
43 * @brief Clear the receive input queue.
44 */
45static inline void usart_clear(void) {
46 osalSysLock();
47 bool volatile queue_not_empty = !iqIsEmptyI(&serial_driver->iqueue);
48 osalSysUnlock();
49
50 while (queue_not_empty) {
51 osalSysLock();
52 /* Hard reset the input queue. */
53 iqResetI(&serial_driver->iqueue);
54 osalSysUnlock();
55 /* Allow pending interrupts to preempt.
56 * Do not merge the lock/unlock blocks into one
57 * or the code will not work properly.
58 * The empty read adds a tiny amount of delay. */
59 (void)queue_not_empty;
60 osalSysLock();
61 queue_not_empty = !iqIsEmptyI(&serial_driver->iqueue);
62 osalSysUnlock();
63 }
64}
65
66/**
67 * @brief Blocking send of buffer with timeout.
68 *
69 * @return true Send success.
70 * @return false Send failed.
71 */
72static inline bool send(const uint8_t* source, const size_t size) {
73 bool success = (size_t)sdWriteTimeout(serial_driver, source, size, TIME_MS2I(SERIAL_USART_TIMEOUT)) == size;
74
75#if !defined(SERIAL_USART_FULL_DUPLEX)
76 if (success) {
77 /* Half duplex fills the input queue with the data we wrote - just throw it away.
78 Under the right circumstances (e.g. bad cables paired with high baud rates)
79 less bytes can be present in the input queue, therefore a timeout is needed. */
80 uint8_t dump[size];
81 return receive(dump, size);
82 }
83#endif
84
85 return success;
86}
87
88/**
89 * @brief Blocking receive of size * bytes with timeout.
90 *
91 * @return true Receive success.
92 * @return false Receive failed.
93 */
94static inline bool receive(uint8_t* destination, const size_t size) {
95 bool success = (size_t)sdReadTimeout(serial_driver, destination, size, TIME_MS2I(SERIAL_USART_TIMEOUT)) == size;
96 return success;
97}
98
99#if !defined(SERIAL_USART_FULL_DUPLEX)
100
101/**
102 * @brief Initiate pins for USART peripheral. Half-duplex configuration.
103 */
104__attribute__((weak)) void usart_init(void) {
105# if defined(MCU_STM32)
106# if defined(USE_GPIOV1)
107 palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
108# else
109 palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE(SERIAL_USART_TX_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
110# endif
111
112# if defined(USART_REMAP)
113 USART_REMAP;
114# endif
115# else
116# pragma message "usart_init: MCU Familiy not supported by default, please supply your own init code by implementing usart_init() in your keyboard files."
117# endif
118}
119
120#else
121
122/**
123 * @brief Initiate pins for USART peripheral. Full-duplex configuration.
124 */
125__attribute__((weak)) void usart_init(void) {
126# if defined(MCU_STM32)
127# if defined(USE_GPIOV1)
128 palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
129 palSetLineMode(SERIAL_USART_RX_PIN, PAL_MODE_INPUT);
130# else
131 palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE(SERIAL_USART_TX_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
132 palSetLineMode(SERIAL_USART_RX_PIN, PAL_MODE_ALTERNATE(SERIAL_USART_RX_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
133# endif
134
135# if defined(USART_REMAP)
136 USART_REMAP;
137# endif
138# else
139# pragma message "usart_init: MCU Familiy not supported by default, please supply your own init code by implementing usart_init() in your keyboard files."
140# endif
141}
142
143#endif
144
145/**
146 * @brief Overridable master specific initializations.
147 */
148__attribute__((weak, nonnull)) void usart_master_init(SerialDriver** driver) {
149 (void)driver;
150 usart_init();
151}
152
153/**
154 * @brief Overridable slave specific initializations.
155 */
156__attribute__((weak, nonnull)) void usart_slave_init(SerialDriver** driver) {
157 (void)driver;
158 usart_init();
159}
160
161/**
162 * @brief This thread runs on the slave and responds to transactions initiated
163 * by the master.
164 */
165static THD_WORKING_AREA(waSlaveThread, 1024);
166static THD_FUNCTION(SlaveThread, arg) {
167 (void)arg;
168 chRegSetThreadName("usart_tx_rx");
169
170 while (true) {
171 if (!react_to_transactions()) {
172 /* Clear the receive queue, to start with a clean slate.
173 * Parts of failed transactions or spurious bytes could still be in it. */
174 usart_clear();
175 }
176 }
177}
178
179/**
180 * @brief Slave specific initializations.
181 */
182void soft_serial_target_init(void) {
183 usart_slave_init(&serial_driver);
184
185 sdStart(serial_driver, &serial_config);
186
187 /* Start transport thread. */
188 chThdCreateStatic(waSlaveThread, sizeof(waSlaveThread), HIGHPRIO, SlaveThread, NULL);
189}
190
191/**
192 * @brief React to transactions started by the master.
193 */
194static inline bool react_to_transactions(void) {
195 /* Wait until there is a transaction for us. */
196 uint8_t sstd_index = (uint8_t)sdGet(serial_driver);
197
198 /* Sanity check that we are actually responding to a valid transaction. */
199 if (sstd_index >= NUM_TOTAL_TRANSACTIONS) {
200 return false;
201 }
202
203 split_transaction_desc_t* trans = &split_transaction_table[sstd_index];
204
205 /* Send back the handshake which is XORed as a simple checksum,
206 to signal that the slave is ready to receive possible transaction buffers */
207 sstd_index ^= HANDSHAKE_MAGIC;
208 if (!send(&sstd_index, sizeof(sstd_index))) {
209 *trans->status = TRANSACTION_DATA_ERROR;
210 return false;
211 }
212
213 /* Receive transaction buffer from the master. If this transaction requires it.*/
214 if (trans->initiator2target_buffer_size) {
215 if (!receive(split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) {
216 *trans->status = TRANSACTION_DATA_ERROR;
217 return false;
218 }
219 }
220
221 /* Allow any slave processing to occur. */
222 if (trans->slave_callback) {
223 trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size, split_trans_target2initiator_buffer(trans));
224 }
225
226 /* Send transaction buffer to the master. If this transaction requires it. */
227 if (trans->target2initiator_buffer_size) {
228 if (!send(split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) {
229 *trans->status = TRANSACTION_DATA_ERROR;
230 return false;
231 }
232 }
233
234 *trans->status = TRANSACTION_ACCEPTED;
235 return true;
236}
237
238/**
239 * @brief Master specific initializations.
240 */
241void soft_serial_initiator_init(void) {
242 usart_master_init(&serial_driver);
243
244#if defined(MCU_STM32) && defined(SERIAL_USART_PIN_SWAP)
245 serial_config.cr2 |= USART_CR2_SWAP; // master has swapped TX/RX pins
246#endif
247
248 sdStart(serial_driver, &serial_config);
249}
250
251/**
252 * @brief Start transaction from the master half to the slave half.
253 *
254 * @param index Transaction Table index of the transaction to start.
255 * @return int TRANSACTION_NO_RESPONSE in case of Timeout.
256 * TRANSACTION_TYPE_ERROR in case of invalid transaction index.
257 * TRANSACTION_END in case of success.
258 */
259int soft_serial_transaction(int index) {
260 /* Clear the receive queue, to start with a clean slate.
261 * Parts of failed transactions or spurious bytes could still be in it. */
262 usart_clear();
263 return initiate_transaction((uint8_t)index);
264}
265
266/**
267 * @brief Initiate transaction to slave half.
268 */
269static inline int initiate_transaction(uint8_t sstd_index) {
270 /* Sanity check that we are actually starting a valid transaction. */
271 if (sstd_index >= NUM_TOTAL_TRANSACTIONS) {
272 dprintln("USART: Illegal transaction Id.");
273 return TRANSACTION_TYPE_ERROR;
274 }
275
276 split_transaction_desc_t* trans = &split_transaction_table[sstd_index];
277
278 /* Transaction is not registered. Abort. */
279 if (!trans->status) {
280 dprintln("USART: Transaction not registered.");
281 return TRANSACTION_TYPE_ERROR;
282 }
283
284 /* Send transaction table index to the slave, which doubles as basic handshake token. */
285 if (!send(&sstd_index, sizeof(sstd_index))) {
286 dprintln("USART: Send Handshake failed.");
287 return TRANSACTION_TYPE_ERROR;
288 }
289
290 uint8_t sstd_index_shake = 0xFF;
291
292 /* Which we always read back first so that we can error out correctly.
293 * - due to the half duplex limitations on return codes, we always have to read *something*.
294 * - without the read, write only transactions *always* succeed, even during the boot process where the slave is not ready.
295 */
296 if (!receive(&sstd_index_shake, sizeof(sstd_index_shake)) || (sstd_index_shake != (sstd_index ^ HANDSHAKE_MAGIC))) {
297 dprintln("USART: Handshake failed.");
298 return TRANSACTION_NO_RESPONSE;
299 }
300
301 /* Send transaction buffer to the slave. If this transaction requires it. */
302 if (trans->initiator2target_buffer_size) {
303 if (!send(split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) {
304 dprintln("USART: Send failed.");
305 return TRANSACTION_NO_RESPONSE;
306 }
307 }
308
309 /* Receive transaction buffer from the slave. If this transaction requires it. */
310 if (trans->target2initiator_buffer_size) {
311 if (!receive(split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) {
312 dprintln("USART: Receive failed.");
313 return TRANSACTION_NO_RESPONSE;
314 }
315 }
316
317 return TRANSACTION_END;
318}
diff --git a/platforms/chibios/drivers/serial_usart.h b/platforms/chibios/drivers/serial_usart.h
new file mode 100644
index 000000000..7b135b31e
--- /dev/null
+++ b/platforms/chibios/drivers/serial_usart.h
@@ -0,0 +1,116 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include "quantum.h"
20#include "serial.h"
21#include "printf.h"
22
23#include <ch.h>
24#include <hal.h>
25
26#if !defined(SERIAL_USART_DRIVER)
27# define SERIAL_USART_DRIVER SD1
28#endif
29
30#if !defined(USE_GPIOV1)
31/* The default PAL alternate modes are used to signal that the pins are used for USART. */
32# if !defined(SERIAL_USART_TX_PAL_MODE)
33# define SERIAL_USART_TX_PAL_MODE 7
34# endif
35# if !defined(SERIAL_USART_RX_PAL_MODE)
36# define SERIAL_USART_RX_PAL_MODE 7
37# endif
38#endif
39
40#if defined(SOFT_SERIAL_PIN)
41# define SERIAL_USART_TX_PIN SOFT_SERIAL_PIN
42#endif
43
44#if !defined(SERIAL_USART_TX_PIN)
45# define SERIAL_USART_TX_PIN A9
46#endif
47
48#if !defined(SERIAL_USART_RX_PIN)
49# define SERIAL_USART_RX_PIN A10
50#endif
51
52#if !defined(USART_CR1_M0)
53# define USART_CR1_M0 USART_CR1_M // some platforms (f1xx) dont have this so
54#endif
55
56#if !defined(SERIAL_USART_CR1)
57# define SERIAL_USART_CR1 (USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0) // parity enable, odd parity, 9 bit length
58#endif
59
60#if !defined(SERIAL_USART_CR2)
61# define SERIAL_USART_CR2 (USART_CR2_STOP_1) // 2 stop bits
62#endif
63
64#if !defined(SERIAL_USART_CR3)
65# define SERIAL_USART_CR3 0
66#endif
67
68#if defined(USART1_REMAP)
69# define USART_REMAP \
70 do { \
71 (AFIO->MAPR |= AFIO_MAPR_USART1_REMAP); \
72 } while (0)
73#elif defined(USART2_REMAP)
74# define USART_REMAP \
75 do { \
76 (AFIO->MAPR |= AFIO_MAPR_USART2_REMAP); \
77 } while (0)
78#elif defined(USART3_PARTIALREMAP)
79# define USART_REMAP \
80 do { \
81 (AFIO->MAPR |= AFIO_MAPR_USART3_REMAP_PARTIALREMAP); \
82 } while (0)
83#elif defined(USART3_FULLREMAP)
84# define USART_REMAP \
85 do { \
86 (AFIO->MAPR |= AFIO_MAPR_USART3_REMAP_FULLREMAP); \
87 } while (0)
88#endif
89
90#if !defined(SELECT_SOFT_SERIAL_SPEED)
91# define SELECT_SOFT_SERIAL_SPEED 1
92#endif
93
94#if defined(SERIAL_USART_SPEED)
95// Allow advanced users to directly set SERIAL_USART_SPEED
96#elif SELECT_SOFT_SERIAL_SPEED == 0
97# define SERIAL_USART_SPEED 460800
98#elif SELECT_SOFT_SERIAL_SPEED == 1
99# define SERIAL_USART_SPEED 230400
100#elif SELECT_SOFT_SERIAL_SPEED == 2
101# define SERIAL_USART_SPEED 115200
102#elif SELECT_SOFT_SERIAL_SPEED == 3
103# define SERIAL_USART_SPEED 57600
104#elif SELECT_SOFT_SERIAL_SPEED == 4
105# define SERIAL_USART_SPEED 38400
106#elif SELECT_SOFT_SERIAL_SPEED == 5
107# define SERIAL_USART_SPEED 19200
108#else
109# error invalid SELECT_SOFT_SERIAL_SPEED value
110#endif
111
112#if !defined(SERIAL_USART_TIMEOUT)
113# define SERIAL_USART_TIMEOUT 20
114#endif
115
116#define HANDSHAKE_MAGIC 7
diff --git a/platforms/chibios/drivers/spi_master.c b/platforms/chibios/drivers/spi_master.c
new file mode 100644
index 000000000..28ddcbb2b
--- /dev/null
+++ b/platforms/chibios/drivers/spi_master.c
@@ -0,0 +1,202 @@
1/* Copyright 2020 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <https://www.gnu.org/licenses/>.
15 */
16
17#include "spi_master.h"
18
19#include "timer.h"
20
21static pin_t currentSlavePin = NO_PIN;
22
23#if defined(K20x) || defined(KL2x)
24static SPIConfig spiConfig = {NULL, 0, 0, 0};
25#else
26static SPIConfig spiConfig = {false, NULL, 0, 0, 0, 0};
27#endif
28
29__attribute__((weak)) void spi_init(void) {
30 static bool is_initialised = false;
31 if (!is_initialised) {
32 is_initialised = true;
33
34 // Try releasing special pins for a short time
35 setPinInput(SPI_SCK_PIN);
36 setPinInput(SPI_MOSI_PIN);
37 setPinInput(SPI_MISO_PIN);
38
39 chThdSleepMilliseconds(10);
40#if defined(USE_GPIOV1)
41 palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), SPI_SCK_PAL_MODE);
42 palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), SPI_MOSI_PAL_MODE);
43 palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), SPI_MISO_PAL_MODE);
44#else
45 palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_ALTERNATE(SPI_SCK_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
46 palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_ALTERNATE(SPI_MOSI_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
47 palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_MODE_ALTERNATE(SPI_MISO_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
48#endif
49 }
50}
51
52bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
53 if (currentSlavePin != NO_PIN || slavePin == NO_PIN) {
54 return false;
55 }
56
57 uint16_t roundedDivisor = 2;
58 while (roundedDivisor < divisor) {
59 roundedDivisor <<= 1;
60 }
61
62 if (roundedDivisor < 2 || roundedDivisor > 256) {
63 return false;
64 }
65
66#if defined(K20x) || defined(KL2x)
67 spiConfig.tar0 = SPIx_CTARn_FMSZ(7) | SPIx_CTARn_ASC(1);
68
69 if (lsbFirst) {
70 spiConfig.tar0 |= SPIx_CTARn_LSBFE;
71 }
72
73 switch (mode) {
74 case 0:
75 break;
76 case 1:
77 spiConfig.tar0 |= SPIx_CTARn_CPHA;
78 break;
79 case 2:
80 spiConfig.tar0 |= SPIx_CTARn_CPOL;
81 break;
82 case 3:
83 spiConfig.tar0 |= SPIx_CTARn_CPHA | SPIx_CTARn_CPOL;
84 break;
85 }
86
87 switch (roundedDivisor) {
88 case 2:
89 spiConfig.tar0 |= SPIx_CTARn_BR(0);
90 break;
91 case 4:
92 spiConfig.tar0 |= SPIx_CTARn_BR(1);
93 break;
94 case 8:
95 spiConfig.tar0 |= SPIx_CTARn_BR(3);
96 break;
97 case 16:
98 spiConfig.tar0 |= SPIx_CTARn_BR(4);
99 break;
100 case 32:
101 spiConfig.tar0 |= SPIx_CTARn_BR(5);
102 break;
103 case 64:
104 spiConfig.tar0 |= SPIx_CTARn_BR(6);
105 break;
106 case 128:
107 spiConfig.tar0 |= SPIx_CTARn_BR(7);
108 break;
109 case 256:
110 spiConfig.tar0 |= SPIx_CTARn_BR(8);
111 break;
112 }
113#else
114 spiConfig.cr1 = 0;
115
116 if (lsbFirst) {
117 spiConfig.cr1 |= SPI_CR1_LSBFIRST;
118 }
119
120 switch (mode) {
121 case 0:
122 break;
123 case 1:
124 spiConfig.cr1 |= SPI_CR1_CPHA;
125 break;
126 case 2:
127 spiConfig.cr1 |= SPI_CR1_CPOL;
128 break;
129 case 3:
130 spiConfig.cr1 |= SPI_CR1_CPHA | SPI_CR1_CPOL;
131 break;
132 }
133
134 switch (roundedDivisor) {
135 case 2:
136 break;
137 case 4:
138 spiConfig.cr1 |= SPI_CR1_BR_0;
139 break;
140 case 8:
141 spiConfig.cr1 |= SPI_CR1_BR_1;
142 break;
143 case 16:
144 spiConfig.cr1 |= SPI_CR1_BR_1 | SPI_CR1_BR_0;
145 break;
146 case 32:
147 spiConfig.cr1 |= SPI_CR1_BR_2;
148 break;
149 case 64:
150 spiConfig.cr1 |= SPI_CR1_BR_2 | SPI_CR1_BR_0;
151 break;
152 case 128:
153 spiConfig.cr1 |= SPI_CR1_BR_2 | SPI_CR1_BR_1;
154 break;
155 case 256:
156 spiConfig.cr1 |= SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0;
157 break;
158 }
159#endif
160
161 currentSlavePin = slavePin;
162 spiConfig.ssport = PAL_PORT(slavePin);
163 spiConfig.sspad = PAL_PAD(slavePin);
164
165 setPinOutput(slavePin);
166 spiStart(&SPI_DRIVER, &spiConfig);
167 spiSelect(&SPI_DRIVER);
168
169 return true;
170}
171
172spi_status_t spi_write(uint8_t data) {
173 uint8_t rxData;
174 spiExchange(&SPI_DRIVER, 1, &data, &rxData);
175
176 return rxData;
177}
178
179spi_status_t spi_read(void) {
180 uint8_t data = 0;
181 spiReceive(&SPI_DRIVER, 1, &data);
182
183 return data;
184}
185
186spi_status_t spi_transmit(const uint8_t *data, uint16_t length) {
187 spiSend(&SPI_DRIVER, length, data);
188 return SPI_STATUS_SUCCESS;
189}
190
191spi_status_t spi_receive(uint8_t *data, uint16_t length) {
192 spiReceive(&SPI_DRIVER, length, data);
193 return SPI_STATUS_SUCCESS;
194}
195
196void spi_stop(void) {
197 if (currentSlavePin != NO_PIN) {
198 spiUnselect(&SPI_DRIVER);
199 spiStop(&SPI_DRIVER);
200 currentSlavePin = NO_PIN;
201 }
202}
diff --git a/platforms/chibios/drivers/spi_master.h b/platforms/chibios/drivers/spi_master.h
new file mode 100644
index 000000000..b5a6ef143
--- /dev/null
+++ b/platforms/chibios/drivers/spi_master.h
@@ -0,0 +1,93 @@
1/* Copyright 2020 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <https://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include <ch.h>
20#include <hal.h>
21#include <stdbool.h>
22
23#include "gpio.h"
24#include "chibios_config.h"
25
26#ifndef SPI_DRIVER
27# define SPI_DRIVER SPID2
28#endif
29
30#ifndef SPI_SCK_PIN
31# define SPI_SCK_PIN B13
32#endif
33
34#ifndef SPI_SCK_PAL_MODE
35# if defined(USE_GPIOV1)
36# define SPI_SCK_PAL_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
37# else
38# define SPI_SCK_PAL_MODE 5
39# endif
40#endif
41
42#ifndef SPI_MOSI_PIN
43# define SPI_MOSI_PIN B15
44#endif
45
46#ifndef SPI_MOSI_PAL_MODE
47# if defined(USE_GPIOV1)
48# define SPI_MOSI_PAL_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
49# else
50# define SPI_MOSI_PAL_MODE 5
51# endif
52#endif
53
54#ifndef SPI_MISO_PIN
55# define SPI_MISO_PIN B14
56#endif
57
58#ifndef SPI_MISO_PAL_MODE
59# if defined(USE_GPIOV1)
60# define SPI_MISO_PAL_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
61# else
62# define SPI_MISO_PAL_MODE 5
63# endif
64#endif
65
66typedef int16_t spi_status_t;
67
68#define SPI_STATUS_SUCCESS (0)
69#define SPI_STATUS_ERROR (-1)
70#define SPI_STATUS_TIMEOUT (-2)
71
72#define SPI_TIMEOUT_IMMEDIATE (0)
73#define SPI_TIMEOUT_INFINITE (0xFFFF)
74
75#ifdef __cplusplus
76extern "C" {
77#endif
78void spi_init(void);
79
80bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
81
82spi_status_t spi_write(uint8_t data);
83
84spi_status_t spi_read(void);
85
86spi_status_t spi_transmit(const uint8_t *data, uint16_t length);
87
88spi_status_t spi_receive(uint8_t *data, uint16_t length);
89
90void spi_stop(void);
91#ifdef __cplusplus
92}
93#endif
diff --git a/platforms/chibios/drivers/uart.c b/platforms/chibios/drivers/uart.c
new file mode 100644
index 000000000..030335b34
--- /dev/null
+++ b/platforms/chibios/drivers/uart.c
@@ -0,0 +1,50 @@
1/* Copyright 2021
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <https://www.gnu.org/licenses/>.
15 */
16
17#include "uart.h"
18
19#include "quantum.h"
20
21static SerialConfig serialConfig = {SERIAL_DEFAULT_BITRATE, SD1_CR1, SD1_CR2, SD1_CR3};
22
23void uart_init(uint32_t baud) {
24 static bool is_initialised = false;
25
26 if (!is_initialised) {
27 is_initialised = true;
28
29 serialConfig.speed = baud;
30
31#if defined(USE_GPIOV1)
32 palSetLineMode(SD1_TX_PIN, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
33 palSetLineMode(SD1_RX_PIN, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
34#else
35 palSetLineMode(SD1_TX_PIN, PAL_MODE_ALTERNATE(SD1_TX_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
36 palSetLineMode(SD1_RX_PIN, PAL_MODE_ALTERNATE(SD1_RX_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
37#endif
38 sdStart(&SERIAL_DRIVER, &serialConfig);
39 }
40}
41
42void uart_putchar(uint8_t c) { sdPut(&SERIAL_DRIVER, c); }
43
44uint8_t uart_getchar(void) {
45 msg_t res = sdGet(&SERIAL_DRIVER);
46
47 return (uint8_t)res;
48}
49
50bool uart_available(void) { return !sdGetWouldBlock(&SERIAL_DRIVER); }
diff --git a/platforms/chibios/drivers/uart.h b/platforms/chibios/drivers/uart.h
new file mode 100644
index 000000000..b4e20e9fd
--- /dev/null
+++ b/platforms/chibios/drivers/uart.h
@@ -0,0 +1,77 @@
1/* Copyright 2021
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <https://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include <stdint.h>
20
21#include <hal.h>
22
23#ifndef SERIAL_DRIVER
24# define SERIAL_DRIVER SD1
25#endif
26
27#ifndef SD1_TX_PIN
28# define SD1_TX_PIN A9
29#endif
30
31#ifndef SD1_TX_PAL_MODE
32# define SD1_TX_PAL_MODE 7
33#endif
34
35#ifndef SD1_RX_PIN
36# define SD1_RX_PIN A10
37#endif
38
39#ifndef SD1_RX_PAL_MODE
40# define SD1_RX_PAL_MODE 7
41#endif
42
43#ifndef SD1_CTS_PIN
44# define SD1_CTS_PIN A11
45#endif
46
47#ifndef SD1_CTS_PAL_MODE
48# define SD1_CTS_PAL_MODE 7
49#endif
50
51#ifndef SD1_RTS_PIN
52# define SD1_RTS_PIN A12
53#endif
54
55#ifndef SD1_RTS_PAL_MODE
56# define SD1_RTS_PAL_MODE 7
57#endif
58
59#ifndef SD1_CR1
60# define SD1_CR1 0
61#endif
62
63#ifndef SD1_CR2
64# define SD1_CR2 0
65#endif
66
67#ifndef SD1_CR3
68# define SD1_CR3 0
69#endif
70
71void uart_init(uint32_t baud);
72
73void uart_putchar(uint8_t c);
74
75uint8_t uart_getchar(void);
76
77bool uart_available(void);
diff --git a/platforms/chibios/drivers/usbpd_stm32g4.c b/platforms/chibios/drivers/usbpd_stm32g4.c
new file mode 100644
index 000000000..f16ca8aea
--- /dev/null
+++ b/platforms/chibios/drivers/usbpd_stm32g4.c
@@ -0,0 +1,76 @@
1/* Copyright 2021 Nick Brassel (@tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <quantum.h>
18
19#ifndef USBPD_UCPD1_CFG1
20# define USBPD_UCPD1_CFG1 (UCPD_CFG1_PSC_UCPDCLK_0 | UCPD_CFG1_TRANSWIN_3 | UCPD_CFG1_IFRGAP_4 | UCPD_CFG1_HBITCLKDIV_4)
21#endif // USBPD_UCPD1_CFG1
22
23// Initialises the USBPD subsystem
24__attribute__((weak)) void usbpd_init(void) {
25 // Disable dead-battery signals
26 PWR->CR3 |= PWR_CR3_UCPD_DBDIS;
27 // Enable the clock for the UCPD1 peripheral
28 RCC->APB1ENR2 |= RCC_APB1ENR2_UCPD1EN;
29
30 // Copy the existing value
31 uint32_t CFG1 = UCPD1->CFG1;
32 // Force-disable UCPD1 before configuring
33 CFG1 &= ~UCPD_CFG1_UCPDEN;
34 // Configure UCPD1
35 CFG1 = USBPD_UCPD1_CFG1;
36 // Apply the changes
37 UCPD1->CFG1 = CFG1;
38 // Enable UCPD1
39 UCPD1->CFG1 |= UCPD_CFG1_UCPDEN;
40
41 // Copy the existing value
42 uint32_t CR = UCPD1->CR;
43 // Clear out ANASUBMODE (irrelevant as a sink device)
44 CR &= ~UCPD_CR_ANASUBMODE_Msk;
45 // Advertise our capabilities as a sink, with both CC lines enabled
46 CR |= UCPD_CR_ANAMODE | UCPD_CR_CCENABLE_Msk;
47 // Apply the changes
48 UCPD1->CR = CR;
49}
50
51// Gets the current state of the USBPD allowance
52__attribute__((weak)) usbpd_allowance_t usbpd_get_allowance(void) {
53 uint32_t CR = UCPD1->CR;
54
55 int ucpd_enabled = (UCPD1->CFG1 & UCPD_CFG1_UCPDEN_Msk) >> UCPD_CFG1_UCPDEN_Pos;
56 int anamode = (CR & UCPD_CR_ANAMODE_Msk) >> UCPD_CR_ANAMODE_Pos;
57 int cc_enabled = (CR & UCPD_CR_CCENABLE_Msk) >> UCPD_CR_CCENABLE_Pos;
58
59 if (ucpd_enabled && anamode && cc_enabled) {
60 uint32_t SR = UCPD1->SR;
61 int vstate_cc1 = (SR & UCPD_SR_TYPEC_VSTATE_CC1_Msk) >> UCPD_SR_TYPEC_VSTATE_CC1_Pos;
62 int vstate_cc2 = (SR & UCPD_SR_TYPEC_VSTATE_CC2_Msk) >> UCPD_SR_TYPEC_VSTATE_CC2_Pos;
63 int vstate_max = vstate_cc1 > vstate_cc2 ? vstate_cc1 : vstate_cc2;
64 switch (vstate_max) {
65 case 0:
66 case 1:
67 return USBPD_500MA; // Note that this is 500mA (i.e. max USB 2.0), not 900mA, as we're not using USB 3.1 as a sink device.
68 case 2:
69 return USBPD_1500MA;
70 case 3:
71 return USBPD_3000MA;
72 }
73 }
74
75 return USBPD_500MA;
76} \ No newline at end of file
diff --git a/platforms/chibios/drivers/ws2812.c b/platforms/chibios/drivers/ws2812.c
new file mode 100644
index 000000000..0d12e2fb7
--- /dev/null
+++ b/platforms/chibios/drivers/ws2812.c
@@ -0,0 +1,114 @@
1#include "quantum.h"
2#include "ws2812.h"
3#include <ch.h>
4#include <hal.h>
5
6/* Adapted from https://github.com/bigjosh/SimpleNeoPixelDemo/ */
7
8#ifndef NOP_FUDGE
9# if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F3XX) || defined(STM32F4XX) || defined(STM32L0XX)
10# define NOP_FUDGE 0.4
11# else
12# error("NOP_FUDGE configuration required")
13# define NOP_FUDGE 1 // this just pleases the compile so the above error is easier to spot
14# endif
15#endif
16
17// Push Pull or Open Drain Configuration
18// Default Push Pull
19#ifndef WS2812_EXTERNAL_PULLUP
20# define WS2812_OUTPUT_MODE PAL_MODE_OUTPUT_PUSHPULL
21#else
22# define WS2812_OUTPUT_MODE PAL_MODE_OUTPUT_OPENDRAIN
23#endif
24
25#define NUMBER_NOPS 6
26#define CYCLES_PER_SEC (STM32_SYSCLK / NUMBER_NOPS * NOP_FUDGE)
27#define NS_PER_SEC (1000000000L) // Note that this has to be SIGNED since we want to be able to check for negative values of derivatives
28#define NS_PER_CYCLE (NS_PER_SEC / CYCLES_PER_SEC)
29#define NS_TO_CYCLES(n) ((n) / NS_PER_CYCLE)
30
31#define wait_ns(x) \
32 do { \
33 for (int i = 0; i < NS_TO_CYCLES(x); i++) { \
34 __asm__ volatile("nop\n\t" \
35 "nop\n\t" \
36 "nop\n\t" \
37 "nop\n\t" \
38 "nop\n\t" \
39 "nop\n\t"); \
40 } \
41 } while (0)
42
43// These are the timing constraints taken mostly from the WS2812 datasheets
44// These are chosen to be conservative and avoid problems rather than for maximum throughput
45
46#define T1H 900 // Width of a 1 bit in ns
47#define T1L (1250 - T1H) // Width of a 1 bit in ns
48
49#define T0H 350 // Width of a 0 bit in ns
50#define T0L (1250 - T0H) // Width of a 0 bit in ns
51
52// The reset gap can be 6000 ns, but depending on the LED strip it may have to be increased
53// to values like 600000 ns. If it is too small, the pixels will show nothing most of the time.
54#define RES (1000 * WS2812_TRST_US) // Width of the low gap between bits to cause a frame to latch
55
56void sendByte(uint8_t byte) {
57 // WS2812 protocol wants most significant bits first
58 for (unsigned char bit = 0; bit < 8; bit++) {
59 bool is_one = byte & (1 << (7 - bit));
60 // using something like wait_ns(is_one ? T1L : T0L) here throws off timings
61 if (is_one) {
62 // 1
63 writePinHigh(RGB_DI_PIN);
64 wait_ns(T1H);
65 writePinLow(RGB_DI_PIN);
66 wait_ns(T1L);
67 } else {
68 // 0
69 writePinHigh(RGB_DI_PIN);
70 wait_ns(T0H);
71 writePinLow(RGB_DI_PIN);
72 wait_ns(T0L);
73 }
74 }
75}
76
77void ws2812_init(void) { palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE); }
78
79// Setleds for standard RGB
80void ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) {
81 static bool s_init = false;
82 if (!s_init) {
83 ws2812_init();
84 s_init = true;
85 }
86
87 // this code is very time dependent, so we need to disable interrupts
88 chSysLock();
89
90 for (uint8_t i = 0; i < leds; i++) {
91 // WS2812 protocol dictates grb order
92#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
93 sendByte(ledarray[i].g);
94 sendByte(ledarray[i].r);
95 sendByte(ledarray[i].b);
96#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
97 sendByte(ledarray[i].r);
98 sendByte(ledarray[i].g);
99 sendByte(ledarray[i].b);
100#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
101 sendByte(ledarray[i].b);
102 sendByte(ledarray[i].g);
103 sendByte(ledarray[i].r);
104#endif
105
106#ifdef RGBW
107 sendByte(ledarray[i].w);
108#endif
109 }
110
111 wait_ns(RES);
112
113 chSysUnlock();
114}
diff --git a/platforms/chibios/drivers/ws2812_pwm.c b/platforms/chibios/drivers/ws2812_pwm.c
new file mode 100644
index 000000000..e6af55b6b
--- /dev/null
+++ b/platforms/chibios/drivers/ws2812_pwm.c
@@ -0,0 +1,311 @@
1#include "ws2812.h"
2#include "quantum.h"
3#include <hal.h>
4
5/* Adapted from https://github.com/joewa/WS2812-LED-Driver_ChibiOS/ */
6
7#ifdef RGBW
8# error "RGBW not supported"
9#endif
10
11#ifndef WS2812_PWM_DRIVER
12# define WS2812_PWM_DRIVER PWMD2 // TIMx
13#endif
14#ifndef WS2812_PWM_CHANNEL
15# define WS2812_PWM_CHANNEL 2 // Channel
16#endif
17#ifndef WS2812_PWM_PAL_MODE
18# define WS2812_PWM_PAL_MODE 2 // DI Pin's alternate function value
19#endif
20#ifndef WS2812_DMA_STREAM
21# define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP
22#endif
23#ifndef WS2812_DMA_CHANNEL
24# define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP
25#endif
26#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && !defined(WS2812_DMAMUX_ID)
27# error "please consult your MCU's datasheet and specify in your config.h: #define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM?_UP"
28#endif
29
30#ifndef WS2812_PWM_COMPLEMENTARY_OUTPUT
31# define WS2812_PWM_OUTPUT_MODE PWM_OUTPUT_ACTIVE_HIGH
32#else
33# if !STM32_PWM_USE_ADVANCED
34# error "WS2812_PWM_COMPLEMENTARY_OUTPUT requires STM32_PWM_USE_ADVANCED == TRUE"
35# endif
36# define WS2812_PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH
37#endif
38
39// Push Pull or Open Drain Configuration
40// Default Push Pull
41#ifndef WS2812_EXTERNAL_PULLUP
42# if defined(USE_GPIOV1)
43# define WS2812_OUTPUT_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
44# else
45# define WS2812_OUTPUT_MODE PAL_MODE_ALTERNATE(WS2812_PWM_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_FLOATING
46# endif
47#else
48# if defined(USE_GPIOV1)
49# define WS2812_OUTPUT_MODE PAL_MODE_STM32_ALTERNATE_OPENDRAIN
50# else
51# define WS2812_OUTPUT_MODE PAL_MODE_ALTERNATE(WS2812_PWM_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_FLOATING
52# endif
53#endif
54
55#ifndef WS2812_PWM_TARGET_PERIOD
56//# define WS2812_PWM_TARGET_PERIOD 800000 // Original code is 800k...?
57# define WS2812_PWM_TARGET_PERIOD 80000 // TODO: work out why 10x less on f303/f4x1
58#endif
59
60/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
61
62#define WS2812_PWM_FREQUENCY (STM32_SYSCLK / 2) /**< Clock frequency of PWM, must be valid with respect to system clock! */
63#define WS2812_PWM_PERIOD (WS2812_PWM_FREQUENCY / WS2812_PWM_TARGET_PERIOD) /**< Clock period in ticks. 1 / 800kHz = 1.25 uS (as per datasheet) */
64
65/**
66 * @brief Number of bit-periods to hold the data line low at the end of a frame
67 *
68 * The reset period for each frame is defined in WS2812_TRST_US.
69 * Calculate the number of zeroes to add at the end assuming 1.25 uS/bit:
70 */
71#define WS2812_RESET_BIT_N (1000 * WS2812_TRST_US / 1250)
72#define WS2812_COLOR_BIT_N (RGBLED_NUM * 24) /**< Number of data bits */
73#define WS2812_BIT_N (WS2812_COLOR_BIT_N + WS2812_RESET_BIT_N) /**< Total number of bits in a frame */
74
75/**
76 * @brief High period for a zero, in ticks
77 *
78 * Per the datasheet:
79 * WS2812:
80 * - T0H: 200 nS to 500 nS, inclusive
81 * - T0L: 650 nS to 950 nS, inclusive
82 * WS2812B:
83 * - T0H: 200 nS to 500 nS, inclusive
84 * - T0L: 750 nS to 1050 nS, inclusive
85 *
86 * The duty cycle is calculated for a high period of 350 nS.
87 */
88#define WS2812_DUTYCYCLE_0 (WS2812_PWM_FREQUENCY / (1000000000 / 350))
89
90/**
91 * @brief High period for a one, in ticks
92 *
93 * Per the datasheet:
94 * WS2812:
95 * - T1H: 550 nS to 850 nS, inclusive
96 * - T1L: 450 nS to 750 nS, inclusive
97 * WS2812B:
98 * - T1H: 750 nS to 1050 nS, inclusive
99 * - T1L: 200 nS to 500 nS, inclusive
100 *
101 * The duty cycle is calculated for a high period of 800 nS.
102 * This is in the middle of the specifications of the WS2812 and WS2812B.
103 */
104#define WS2812_DUTYCYCLE_1 (WS2812_PWM_FREQUENCY / (1000000000 / 800))
105
106/* --- PRIVATE MACROS ------------------------------------------------------- */
107
108/**
109 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given bit
110 *
111 * @param[in] led: The led index [0, @ref RGBLED_NUM)
112 * @param[in] byte: The byte number [0, 2]
113 * @param[in] bit: The bit number [0, 7]
114 *
115 * @return The bit index
116 */
117#define WS2812_BIT(led, byte, bit) (24 * (led) + 8 * (byte) + (7 - (bit)))
118
119#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
120/**
121 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given red bit
122 *
123 * @note The red byte is the middle byte in the color packet
124 *
125 * @param[in] led: The led index [0, @ref RGBLED_NUM)
126 * @param[in] bit: The bit number [0, 7]
127 *
128 * @return The bit index
129 */
130# define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 1, (bit))
131
132/**
133 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given green bit
134 *
135 * @note The red byte is the first byte in the color packet
136 *
137 * @param[in] led: The led index [0, @ref RGBLED_NUM)
138 * @param[in] bit: The bit number [0, 7]
139 *
140 * @return The bit index
141 */
142# define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 0, (bit))
143
144/**
145 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given blue bit
146 *
147 * @note The red byte is the last byte in the color packet
148 *
149 * @param[in] led: The led index [0, @ref RGBLED_NUM)
150 * @param[in] bit: The bit index [0, 7]
151 *
152 * @return The bit index
153 */
154# define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 2, (bit))
155
156#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
157/**
158 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given red bit
159 *
160 * @note The red byte is the middle byte in the color packet
161 *
162 * @param[in] led: The led index [0, @ref RGBLED_NUM)
163 * @param[in] bit: The bit number [0, 7]
164 *
165 * @return The bit index
166 */
167# define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 0, (bit))
168
169/**
170 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given green bit
171 *
172 * @note The red byte is the first byte in the color packet
173 *
174 * @param[in] led: The led index [0, @ref RGBLED_NUM)
175 * @param[in] bit: The bit number [0, 7]
176 *
177 * @return The bit index
178 */
179# define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 1, (bit))
180
181/**
182 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given blue bit
183 *
184 * @note The red byte is the last byte in the color packet
185 *
186 * @param[in] led: The led index [0, @ref RGBLED_NUM)
187 * @param[in] bit: The bit index [0, 7]
188 *
189 * @return The bit index
190 */
191# define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 2, (bit))
192
193#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
194/**
195 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given red bit
196 *
197 * @note The red byte is the middle byte in the color packet
198 *
199 * @param[in] led: The led index [0, @ref RGBLED_NUM)
200 * @param[in] bit: The bit number [0, 7]
201 *
202 * @return The bit index
203 */
204# define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 2, (bit))
205
206/**
207 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given green bit
208 *
209 * @note The red byte is the first byte in the color packet
210 *
211 * @param[in] led: The led index [0, @ref RGBLED_NUM)
212 * @param[in] bit: The bit number [0, 7]
213 *
214 * @return The bit index
215 */
216# define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 1, (bit))
217
218/**
219 * @brief Determine the index in @ref ws2812_frame_buffer "the frame buffer" of a given blue bit
220 *
221 * @note The red byte is the last byte in the color packet
222 *
223 * @param[in] led: The led index [0, @ref RGBLED_NUM)
224 * @param[in] bit: The bit index [0, 7]
225 *
226 * @return The bit index
227 */
228# define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 0, (bit))
229#endif
230
231/* --- PRIVATE VARIABLES ---------------------------------------------------- */
232
233static uint32_t ws2812_frame_buffer[WS2812_BIT_N + 1]; /**< Buffer for a frame */
234
235/* --- PUBLIC FUNCTIONS ----------------------------------------------------- */
236/*
237 * Gedanke: Double-buffer type transactions: double buffer transfers using two memory pointers for
238the memory (while the DMA is reading/writing from/to a buffer, the application can
239write/read to/from the other buffer).
240 */
241
242void ws2812_init(void) {
243 // Initialize led frame buffer
244 uint32_t i;
245 for (i = 0; i < WS2812_COLOR_BIT_N; i++) ws2812_frame_buffer[i] = WS2812_DUTYCYCLE_0; // All color bits are zero duty cycle
246 for (i = 0; i < WS2812_RESET_BIT_N; i++) ws2812_frame_buffer[i + WS2812_COLOR_BIT_N] = 0; // All reset bits are zero
247
248 palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE);
249
250 // PWM Configuration
251 //#pragma GCC diagnostic ignored "-Woverride-init" // Turn off override-init warning for this struct. We use the overriding ability to set a "default" channel config
252 static const PWMConfig ws2812_pwm_config = {
253 .frequency = WS2812_PWM_FREQUENCY,
254 .period = WS2812_PWM_PERIOD, // Mit dieser Periode wird UDE-Event erzeugt und ein neuer Wert (Länge WS2812_BIT_N) vom DMA ins CCR geschrieben
255 .callback = NULL,
256 .channels =
257 {
258 [0 ... 3] = {.mode = PWM_OUTPUT_DISABLED, .callback = NULL}, // Channels default to disabled
259 [WS2812_PWM_CHANNEL - 1] = {.mode = WS2812_PWM_OUTPUT_MODE, .callback = NULL}, // Turn on the channel we care about
260 },
261 .cr2 = 0,
262 .dier = TIM_DIER_UDE, // DMA on update event for next period
263 };
264 //#pragma GCC diagnostic pop // Restore command-line warning options
265
266 // Configure DMA
267 // dmaInit(); // Joe added this
268 dmaStreamAlloc(WS2812_DMA_STREAM - STM32_DMA_STREAM(0), 10, NULL, NULL);
269 dmaStreamSetPeripheral(WS2812_DMA_STREAM, &(WS2812_PWM_DRIVER.tim->CCR[WS2812_PWM_CHANNEL - 1])); // Ziel ist der An-Zeit im Cap-Comp-Register
270 dmaStreamSetMemory0(WS2812_DMA_STREAM, ws2812_frame_buffer);
271 dmaStreamSetTransactionSize(WS2812_DMA_STREAM, WS2812_BIT_N);
272 dmaStreamSetMode(WS2812_DMA_STREAM, STM32_DMA_CR_CHSEL(WS2812_DMA_CHANNEL) | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3));
273 // M2P: Memory 2 Periph; PL: Priority Level
274
275#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE)
276 // If the MCU has a DMAMUX we need to assign the correct resource
277 dmaSetRequestSource(WS2812_DMA_STREAM, WS2812_DMAMUX_ID);
278#endif
279
280 // Start DMA
281 dmaStreamEnable(WS2812_DMA_STREAM);
282
283 // Configure PWM
284 // NOTE: It's required that preload be enabled on the timer channel CCR register. This is currently enabled in the
285 // ChibiOS driver code, so we don't have to do anything special to the timer. If we did, we'd have to start the timer,
286 // disable counting, enable the channel, and then make whatever configuration changes we need.
287 pwmStart(&WS2812_PWM_DRIVER, &ws2812_pwm_config);
288 pwmEnableChannel(&WS2812_PWM_DRIVER, WS2812_PWM_CHANNEL - 1, 0); // Initial period is 0; output will be low until first duty cycle is DMA'd in
289}
290
291void ws2812_write_led(uint16_t led_number, uint8_t r, uint8_t g, uint8_t b) {
292 // Write color to frame buffer
293 for (uint8_t bit = 0; bit < 8; bit++) {
294 ws2812_frame_buffer[WS2812_RED_BIT(led_number, bit)] = ((r >> bit) & 0x01) ? WS2812_DUTYCYCLE_1 : WS2812_DUTYCYCLE_0;
295 ws2812_frame_buffer[WS2812_GREEN_BIT(led_number, bit)] = ((g >> bit) & 0x01) ? WS2812_DUTYCYCLE_1 : WS2812_DUTYCYCLE_0;
296 ws2812_frame_buffer[WS2812_BLUE_BIT(led_number, bit)] = ((b >> bit) & 0x01) ? WS2812_DUTYCYCLE_1 : WS2812_DUTYCYCLE_0;
297 }
298}
299
300// Setleds for standard RGB
301void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) {
302 static bool s_init = false;
303 if (!s_init) {
304 ws2812_init();
305 s_init = true;
306 }
307
308 for (uint16_t i = 0; i < leds; i++) {
309 ws2812_write_led(i, ledarray[i].r, ledarray[i].g, ledarray[i].b);
310 }
311}
diff --git a/platforms/chibios/drivers/ws2812_spi.c b/platforms/chibios/drivers/ws2812_spi.c
new file mode 100644
index 000000000..377a929b9
--- /dev/null
+++ b/platforms/chibios/drivers/ws2812_spi.c
@@ -0,0 +1,159 @@
1#include "quantum.h"
2#include "ws2812.h"
3
4/* Adapted from https://github.com/gamazeps/ws2812b-chibios-SPIDMA/ */
5
6#ifdef RGBW
7# error "RGBW not supported"
8#endif
9
10// Define the spi your LEDs are plugged to here
11#ifndef WS2812_SPI
12# define WS2812_SPI SPID1
13#endif
14
15#ifndef WS2812_SPI_MOSI_PAL_MODE
16# define WS2812_SPI_MOSI_PAL_MODE 5
17#endif
18
19#ifndef WS2812_SPI_SCK_PAL_MODE
20# define WS2812_SPI_SCK_PAL_MODE 5
21#endif
22
23// Push Pull or Open Drain Configuration
24// Default Push Pull
25#ifndef WS2812_EXTERNAL_PULLUP
26# if defined(USE_GPIOV1)
27# define WS2812_MOSI_OUTPUT_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
28# else
29# define WS2812_MOSI_OUTPUT_MODE PAL_MODE_ALTERNATE(WS2812_SPI_MOSI_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL
30# endif
31#else
32# if defined(USE_GPIOV1)
33# define WS2812_MOSI_OUTPUT_MODE PAL_MODE_STM32_ALTERNATE_OPENDRAIN
34# else
35# define WS2812_MOSI_OUTPUT_MODE PAL_MODE_ALTERNATE(WS2812_SPI_MOSI_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN
36# endif
37#endif
38
39// Define SPI config speed
40// baudrate should target 3.2MHz
41// F072 fpclk = 48MHz
42// 48/16 = 3Mhz
43#if WS2812_SPI_DIVISOR == 2
44# define WS2812_SPI_DIVISOR (0)
45#elif WS2812_SPI_DIVISOR == 4
46# define WS2812_SPI_DIVISOR (SPI_CR1_BR_0)
47#elif WS2812_SPI_DIVISOR == 8
48# define WS2812_SPI_DIVISOR (SPI_CR1_BR_1)
49#elif WS2812_SPI_DIVISOR == 16 // same as default
50# define WS2812_SPI_DIVISOR (SPI_CR1_BR_1 | SPI_CR1_BR_0)
51#elif WS2812_SPI_DIVISOR == 32
52# define WS2812_SPI_DIVISOR (SPI_CR1_BR_2)
53#elif WS2812_SPI_DIVISOR == 64
54# define WS2812_SPI_DIVISOR (SPI_CR1_BR_2 | SPI_CR1_BR_0)
55#elif WS2812_SPI_DIVISOR == 128
56# define WS2812_SPI_DIVISOR (SPI_CR1_BR_2 | SPI_CR1_BR_1)
57#elif WS2812_SPI_DIVISOR == 256
58# define WS2812_SPI_DIVISOR (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0)
59#else
60# define WS2812_SPI_DIVISOR (SPI_CR1_BR_1 | SPI_CR1_BR_0) // default
61#endif
62
63// Use SPI circular buffer
64#ifdef WS2812_SPI_USE_CIRCULAR_BUFFER
65# define WS2812_SPI_BUFFER_MODE 1 // circular buffer
66#else
67# define WS2812_SPI_BUFFER_MODE 0 // normal buffer
68#endif
69
70#if defined(USE_GPIOV1)
71# define WS2812_SCK_OUTPUT_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
72#else
73# define WS2812_SCK_OUTPUT_MODE PAL_MODE_ALTERNATE(WS2812_SPI_SCK_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL
74#endif
75
76#define BYTES_FOR_LED_BYTE 4
77#define NB_COLORS 3
78#define BYTES_FOR_LED (BYTES_FOR_LED_BYTE * NB_COLORS)
79#define DATA_SIZE (BYTES_FOR_LED * RGBLED_NUM)
80#define RESET_SIZE (1000 * WS2812_TRST_US / (2 * 1250))
81#define PREAMBLE_SIZE 4
82
83static uint8_t txbuf[PREAMBLE_SIZE + DATA_SIZE + RESET_SIZE] = {0};
84
85/*
86 * As the trick here is to use the SPI to send a huge pattern of 0 and 1 to
87 * the ws2812b protocol, we use this helper function to translate bytes into
88 * 0s and 1s for the LED (with the appropriate timing).
89 */
90static uint8_t get_protocol_eq(uint8_t data, int pos) {
91 uint8_t eq = 0;
92 if (data & (1 << (2 * (3 - pos))))
93 eq = 0b1110;
94 else
95 eq = 0b1000;
96 if (data & (2 << (2 * (3 - pos))))
97 eq += 0b11100000;
98 else
99 eq += 0b10000000;
100 return eq;
101}
102
103static void set_led_color_rgb(LED_TYPE color, int pos) {
104 uint8_t* tx_start = &txbuf[PREAMBLE_SIZE];
105
106#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
107 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.g, j);
108 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.r, j);
109 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.b, j);
110#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
111 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.r, j);
112 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j);
113 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.b, j);
114#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
115 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.b, j);
116 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j);
117 for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.r, j);
118#endif
119}
120
121void ws2812_init(void) {
122 palSetLineMode(RGB_DI_PIN, WS2812_MOSI_OUTPUT_MODE);
123
124#ifdef WS2812_SPI_SCK_PIN
125 palSetLineMode(WS2812_SPI_SCK_PIN, WS2812_SCK_OUTPUT_MODE);
126#endif // WS2812_SPI_SCK_PIN
127
128 // TODO: more dynamic baudrate
129 static const SPIConfig spicfg = {WS2812_SPI_BUFFER_MODE, NULL, PAL_PORT(RGB_DI_PIN), PAL_PAD(RGB_DI_PIN), WS2812_SPI_DIVISOR};
130
131 spiAcquireBus(&WS2812_SPI); /* Acquire ownership of the bus. */
132 spiStart(&WS2812_SPI, &spicfg); /* Setup transfer parameters. */
133 spiSelect(&WS2812_SPI); /* Slave Select assertion. */
134#ifdef WS2812_SPI_USE_CIRCULAR_BUFFER
135 spiStartSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf);
136#endif
137}
138
139void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) {
140 static bool s_init = false;
141 if (!s_init) {
142 ws2812_init();
143 s_init = true;
144 }
145
146 for (uint8_t i = 0; i < leds; i++) {
147 set_led_color_rgb(ledarray[i], i);
148 }
149
150 // Send async - each led takes ~0.03ms, 50 leds ~1.5ms, animations flushing faster than send will cause issues.
151 // Instead spiSend can be used to send synchronously (or the thread logic can be added back).
152#ifndef WS2812_SPI_USE_CIRCULAR_BUFFER
153# ifdef WS2812_SPI_SYNC
154 spiSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf);
155# else
156 spiStartSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf);
157# endif
158#endif
159}
diff --git a/platforms/chibios/flash.mk b/platforms/chibios/flash.mk
new file mode 100644
index 000000000..c0b32c2f2
--- /dev/null
+++ b/platforms/chibios/flash.mk
@@ -0,0 +1,87 @@
1# Hey Emacs, this is a -*- makefile -*-
2##############################################################################
3# Architecture or project specific options
4#
5
6DFU_ARGS ?=
7ifneq ("$(SERIAL)","")
8 DFU_ARGS += -S $(SERIAL)
9endif
10
11DFU_UTIL ?= dfu-util
12
13define EXEC_DFU_UTIL
14 if ! $(DFU_UTIL) -l | grep -q "Found DFU"; then \
15 printf "$(MSG_BOOTLOADER_NOT_FOUND_QUICK_RETRY)" ;\
16 sleep $(BOOTLOADER_RETRY_TIME) ;\
17 while ! $(DFU_UTIL) -l | grep -q "Found DFU"; do \
18 printf "." ;\
19 sleep $(BOOTLOADER_RETRY_TIME) ;\
20 done ;\
21 printf "\n" ;\
22 fi
23 $(DFU_UTIL) $(DFU_ARGS) -D $(BUILD_DIR)/$(TARGET).bin
24endef
25
26dfu-util: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter
27 $(call EXEC_DFU_UTIL)
28
29# TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS
30# within the emulated eeprom via dfu-util or another tool
31ifneq (,$(filter $(MAKECMDGOALS),dfu-util-split-left))
32 OPT_DEFS += -DINIT_EE_HANDS_LEFT
33endif
34
35ifneq (,$(filter $(MAKECMDGOALS),dfu-util-split-right))
36 OPT_DEFS += -DINIT_EE_HANDS_RIGHT
37endif
38
39dfu-util-split-left: dfu-util
40
41dfu-util-split-right: dfu-util
42
43ST_LINK_CLI ?= st-link_cli
44ST_LINK_ARGS ?=
45
46st-link-cli: $(BUILD_DIR)/$(TARGET).hex sizeafter
47 $(ST_LINK_CLI) $(ST_LINK_ARGS) -q -c SWD -p $(BUILD_DIR)/$(TARGET).hex -Rst
48
49ST_FLASH ?= st-flash
50ST_FLASH_ARGS ?=
51
52st-flash: $(BUILD_DIR)/$(TARGET).hex sizeafter
53 $(ST_FLASH) $(ST_FLASH_ARGS) --reset --format ihex write $(BUILD_DIR)/$(TARGET).hex
54
55# Autodetect teensy loader
56ifndef TEENSY_LOADER_CLI
57 ifneq (, $(shell which teensy-loader-cli 2>/dev/null))
58 TEENSY_LOADER_CLI ?= teensy-loader-cli
59 else
60 TEENSY_LOADER_CLI ?= teensy_loader_cli
61 endif
62endif
63
64TEENSY_LOADER_CLI_MCU ?= $(MCU_LDSCRIPT)
65
66define EXEC_TEENSY
67 $(TEENSY_LOADER_CLI) -mmcu=$(TEENSY_LOADER_CLI_MCU) -w -v $(BUILD_DIR)/$(TARGET).hex
68endef
69
70teensy: $(BUILD_DIR)/$(TARGET).hex cpfirmware sizeafter
71 $(call EXEC_TEENSY)
72
73
74flash: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter
75ifneq ($(strip $(PROGRAM_CMD)),)
76 $(UNSYNC_OUTPUT_CMD) && $(PROGRAM_CMD)
77else ifeq ($(strip $(BOOTLOADER)),kiibohd)
78 $(UNSYNC_OUTPUT_CMD) && $(call EXEC_DFU_UTIL)
79else ifeq ($(strip $(MCU_FAMILY)),KINETIS)
80 $(UNSYNC_OUTPUT_CMD) && $(call EXEC_TEENSY)
81else ifeq ($(strip $(MCU_FAMILY)),MIMXRT1062)
82 $(UNSYNC_OUTPUT_CMD) && $(call EXEC_TEENSY)
83else ifeq ($(strip $(MCU_FAMILY)),STM32)
84 $(UNSYNC_OUTPUT_CMD) && $(call EXEC_DFU_UTIL)
85else
86 $(PRINT_OK); $(SILENT) || printf "$(MSG_FLASH_BOOTLOADER)"
87endif