diff options
Diffstat (limited to 'platforms/chibios')
53 files changed, 1023 insertions, 655 deletions
diff --git a/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/bootloader_defs.h b/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/bootloader_defs.h deleted file mode 100644 index 4da3d39a32..0000000000 --- a/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/bootloader_defs.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 diff --git a/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/bootloader_defs.h b/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/bootloader_defs.h deleted file mode 100644 index 4da3d39a32..0000000000 --- a/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/bootloader_defs.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 diff --git a/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/bootloader_defs.h deleted file mode 100644 index 25113425a6..0000000000 --- a/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/bootloader_defs.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFFC400 diff --git a/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/bootloader_defs.h deleted file mode 100644 index dccd0fa5d1..0000000000 --- a/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/bootloader_defs.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here (page 175): - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFFC800 diff --git a/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/bootloader_defs.h deleted file mode 100644 index 87ac7b10dc..0000000000 --- a/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/bootloader_defs.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFFD800 diff --git a/platforms/chibios/boards/GENERIC_STM32_F405XG/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F405XG/configs/config.h index cc52a953ed..90a41326a1 100644 --- a/platforms/chibios/boards/GENERIC_STM32_F405XG/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_F405XG/configs/config.h @@ -17,7 +17,7 @@ /* Address for jumping to bootloader on STM32 chips. */ /* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 + #ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP # define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE #endif diff --git a/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h index cc52a953ed..90a41326a1 100644 --- a/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h @@ -17,7 +17,7 @@ /* Address for jumping to bootloader on STM32 chips. */ /* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 + #ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP # define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE #endif diff --git a/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h index cc52a953ed..90a41326a1 100644 --- a/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h @@ -17,7 +17,7 @@ /* Address for jumping to bootloader on STM32 chips. */ /* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 + #ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP # define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE #endif diff --git a/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h index c27c61b19a..fc9055ccfb 100644 --- a/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h @@ -17,7 +17,6 @@ /* Address for jumping to bootloader on STM32 chips. */ /* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 #define PAL_STM32_OSPEED_HIGHEST PAL_STM32_OSPEED_HIGH diff --git a/platforms/chibios/boards/GENERIC_STM32_L432XC/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_L432XC/board/board.mk new file mode 100644 index 0000000000..1250385eb8 --- /dev/null +++ b/platforms/chibios/boards/GENERIC_STM32_L432XC/board/board.mk @@ -0,0 +1,9 @@ +# List of all the board related files. +BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC/board.c + +# Required include directories +BOARDINC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC + +# Shared variables +ALLCSRC += $(BOARDSRC) +ALLINC += $(BOARDINC) diff --git a/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/config.h new file mode 100644 index 0000000000..b1838b30a8 --- /dev/null +++ b/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/config.h @@ -0,0 +1,10 @@ +// Copyright 2021 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +// Fixup equivalent usages within QMK as the base board definitions only go up to high +#define PAL_STM32_OSPEED_HIGHEST PAL_STM32_OSPEED_HIGH + +#ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP +# define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE +#endif diff --git a/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/mcuconf.h new file mode 100644 index 0000000000..707134d49e --- /dev/null +++ b/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/mcuconf.h @@ -0,0 +1,267 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * STM32L4xx drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +#ifndef MCUCONF_H +#define MCUCONF_H + +#define STM32L4xx_MCUCONF +#define STM32L432_MCUCONF +#define STM32L433_MCUCONF + +/* + * HAL driver system settings. + */ +#define STM32_NO_INIT FALSE +#define STM32_VOS STM32_VOS_RANGE1 +#define STM32_PVD_ENABLE FALSE +#define STM32_PLS STM32_PLS_LEV0 +#define STM32_HSI16_ENABLED TRUE +#define STM32_HSI48_ENABLED TRUE +#define STM32_LSI_ENABLED TRUE +#define STM32_HSE_ENABLED FALSE +#define STM32_LSE_ENABLED FALSE +#define STM32_MSIPLL_ENABLED FALSE +#define STM32_MSIRANGE STM32_MSIRANGE_4M +#define STM32_MSISRANGE STM32_MSISRANGE_4M +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSI16 +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 10 +#define STM32_PLLPDIV_VALUE 0 +#define STM32_PLLP_VALUE 7 +#define STM32_PLLQ_VALUE 2 +#define STM32_PLLR_VALUE 2 +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#define STM32_STOPWUCK STM32_STOPWUCK_MSI +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK +#define STM32_PLLSAI1N_VALUE 24 +#define STM32_PLLSAI1PDIV_VALUE 0 +#define STM32_PLLSAI1P_VALUE 7 +#define STM32_PLLSAI1Q_VALUE 2 +#define STM32_PLLSAI1R_VALUE 2 + +/* + * Peripherals clock sources. + */ +#define STM32_USART1SEL STM32_USART1SEL_SYSCLK +#define STM32_USART2SEL STM32_USART2SEL_SYSCLK +#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK +#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK +#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 +#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 +#define STM32_SAI1SEL STM32_SAI1SEL_OFF +#define STM32_CLK48SEL STM32_CLK48SEL_HSI48 +#define STM32_ADCSEL STM32_ADCSEL_SYSCLK +#define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1 +#define STM32_RTCSEL STM32_RTCSEL_LSI + +/* + * IRQ system settings. + */ +#define STM32_IRQ_EXTI0_PRIORITY 6 +#define STM32_IRQ_EXTI1_PRIORITY 6 +#define STM32_IRQ_EXTI2_PRIORITY 6 +#define STM32_IRQ_EXTI3_PRIORITY 6 +#define STM32_IRQ_EXTI4_PRIORITY 6 +#define STM32_IRQ_EXTI5_9_PRIORITY 6 +#define STM32_IRQ_EXTI10_15_PRIORITY 6 +#define STM32_IRQ_EXTI1635_38_PRIORITY 6 +#define STM32_IRQ_EXTI18_PRIORITY 6 +#define STM32_IRQ_EXTI19_PRIORITY 6 +#define STM32_IRQ_EXTI20_PRIORITY 6 +#define STM32_IRQ_EXTI21_22_PRIORITY 15 + +#define STM32_IRQ_TIM1_BRK_TIM15_PRIORITY 7 +#define STM32_IRQ_TIM1_UP_TIM16_PRIORITY 7 +#define STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY 7 +#define STM32_IRQ_TIM1_CC_PRIORITY 7 +#define STM32_IRQ_TIM2_PRIORITY 7 +#define STM32_IRQ_TIM6_PRIORITY 7 +#define STM32_IRQ_TIM7_PRIORITY 7 + +#define STM32_IRQ_USART1_PRIORITY 12 +#define STM32_IRQ_USART2_PRIORITY 12 +#define STM32_IRQ_LPUART1_PRIORITY 12 + +/* + * ADC driver system settings. + */ +#define STM32_ADC_COMPACT_SAMPLES FALSE +#define STM32_ADC_USE_ADC1 FALSE +#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#define STM32_ADC_ADC12_IRQ_PRIORITY 5 +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC123_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 +#define STM32_ADC_ADC123_PRESC ADC_CCR_PRESC_DIV2 + +/* + * CAN driver system settings. + */ +#define STM32_CAN_USE_CAN1 FALSE +#define STM32_CAN_CAN1_IRQ_PRIORITY 11 + +/* + * DAC driver system settings. + */ +#define STM32_DAC_DUAL_MODE FALSE +#define STM32_DAC_USE_DAC1_CH1 FALSE +#define STM32_DAC_USE_DAC1_CH2 FALSE +#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) + +/* + * GPT driver system settings. + */ +#define STM32_GPT_USE_TIM1 FALSE +#define STM32_GPT_USE_TIM2 FALSE +#define STM32_GPT_USE_TIM6 FALSE +#define STM32_GPT_USE_TIM7 FALSE +#define STM32_GPT_USE_TIM15 FALSE +#define STM32_GPT_USE_TIM16 FALSE + +/* + * I2C driver system settings. + */ +#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C3 FALSE +#define STM32_I2C_BUSY_TIMEOUT 50 +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C1_IRQ_PRIORITY 5 +#define STM32_I2C_I2C3_IRQ_PRIORITY 5 +#define STM32_I2C_I2C1_DMA_PRIORITY 3 +#define STM32_I2C_I2C3_DMA_PRIORITY 3 +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") + +/* + * ICU driver system settings. + */ +#define STM32_ICU_USE_TIM1 FALSE +#define STM32_ICU_USE_TIM2 FALSE +#define STM32_ICU_USE_TIM15 FALSE +#define STM32_ICU_USE_TIM16 FALSE + +/* + * PWM driver system settings. + */ +#define STM32_PWM_USE_ADVANCED FALSE +#define STM32_PWM_USE_TIM1 FALSE +#define STM32_PWM_USE_TIM2 FALSE +#define STM32_PWM_USE_TIM15 FALSE +#define STM32_PWM_USE_TIM16 FALSE + +/* + * RTC driver system settings. + */ +#define STM32_RTC_PRESA_VALUE 32 +#define STM32_RTC_PRESS_VALUE 1024 +#define STM32_RTC_CR_INIT 0 +#define STM32_RTC_TAMPCR_INIT 0 + +/* + * SERIAL driver system settings. + */ +#define STM32_SERIAL_USE_USART1 FALSE +#define STM32_SERIAL_USE_USART2 FALSE +#define STM32_SERIAL_USE_LPUART1 FALSE +#define STM32_SERIAL_USART1_PRIORITY 12 +#define STM32_SERIAL_USART2_PRIORITY 12 +#define STM32_SERIAL_LPUART1_PRIORITY 12 + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI3 FALSE +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI3_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") + +/* + * ST driver system settings. + */ +#define STM32_ST_IRQ_PRIORITY 8 +#define STM32_ST_USE_TIMER 2 + +/* + * TRNG driver system settings. + */ +#define STM32_TRNG_USE_RNG1 FALSE + +/* + * UART driver system settings. + */ +#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART2 FALSE +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") + +/* + * USB driver system settings. + */ +#define STM32_USB_USE_USB1 TRUE +#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE +#define STM32_USB_USB1_HP_IRQ_PRIORITY 13 +#define STM32_USB_USB1_LP_IRQ_PRIORITY 14 + +/* + * WDG driver system settings. + */ +#define STM32_WDG_USE_IWDG FALSE + +/* + * WSPI driver system settings. + */ +#define STM32_WSPI_USE_QUADSPI1 FALSE +#define STM32_WSPI_QUADSPI1_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_WSPI_QUADSPI1_PRESCALER_VALUE 1 + +#endif /* MCUCONF_H */ diff --git a/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h index c27c61b19a..fc9055ccfb 100644 --- a/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h @@ -17,7 +17,6 @@ /* Address for jumping to bootloader on STM32 chips. */ /* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 #define PAL_STM32_OSPEED_HIGHEST PAL_STM32_OSPEED_HIGH diff --git a/platforms/chibios/boards/GENERIC_WB32_F3G71XX/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_WB32_F3G71XX/configs/bootloader_defs.h deleted file mode 100644 index c929d2ad03..0000000000 --- a/platforms/chibios/boards/GENERIC_WB32_F3G71XX/configs/bootloader_defs.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Address for jumping to bootloader on WB32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.westberrytech.com/down/mcu/data/WB32F3G71xx_rm.pdf - */ -#ifndef WB32_BOOTLOADER_ADDRESS -# undef STM32_BOOTLOADER_ADDRESS -# define WB32_BOOTLOADER_ADDRESS 0x1FFFE000 -# define STM32_BOOTLOADER_ADDRESS WB32_BOOTLOADER_ADDRESS -#else -# undef STM32_BOOTLOADER_ADDRESS -# define STM32_BOOTLOADER_ADDRESS WB32_BOOTLOADER_ADDRESS -#endif diff --git a/platforms/chibios/boards/QMK_PROTON_C/configs/bootloader_defs.h b/platforms/chibios/boards/QMK_PROTON_C/configs/bootloader_defs.h deleted file mode 100644 index 3b0e9d20a6..0000000000 --- a/platforms/chibios/boards/QMK_PROTON_C/configs/bootloader_defs.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - * This also requires a patch to chibios: - * <tmk_dir>/tmk_core/tool/chibios/ch-bootloader-jump.patch - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFFD800 diff --git a/platforms/chibios/bootloader.c b/platforms/chibios/bootloader.c deleted file mode 100644 index 58212948b0..0000000000 --- a/platforms/chibios/bootloader.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "bootloader.h" - -#include <ch.h> -#include <hal.h> -#include "wait.h" - -/* This code should be checked whether it runs correctly on platforms */ -#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) -#define BOOTLOADER_MAGIC 0xDEADBEEF -#define MAGIC_ADDR (unsigned long *)(SYMVAL(__ram0_end__) - 4) - -#ifndef STM32_BOOTLOADER_DUAL_BANK -# define STM32_BOOTLOADER_DUAL_BANK FALSE -#endif - -#ifdef BOOTLOADER_TINYUF2 - -# define DBL_TAP_MAGIC 0xf01669ef // From tinyuf2's board_api.h - -// defined by linker script -extern uint32_t _board_dfu_dbl_tap[]; -# define DBL_TAP_REG _board_dfu_dbl_tap[0] - -void bootloader_jump(void) { - DBL_TAP_REG = DBL_TAP_MAGIC; - NVIC_SystemReset(); -} - -void enter_bootloader_mode_if_requested(void) { /* not needed, no two-stage reset */ -} - -#elif STM32_BOOTLOADER_DUAL_BANK - -// Need pin definitions -# include "config_common.h" - -# ifndef STM32_BOOTLOADER_DUAL_BANK_GPIO -# error "No STM32_BOOTLOADER_DUAL_BANK_GPIO defined, don't know which pin to toggle" -# endif - -# ifndef STM32_BOOTLOADER_DUAL_BANK_POLARITY -# define STM32_BOOTLOADER_DUAL_BANK_POLARITY 0 -# endif - -# ifndef STM32_BOOTLOADER_DUAL_BANK_DELAY -# define STM32_BOOTLOADER_DUAL_BANK_DELAY 100000 -# endif - -extern uint32_t __ram0_end__; - -__attribute__((weak)) void bootloader_jump(void) { - // For STM32 MCUs with dual-bank flash, and we're incapable of jumping to the bootloader. The first valid flash - // bank is executed unconditionally after a reset, so it doesn't enter DFU unless BOOT0 is high. Instead, we do - // it with hardware...in this case, we pull a GPIO high/low depending on the configuration, connects 3.3V to - // BOOT0's RC charging circuit, lets it charge the capacitor, and issue a system reset. See the QMK discord - // #hardware channel pins for an example circuit. - palSetPadMode(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_MODE_OUTPUT_PUSHPULL); -# if STM32_BOOTLOADER_DUAL_BANK_POLARITY - palSetPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO)); -# else - palClearPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO)); -# endif - - // Wait for a while for the capacitor to charge - wait_ms(100); - - // Issue a system reset to get the ROM bootloader to execute, with BOOT0 high - NVIC_SystemReset(); -} - -void enter_bootloader_mode_if_requested(void) {} // not needed at all, but if anybody attempts to invoke it.... - -#elif defined(STM32_BOOTLOADER_ADDRESS) // STM32_BOOTLOADER_DUAL_BANK - -extern uint32_t __ram0_end__; - -__attribute__((weak)) void bootloader_jump(void) { - *MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader - NVIC_SystemReset(); -} - -void enter_bootloader_mode_if_requested(void) { - unsigned long *check = MAGIC_ADDR; - if (*check == BOOTLOADER_MAGIC) { - *check = 0; - __set_CONTROL(0); - __set_MSP(*(__IO uint32_t *)STM32_BOOTLOADER_ADDRESS); - __enable_irq(); - - typedef void (*BootJump_t)(void); - BootJump_t boot_jump = *(BootJump_t *)(STM32_BOOTLOADER_ADDRESS + 4); - boot_jump(); - while (1) - ; - } -} - -#elif defined(GD32VF103) - -# define DBGMCU_KEY_UNLOCK 0x4B5A6978 -# define DBGMCU_CMD_RESET 0x1 - -__IO uint32_t *DBGMCU_KEY = (uint32_t *)DBGMCU_BASE + 0x0CU; -__IO uint32_t *DBGMCU_CMD = (uint32_t *)DBGMCU_BASE + 0x08U; - -__attribute__((weak)) void bootloader_jump(void) { - /* The MTIMER unit of the GD32VF103 doesn't have the MSFRST - * register to generate a software reset request. - * BUT instead two undocumented registers in the debug peripheral - * that allow issueing a software reset. WHO would need the MSFRST - * register anyway? Source: - * https://github.com/esmil/gd32vf103inator/blob/master/include/gd32vf103/dbg.h */ - *DBGMCU_KEY = DBGMCU_KEY_UNLOCK; - *DBGMCU_CMD = DBGMCU_CMD_RESET; -} - -void enter_bootloader_mode_if_requested(void) { /* Jumping to bootloader is not possible from user code. */ -} - -#elif defined(KL2x) || defined(K20x) || defined(MK66F18) || defined(MIMXRT1062) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS -/* Kinetis */ - -# if defined(BOOTLOADER_KIIBOHD) -/* Kiibohd Bootloader (MCHCK and Infinity KB) */ -# define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 -const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -__attribute__((weak)) void bootloader_jump(void) { - void *volatile vbat = (void *)VBAT; - __builtin_memcpy(vbat, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); - // request reset - SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; -} - -# else /* defined(BOOTLOADER_KIIBOHD) */ -/* Default for Kinetis - expecting an ARM Teensy */ -# include "wait.h" -__attribute__((weak)) void bootloader_jump(void) { - wait_ms(100); - __BKPT(0); -} -# endif /* defined(BOOTLOADER_KIIBOHD) */ - -#else /* neither STM32 nor KINETIS */ -__attribute__((weak)) void bootloader_jump(void) {} -#endif diff --git a/platforms/chibios/boards/GENERIC_STM32_G431XB/configs/config.h b/platforms/chibios/bootloaders/custom.c index 39ce627e77..bba9fc4637 100644 --- a/platforms/chibios/boards/GENERIC_STM32_G431XB/configs/config.h +++ b/platforms/chibios/bootloaders/custom.c @@ -1,8 +1,8 @@ -/* Copyright 2018-2020 Nick Brassel (@tzarc) +/* Copyright 2021 QMK * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or + * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -14,10 +14,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here (page 175): - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - * This also requires a patch to chibios: - * <tmk_dir>/tmk_core/tool/chibios/ch-bootloader-jump.patch - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 +#include "bootloader.h" + +__attribute__((weak)) void bootloader_jump(void) {} + +__attribute__((weak)) void enter_bootloader_mode_if_requested(void) {} diff --git a/platforms/chibios/bootloaders/gd32v_dfu.c b/platforms/chibios/bootloaders/gd32v_dfu.c new file mode 100644 index 0000000000..baa7d1f882 --- /dev/null +++ b/platforms/chibios/bootloaders/gd32v_dfu.c @@ -0,0 +1,40 @@ +/* Copyright 2021 QMK + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "bootloader.h" + +#include <ch.h> +#include <hal.h> + +#define DBGMCU_KEY_UNLOCK 0x4B5A6978 +#define DBGMCU_CMD_RESET 0x1 + +__IO uint32_t *DBGMCU_KEY = (uint32_t *)DBGMCU_BASE + 0x0CU; +__IO uint32_t *DBGMCU_CMD = (uint32_t *)DBGMCU_BASE + 0x08U; + +__attribute__((weak)) void bootloader_jump(void) { + /* The MTIMER unit of the GD32VF103 doesn't have the MSFRST + * register to generate a software reset request. + * BUT instead two undocumented registers in the debug peripheral + * that allow issueing a software reset. WHO would need the MSFRST + * register anyway? Source: + * https://github.com/esmil/gd32vf103inator/blob/master/include/gd32vf103/dbg.h */ + *DBGMCU_KEY = DBGMCU_KEY_UNLOCK; + *DBGMCU_CMD = DBGMCU_CMD_RESET; +} + +/* Jumping to bootloader is not possible from user code. */ +void enter_bootloader_mode_if_requested(void) {} diff --git a/platforms/chibios/bootloaders/halfkay.c b/platforms/chibios/bootloaders/halfkay.c new file mode 100644 index 0000000000..168c2abc23 --- /dev/null +++ b/platforms/chibios/bootloaders/halfkay.c @@ -0,0 +1,25 @@ +/* Copyright 2021 QMK + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "bootloader.h" + +#include <ch.h> +#include "wait.h" + +__attribute__((weak)) void bootloader_jump(void) { + wait_ms(100); + __BKPT(0); +} diff --git a/platforms/chibios/bootloaders/kiibohd.c b/platforms/chibios/bootloaders/kiibohd.c new file mode 100644 index 0000000000..911e807092 --- /dev/null +++ b/platforms/chibios/bootloaders/kiibohd.c @@ -0,0 +1,32 @@ +/* Copyright 2021 QMK + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "bootloader.h" + +#include <ch.h> + +/* Kiibohd Bootloader (MCHCK and Infinity KB) */ +#define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 + +const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + +__attribute__((weak)) void bootloader_jump(void) { + void *volatile vbat = (void *)VBAT; + __builtin_memcpy(vbat, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); + + // request reset + SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; +} diff --git a/platforms/chibios/bootloaders/stm32_dfu.c b/platforms/chibios/bootloaders/stm32_dfu.c new file mode 100644 index 0000000000..0e74111367 --- /dev/null +++ b/platforms/chibios/bootloaders/stm32_dfu.c @@ -0,0 +1,94 @@ +/* Copyright 2021 QMK + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "bootloader.h" + +#include <ch.h> +#include <hal.h> +#include "wait.h" + +extern uint32_t __ram0_end__; + +#ifndef STM32_BOOTLOADER_DUAL_BANK +# define STM32_BOOTLOADER_DUAL_BANK FALSE +#endif + +#if STM32_BOOTLOADER_DUAL_BANK +# include "config_common.h" + +# ifndef STM32_BOOTLOADER_DUAL_BANK_GPIO +# error "No STM32_BOOTLOADER_DUAL_BANK_GPIO defined, don't know which pin to toggle" +# endif + +# ifndef STM32_BOOTLOADER_DUAL_BANK_POLARITY +# define STM32_BOOTLOADER_DUAL_BANK_POLARITY 0 +# endif + +# ifndef STM32_BOOTLOADER_DUAL_BANK_DELAY +# define STM32_BOOTLOADER_DUAL_BANK_DELAY 100000 +# endif + +__attribute__((weak)) void bootloader_jump(void) { + // For STM32 MCUs with dual-bank flash, and we're incapable of jumping to the bootloader. The first valid flash + // bank is executed unconditionally after a reset, so it doesn't enter DFU unless BOOT0 is high. Instead, we do + // it with hardware...in this case, we pull a GPIO high/low depending on the configuration, connects 3.3V to + // BOOT0's RC charging circuit, lets it charge the capacitor, and issue a system reset. See the QMK discord + // #hardware channel pins for an example circuit. + palSetPadMode(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_MODE_OUTPUT_PUSHPULL); +# if STM32_BOOTLOADER_DUAL_BANK_POLARITY + palSetPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO)); +# else + palClearPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO)); +# endif + + // Wait for a while for the capacitor to charge + wait_ms(100); + + // Issue a system reset to get the ROM bootloader to execute, with BOOT0 high + NVIC_SystemReset(); +} + +// not needed at all, but if anybody attempts to invoke it.... +void enter_bootloader_mode_if_requested(void) {} + +#else + +/* This code should be checked whether it runs correctly on platforms */ +# define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) +# define BOOTLOADER_MAGIC 0xDEADBEEF +# define MAGIC_ADDR (unsigned long *)(SYMVAL(__ram0_end__) - 4) + +__attribute__((weak)) void bootloader_jump(void) { + *MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader + NVIC_SystemReset(); +} + +void enter_bootloader_mode_if_requested(void) { + unsigned long *check = MAGIC_ADDR; + if (*check == BOOTLOADER_MAGIC) { + *check = 0; + __set_CONTROL(0); + __set_MSP(*(__IO uint32_t *)STM32_BOOTLOADER_ADDRESS); + __enable_irq(); + + typedef void (*BootJump_t)(void); + BootJump_t boot_jump = *(BootJump_t *)(STM32_BOOTLOADER_ADDRESS + 4); + boot_jump(); + while (1) + ; + } +} +#endif diff --git a/platforms/chibios/bootloaders/stm32duino.c b/platforms/chibios/bootloaders/stm32duino.c new file mode 100644 index 0000000000..53d3ba0adb --- /dev/null +++ b/platforms/chibios/bootloaders/stm32duino.c @@ -0,0 +1,23 @@ +/* Copyright 2021 QMK + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "bootloader.h" + +#include <ch.h> + +__attribute__((weak)) void bootloader_jump(void) { + NVIC_SystemReset(); +} diff --git a/platforms/chibios/bootloaders/tinyuf2.c b/platforms/chibios/bootloaders/tinyuf2.c new file mode 100644 index 0000000000..9ffca5dec8 --- /dev/null +++ b/platforms/chibios/bootloaders/tinyuf2.c @@ -0,0 +1,34 @@ +/* Copyright 2021 QMK + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "bootloader.h" + +#include <ch.h> + +// From tinyuf2's board_api.h +#define DBL_TAP_MAGIC 0xF01669EF + +// defined by linker script +extern uint32_t _board_dfu_dbl_tap[]; +#define DBL_TAP_REG _board_dfu_dbl_tap[0] + +__attribute__((weak)) void bootloader_jump(void) { + DBL_TAP_REG = DBL_TAP_MAGIC; + NVIC_SystemReset(); +} + +/* not needed, no two-stage reset */ +void enter_bootloader_mode_if_requested(void) {} diff --git a/platforms/chibios/chibios_config.h b/platforms/chibios/chibios_config.h index 4e35736606..67d7541ba2 100644 --- a/platforms/chibios/chibios_config.h +++ b/platforms/chibios/chibios_config.h @@ -16,7 +16,7 @@ #pragma once #ifndef USB_VBUS_PIN -# define SPLIT_USB_DETECT // Force this on when dedicated pin is not used +# define SPLIT_USB_DETECT // Force this on when dedicated pin is not used #endif // STM32 compatibility @@ -76,7 +76,7 @@ # if defined(K20x) || defined(KL2x) # define USE_I2CV1 -# define USE_I2CV1_CONTRIB // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed +# define USE_I2CV1_CONTRIB // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed # define USE_GPIOV1 # endif #endif diff --git a/platforms/chibios/drivers/analog.c b/platforms/chibios/drivers/analog.c index eb437665f1..48a59fd290 100644 --- a/platforms/chibios/drivers/analog.c +++ b/platforms/chibios/drivers/analog.c @@ -101,9 +101,9 @@ // Options are 12, 10, 8, and 6 bit. #ifndef ADC_RESOLUTION -# ifdef ADC_CFGR_RES_10BITS // ADCv3, ADCv4 +# ifdef ADC_CFGR_RES_10BITS // ADCv3, ADCv4 # define ADC_RESOLUTION ADC_CFGR_RES_10BITS -# else // ADCv1, ADCv5, or the bodge for ADCv2 above +# else // ADCv1, ADCv5, or the bodge for ADCv2 above # define ADC_RESOLUTION ADC_CFGR1_RES_10BIT # endif #endif @@ -123,7 +123,7 @@ static ADCConversionGroup adcConversionGroup = { .smpr = ADC_SAMPLING_RATE, #elif defined(USE_ADCV2) # if !defined(STM32F1XX) && !defined(GD32VF103) - .cr2 = ADC_CR2_SWSTART, // F103 seem very unhappy with, F401 seems very unhappy without... + .cr2 = ADC_CR2_SWSTART, // F103 seem very unhappy with, F401 seems very unhappy without... # endif .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), .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), diff --git a/platforms/chibios/drivers/analog.h b/platforms/chibios/drivers/analog.h index e61c394265..8a821719e3 100644 --- a/platforms/chibios/drivers/analog.h +++ b/platforms/chibios/drivers/analog.h @@ -28,7 +28,9 @@ typedef struct { uint8_t adc; } adc_mux; #define TO_MUX(i, a) \ - (adc_mux) { i, a } + (adc_mux) { \ + i, a \ + } int16_t analogReadPin(pin_t pin); int16_t analogReadPinAdc(pin_t pin, uint8_t adc); diff --git a/platforms/chibios/drivers/audio_dac_additive.c b/platforms/chibios/drivers/audio_dac_additive.c index db304adb87..db07c4b393 100644 --- a/platforms/chibios/drivers/audio_dac_additive.c +++ b/platforms/chibios/drivers/audio_dac_additive.c @@ -52,19 +52,19 @@ static const dacsample_t dac_buffer_sine[AUDIO_DAC_BUFFER_SIZE] = { // 256 values, max 4095 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd, 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1}; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SINE +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SINE #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE static const dacsample_t dac_buffer_triangle[AUDIO_DAC_BUFFER_SIZE] = { // 256 values, max 4095 0x0, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, 0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20}; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE static const dacsample_t dac_buffer_square[AUDIO_DAC_BUFFER_SIZE] = { - [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0, // first and - [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, // second half + [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0, // first and + [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, // second half }; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE /* // four steps: 0, 1/3, 2/3 and 1 static const dacsample_t dac_buffer_staircase[AUDIO_DAC_BUFFER_SIZE] = { @@ -77,7 +77,7 @@ static const dacsample_t dac_buffer_staircase[AUDIO_DAC_BUFFER_SIZE] = { #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID static const dacsample_t dac_buffer_trapezoid[AUDIO_DAC_BUFFER_SIZE] = {0x0, 0x1f, 0x7f, 0xdf, 0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf, 0x7f, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID static dacsample_t dac_buffer_empty[AUDIO_DAC_BUFFER_SIZE] = {AUDIO_DAC_OFF_VALUE}; @@ -98,7 +98,7 @@ typedef enum { OUTPUT_REACHED_ZERO_BEFORE_OFF, OUTPUT_OFF, OUTPUT_OFF_1, - OUTPUT_OFF_2, // trailing off: giving the DAC two more conversion cycles until the AUDIO_DAC_OFF_VALUE reaches the output, then turn the timer off, which leaves the output at that level + OUTPUT_OFF_2, // trailing off: giving the DAC two more conversion cycles until the AUDIO_DAC_OFF_VALUE reaches the output, then turn the timer off, which leaves the output at that level number_of_output_states } output_states_t; output_states_t state = OUTPUT_OFF_2; @@ -171,7 +171,7 @@ static void dac_end(DACDriver *dacp) { // work on the other half of the buffer if (dacIsBufferComplete(dacp)) { - sample_p += AUDIO_DAC_BUFFER_SIZE / 2; // 'half_index' + sample_p += AUDIO_DAC_BUFFER_SIZE / 2; // 'half_index' } for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE / 2; s++) { @@ -196,8 +196,8 @@ static void dac_end(DACDriver *dacp) { * * * * =====*=*================================================= 0x0 */ - if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) && // value approaches from below - (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100))) // or above + if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) && // value approaches from below + (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100))) // or above ) { if ((OUTPUT_SHOULD_START == state) && (active_tones_snapshot_length > 0)) { state = OUTPUT_RUN_NORMALLY; @@ -220,7 +220,7 @@ static void dac_end(DACDriver *dacp) { // -> saves cpu cycles (?) for (uint8_t i = 0; i < active_tones; i++) { float freq = audio_get_processed_frequency(i); - if (freq > 0) { // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step + if (freq > 0) { // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step active_tones_snapshot[active_tones_snapshot_length++] = freq; } } @@ -321,7 +321,9 @@ void audio_driver_initialize() { gptStart(&GPTD6, &gpt6cfg1); } -void audio_driver_stop(void) { state = OUTPUT_SHOULD_STOP; } +void audio_driver_stop(void) { + state = OUTPUT_SHOULD_STOP; +} void audio_driver_start(void) { gptStartContinuous(&GPTD6, 2U); diff --git a/platforms/chibios/drivers/audio_dac_basic.c b/platforms/chibios/drivers/audio_dac_basic.c index fac6513506..64439a1e3c 100644 --- a/platforms/chibios/drivers/audio_dac_basic.c +++ b/platforms/chibios/drivers/audio_dac_basic.c @@ -115,13 +115,15 @@ void channel_1_set_frequency(float freq) { channel_1_frequency = freq; channel_1_stop(); - if (freq <= 0.0) // a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; gpt6cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; channel_1_start(); } -float channel_1_get_frequency(void) { return channel_1_frequency; } +float channel_1_get_frequency(void) { + return channel_1_frequency; +} void channel_2_start(void) { gptStart(&GPTD7, &gpt7cfg1); @@ -140,13 +142,15 @@ void channel_2_set_frequency(float freq) { channel_2_frequency = freq; channel_2_stop(); - if (freq <= 0.0) // a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; gpt7cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; channel_2_start(); } -float channel_2_get_frequency(void) { return channel_2_frequency; } +float channel_2_get_frequency(void) { + return channel_2_frequency; +} static void gpt_audio_state_cb(GPTDriver *gptp) { if (audio_update_state()) { @@ -155,8 +159,8 @@ static void gpt_audio_state_cb(GPTDriver *gptp) { channel_1_set_frequency(audio_get_processed_frequency(0)); channel_2_set_frequency(audio_get_processed_frequency(0)); -#else // two separate audio outputs/speakers - // primary speaker on A4, optional secondary on A5 +#else // two separate audio outputs/speakers + // primary speaker on A4, optional secondary on A5 if (AUDIO_PIN == A4) { channel_1_set_frequency(audio_get_processed_frequency(0)); if (AUDIO_PIN_ALT == A5) { diff --git a/platforms/chibios/drivers/audio_pwm_hardware.c b/platforms/chibios/drivers/audio_pwm_hardware.c index cd40019ee7..710f397609 100644 --- a/platforms/chibios/drivers/audio_pwm_hardware.c +++ b/platforms/chibios/drivers/audio_pwm_hardware.c @@ -72,7 +72,7 @@ static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { channel_1_frequency = freq; - if (freq <= 0.0) // a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; pwmcnt_t period = (pwmCFG.frequency / freq); @@ -82,14 +82,18 @@ void channel_1_set_frequency(float freq) { PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); } -float channel_1_get_frequency(void) { return channel_1_frequency; } +float channel_1_get_frequency(void) { + return channel_1_frequency; +} void channel_1_start(void) { pwmStop(&AUDIO_PWM_DRIVER); pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); } -void channel_1_stop(void) { pwmStop(&AUDIO_PWM_DRIVER); } +void channel_1_stop(void) { + pwmStop(&AUDIO_PWM_DRIVER); +} static void gpt_callback(GPTDriver *gptp); GPTConfig gptCFG = { @@ -108,9 +112,9 @@ void audio_driver_initialize(void) { pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); // connect the AUDIO_PIN to the PWM hardware -#if defined(USE_GPIOV1) // STM32F103C8 +#if defined(USE_GPIOV1) // STM32F103C8 palSetLineMode(AUDIO_PIN, PAL_MODE_ALTERNATE_PUSHPULL); -#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) +#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) palSetLineMode(AUDIO_PIN, PAL_MODE_ALTERNATE(AUDIO_PWM_PAL_MODE)); #endif @@ -135,10 +139,10 @@ void audio_driver_stop(void) { * and updates the pwm to output that frequency */ static void gpt_callback(GPTDriver *gptp) { - float freq; // TODO: freq_alt + float freq; // TODO: freq_alt if (audio_update_state()) { - freq = audio_get_processed_frequency(0); // freq_alt would be index=1 + freq = audio_get_processed_frequency(0); // freq_alt would be index=1 channel_1_set_frequency(freq); } } diff --git a/platforms/chibios/drivers/audio_pwm_software.c b/platforms/chibios/drivers/audio_pwm_software.c index 15c3e98b6a..e01f86ea52 100644 --- a/platforms/chibios/drivers/audio_pwm_software.c +++ b/platforms/chibios/drivers/audio_pwm_software.c @@ -57,7 +57,7 @@ static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { channel_1_frequency = freq; - if (freq <= 0.0) // a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; pwmcnt_t period = (pwmCFG.frequency / freq); @@ -68,7 +68,9 @@ void channel_1_set_frequency(float freq) { PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); } -float channel_1_get_frequency(void) { return channel_1_frequency; } +float channel_1_get_frequency(void) { + return channel_1_frequency; +} void channel_1_start(void) { pwmStop(&AUDIO_PWM_DRIVER); @@ -81,10 +83,10 @@ void channel_1_start(void) { void channel_1_stop(void) { pwmStop(&AUDIO_PWM_DRIVER); - palClearLine(AUDIO_PIN); // leave the line low, after last note was played + palClearLine(AUDIO_PIN); // leave the line low, after last note was played #if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) - palClearLine(AUDIO_PIN_ALT); // leave the line low, after last note was played + palClearLine(AUDIO_PIN_ALT); // leave the line low, after last note was played #endif } @@ -100,7 +102,7 @@ static void pwm_audio_period_callback(PWMDriver *pwmp) { static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; if (channel_1_frequency > 0) { - palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not necessarily the one connected to the timer + palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not necessarily the one connected to the timer #if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) palClearLine(AUDIO_PIN_ALT); #endif @@ -131,7 +133,7 @@ void audio_driver_initialize(void) { palClearLine(AUDIO_PIN_ALT); #endif - pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER); // enable pwm callbacks + pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER); // enable pwm callbacks pwmEnableChannelNotification(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1); gptStart(&AUDIO_STATE_TIMER, &gptCFG); @@ -155,10 +157,10 @@ void audio_driver_stop(void) { * and updates the pwm to output that frequency */ static void gpt_callback(GPTDriver *gptp) { - float freq; // TODO: freq_alt + float freq; // TODO: freq_alt if (audio_update_state()) { - freq = audio_get_processed_frequency(0); // freq_alt would be index=1 + freq = audio_get_processed_frequency(0); // freq_alt would be index=1 channel_1_set_frequency(freq); } } diff --git a/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h b/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h index a35defca8b..616d7ccbee 100644 --- a/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h +++ b/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h @@ -24,7 +24,7 @@ # define STM32_ONBOARD_EEPROM_SIZE 1024 # else # include "eeconfig.h" -# 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 +# 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 # endif #endif diff --git a/platforms/chibios/drivers/i2c_master.c b/platforms/chibios/drivers/i2c_master.c index 43591d56f8..d10bdbabc1 100644 --- a/platforms/chibios/drivers/i2c_master.c +++ b/platforms/chibios/drivers/i2c_master.c @@ -27,8 +27,67 @@ #include "quantum.h" #include "i2c_master.h" #include <string.h> +#include <ch.h> #include <hal.h> +#ifndef I2C1_SCL_PIN +# define I2C1_SCL_PIN B6 +#endif +#ifndef I2C1_SDA_PIN +# define I2C1_SDA_PIN B7 +#endif + +#ifdef USE_I2CV1 +# ifndef I2C1_OPMODE +# define I2C1_OPMODE OPMODE_I2C +# endif +# ifndef I2C1_CLOCK_SPEED +# define I2C1_CLOCK_SPEED 100000 /* 400000 */ +# endif +# ifndef I2C1_DUTY_CYCLE +# define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */ +# endif +#else +// The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock +// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html +# ifndef I2C1_TIMINGR_PRESC +# define I2C1_TIMINGR_PRESC 0U +# endif +# ifndef I2C1_TIMINGR_SCLDEL +# define I2C1_TIMINGR_SCLDEL 7U +# endif +# ifndef I2C1_TIMINGR_SDADEL +# define I2C1_TIMINGR_SDADEL 0U +# endif +# ifndef I2C1_TIMINGR_SCLH +# define I2C1_TIMINGR_SCLH 38U +# endif +# ifndef I2C1_TIMINGR_SCLL +# define I2C1_TIMINGR_SCLL 129U +# endif +#endif + +#ifndef I2C_DRIVER +# define I2C_DRIVER I2CD1 +#endif + +#ifdef USE_GPIOV1 +# ifndef I2C1_SCL_PAL_MODE +# define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN +# endif +# ifndef I2C1_SDA_PAL_MODE +# define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN +# endif +#else +// The default PAL alternate modes are used to signal that the pins are used for I2C +# ifndef I2C1_SCL_PAL_MODE +# define I2C1_SCL_PAL_MODE 4 +# endif +# ifndef I2C1_SDA_PAL_MODE +# define I2C1_SDA_PAL_MODE 4 +# endif +#endif + static uint8_t i2c_address; static const I2CConfig i2cconfig = { @@ -144,4 +203,6 @@ i2c_status_t i2c_readReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uin return chibios_to_qmk(&status); } -void i2c_stop(void) { i2cStop(&I2C_DRIVER); } +void i2c_stop(void) { + i2cStop(&I2C_DRIVER); +} diff --git a/platforms/chibios/drivers/i2c_master.h b/platforms/chibios/drivers/i2c_master.h index 5f082e9d1e..deee7ecc08 100644 --- a/platforms/chibios/drivers/i2c_master.h +++ b/platforms/chibios/drivers/i2c_master.h @@ -24,66 +24,7 @@ */ #pragma once -#include <ch.h> -#include <hal.h> - -#ifndef I2C1_SCL_PIN -# define I2C1_SCL_PIN B6 -#endif -#ifndef I2C1_SDA_PIN -# define I2C1_SDA_PIN B7 -#endif - -#ifdef USE_I2CV1 -# ifndef I2C1_OPMODE -# define I2C1_OPMODE OPMODE_I2C -# endif -# ifndef I2C1_CLOCK_SPEED -# define I2C1_CLOCK_SPEED 100000 /* 400000 */ -# endif -# ifndef I2C1_DUTY_CYCLE -# define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */ -# endif -#else -// The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock -// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html -# ifndef I2C1_TIMINGR_PRESC -# define I2C1_TIMINGR_PRESC 0U -# endif -# ifndef I2C1_TIMINGR_SCLDEL -# define I2C1_TIMINGR_SCLDEL 7U -# endif -# ifndef I2C1_TIMINGR_SDADEL -# define I2C1_TIMINGR_SDADEL 0U -# endif -# ifndef I2C1_TIMINGR_SCLH -# define I2C1_TIMINGR_SCLH 38U -# endif -# ifndef I2C1_TIMINGR_SCLL -# define I2C1_TIMINGR_SCLL 129U -# endif -#endif - -#ifndef I2C_DRIVER -# define I2C_DRIVER I2CD1 -#endif - -#ifdef USE_GPIOV1 -# ifndef I2C1_SCL_PAL_MODE -# define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN -# endif -# ifndef I2C1_SDA_PAL_MODE -# define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN -# endif -#else -// The default PAL alternate modes are used to signal that the pins are used for I2C -# ifndef I2C1_SCL_PAL_MODE -# define I2C1_SCL_PAL_MODE 4 -# endif -# ifndef I2C1_SDA_PAL_MODE -# define I2C1_SDA_PAL_MODE 4 -# endif -#endif +#include <stdint.h> typedef int16_t i2c_status_t; diff --git a/platforms/chibios/drivers/serial.c b/platforms/chibios/drivers/serial.c index ef6f0aa8d5..6db5d85250 100644 --- a/platforms/chibios/drivers/serial.c +++ b/platforms/chibios/drivers/serial.c @@ -50,14 +50,30 @@ # error invalid SELECT_SOFT_SERIAL_SPEED value #endif -inline static void serial_delay(void) { wait_us(SERIAL_DELAY); } -inline static void serial_delay_half(void) { wait_us(SERIAL_DELAY / 2); } -inline static void serial_delay_blip(void) { wait_us(1); } -inline static void serial_output(void) { setPinOutput(SOFT_SERIAL_PIN); } -inline static void serial_input(void) { setPinInputHigh(SOFT_SERIAL_PIN); } -inline static bool serial_read_pin(void) { return !!readPin(SOFT_SERIAL_PIN); } -inline static void serial_low(void) { writePinLow(SOFT_SERIAL_PIN); } -inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); } +inline static void serial_delay(void) { + wait_us(SERIAL_DELAY); +} +inline static void serial_delay_half(void) { + wait_us(SERIAL_DELAY / 2); +} +inline static void serial_delay_blip(void) { + wait_us(1); +} +inline static void serial_output(void) { + setPinOutput(SOFT_SERIAL_PIN); +} +inline static void serial_input(void) { + setPinInputHigh(SOFT_SERIAL_PIN); +} +inline static bool serial_read_pin(void) { + return !!readPin(SOFT_SERIAL_PIN); +} +inline static void serial_low(void) { + writePinLow(SOFT_SERIAL_PIN); +} +inline static void serial_high(void) { + writePinHigh(SOFT_SERIAL_PIN); +} void interrupt_handler(void *arg); @@ -179,8 +195,6 @@ void interrupt_handler(void *arg) { // wait for the sync to finish sending serial_delay(); - *trans->status = (checksum_computed == checksum_received) ? TRANSACTION_ACCEPTED : TRANSACTION_DATA_ERROR; - // end transaction serial_input(); @@ -193,17 +207,12 @@ void interrupt_handler(void *arg) { ///////// // start transaction by initiator // -// int soft_serial_transaction(int sstd_index) +// bool soft_serial_transaction(int sstd_index) // -// Returns: -// TRANSACTION_END -// TRANSACTION_NO_RESPONSE -// TRANSACTION_DATA_ERROR // this code is very time dependent, so we need to disable interrupts -int soft_serial_transaction(int sstd_index) { - if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR; +bool soft_serial_transaction(int sstd_index) { + if (sstd_index > NUM_TOTAL_TRANSACTIONS) return false; split_transaction_desc_t *trans = &split_transaction_table[sstd_index]; - if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered // TODO: remove extra delay between transactions serial_delay(); @@ -226,14 +235,14 @@ int soft_serial_transaction(int sstd_index) { // slave failed to pull the line low, assume not present dprintf("serial::NO_RESPONSE\n"); chSysUnlock(); - return TRANSACTION_NO_RESPONSE; + return false; } // if the slave is present syncronize with it uint8_t checksum = 0; // send data to the slave - serial_write_byte(sstd_index); // first chunk is transaction id + serial_write_byte(sstd_index); // first chunk is transaction id sync_recv(); for (int i = 0; i < trans->initiator2target_buffer_size; ++i) { @@ -245,7 +254,7 @@ int soft_serial_transaction(int sstd_index) { sync_recv(); serial_delay(); - serial_delay(); // read mid pulses + serial_delay(); // read mid pulses // receive data from the slave uint8_t checksum_computed = 0; @@ -266,7 +275,7 @@ int soft_serial_transaction(int sstd_index) { serial_high(); chSysUnlock(); - return TRANSACTION_DATA_ERROR; + return false; } // always, release the line when not in use @@ -274,5 +283,5 @@ int soft_serial_transaction(int sstd_index) { serial_output(); chSysUnlock(); - return TRANSACTION_END; + return true; } diff --git a/platforms/chibios/drivers/serial_usart.c b/platforms/chibios/drivers/serial_usart.c index 124e4be685..85c64214d1 100644 --- a/platforms/chibios/drivers/serial_usart.c +++ b/platforms/chibios/drivers/serial_usart.c @@ -36,7 +36,7 @@ static SerialDriver* serial_driver = &SERIAL_USART_DRIVER; static inline bool react_to_transactions(void); static inline bool __attribute__((nonnull)) receive(uint8_t* destination, const size_t size); static inline bool __attribute__((nonnull)) send(const uint8_t* source, const size_t size); -static inline int initiate_transaction(uint8_t sstd_index); +static inline bool initiate_transaction(uint8_t sstd_index); static inline void usart_clear(void); /** @@ -206,14 +206,12 @@ static inline bool react_to_transactions(void) { to signal that the slave is ready to receive possible transaction buffers */ sstd_index ^= HANDSHAKE_MAGIC; if (!send(&sstd_index, sizeof(sstd_index))) { - *trans->status = TRANSACTION_DATA_ERROR; return false; } /* Receive transaction buffer from the master. If this transaction requires it.*/ if (trans->initiator2target_buffer_size) { if (!receive(split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) { - *trans->status = TRANSACTION_DATA_ERROR; return false; } } @@ -226,12 +224,10 @@ static inline bool react_to_transactions(void) { /* Send transaction buffer to the master. If this transaction requires it. */ if (trans->target2initiator_buffer_size) { if (!send(split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) { - *trans->status = TRANSACTION_DATA_ERROR; return false; } } - *trans->status = TRANSACTION_ACCEPTED; return true; } @@ -242,7 +238,7 @@ void soft_serial_initiator_init(void) { usart_master_init(&serial_driver); #if defined(MCU_STM32) && defined(SERIAL_USART_PIN_SWAP) - serial_config.cr2 |= USART_CR2_SWAP; // master has swapped TX/RX pins + serial_config.cr2 |= USART_CR2_SWAP; // master has swapped TX/RX pins #endif sdStart(serial_driver, &serial_config); @@ -252,11 +248,9 @@ void soft_serial_initiator_init(void) { * @brief Start transaction from the master half to the slave half. * * @param index Transaction Table index of the transaction to start. - * @return int TRANSACTION_NO_RESPONSE in case of Timeout. - * TRANSACTION_TYPE_ERROR in case of invalid transaction index. - * TRANSACTION_END in case of success. + * @return bool Indicates success of transaction. */ -int soft_serial_transaction(int index) { +bool soft_serial_transaction(int index) { /* Clear the receive queue, to start with a clean slate. * Parts of failed transactions or spurious bytes could still be in it. */ usart_clear(); @@ -266,25 +260,19 @@ int soft_serial_transaction(int index) { /** * @brief Initiate transaction to slave half. */ -static inline int initiate_transaction(uint8_t sstd_index) { +static inline bool initiate_transaction(uint8_t sstd_index) { /* Sanity check that we are actually starting a valid transaction. */ if (sstd_index >= NUM_TOTAL_TRANSACTIONS) { dprintln("USART: Illegal transaction Id."); - return TRANSACTION_TYPE_ERROR; + return false; } split_transaction_desc_t* trans = &split_transaction_table[sstd_index]; - /* Transaction is not registered. Abort. */ - if (!trans->status) { - dprintln("USART: Transaction not registered."); - return TRANSACTION_TYPE_ERROR; - } - /* Send transaction table index to the slave, which doubles as basic handshake token. */ if (!send(&sstd_index, sizeof(sstd_index))) { dprintln("USART: Send Handshake failed."); - return TRANSACTION_TYPE_ERROR; + return false; } uint8_t sstd_index_shake = 0xFF; @@ -295,14 +283,14 @@ static inline int initiate_transaction(uint8_t sstd_index) { */ if (!receive(&sstd_index_shake, sizeof(sstd_index_shake)) || (sstd_index_shake != (sstd_index ^ HANDSHAKE_MAGIC))) { dprintln("USART: Handshake failed."); - return TRANSACTION_NO_RESPONSE; + return false; } /* Send transaction buffer to the slave. If this transaction requires it. */ if (trans->initiator2target_buffer_size) { if (!send(split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) { dprintln("USART: Send failed."); - return TRANSACTION_NO_RESPONSE; + return false; } } @@ -310,9 +298,9 @@ static inline int initiate_transaction(uint8_t sstd_index) { if (trans->target2initiator_buffer_size) { if (!receive(split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) { dprintln("USART: Receive failed."); - return TRANSACTION_NO_RESPONSE; + return false; } } - return TRANSACTION_END; + return true; } diff --git a/platforms/chibios/drivers/serial_usart.h b/platforms/chibios/drivers/serial_usart.h index 7b135b31e0..81fe9e0113 100644 --- a/platforms/chibios/drivers/serial_usart.h +++ b/platforms/chibios/drivers/serial_usart.h @@ -50,15 +50,15 @@ #endif #if !defined(USART_CR1_M0) -# define USART_CR1_M0 USART_CR1_M // some platforms (f1xx) dont have this so +# define USART_CR1_M0 USART_CR1_M // some platforms (f1xx) dont have this so #endif #if !defined(SERIAL_USART_CR1) -# define SERIAL_USART_CR1 (USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0) // parity enable, odd parity, 9 bit length +# define SERIAL_USART_CR1 (USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0) // parity enable, odd parity, 9 bit length #endif #if !defined(SERIAL_USART_CR2) -# define SERIAL_USART_CR2 (USART_CR2_STOP_1) // 2 stop bits +# define SERIAL_USART_CR2 (USART_CR2_STOP_1) // 2 stop bits #endif #if !defined(SERIAL_USART_CR3) diff --git a/platforms/chibios/drivers/spi_master.c b/platforms/chibios/drivers/spi_master.c index dde0bb0597..998bace550 100644 --- a/platforms/chibios/drivers/spi_master.c +++ b/platforms/chibios/drivers/spi_master.c @@ -115,7 +115,7 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { #elif defined(HT32) spiConfig.cr0 = SPI_CR0_SELOEN; - spiConfig.cr1 = SPI_CR1_MODE | 8; // 8 bits and in master mode + spiConfig.cr1 = SPI_CR1_MODE | 8; // 8 bits and in master mode if (lsbFirst) { spiConfig.cr1 |= SPI_CR1_FIRSTBIT; diff --git a/platforms/chibios/drivers/uart.c b/platforms/chibios/drivers/uart.c index d2ea5d6415..4884d7024f 100644 --- a/platforms/chibios/drivers/uart.c +++ b/platforms/chibios/drivers/uart.c @@ -43,7 +43,9 @@ void uart_init(uint32_t baud) { } } -void uart_write(uint8_t data) { sdPut(&SERIAL_DRIVER, c); } +void uart_write(uint8_t data) { + sdPut(&SERIAL_DRIVER, data); +} uint8_t uart_read(void) { msg_t res = sdGet(&SERIAL_DRIVER); @@ -51,8 +53,14 @@ uint8_t uart_read(void) { return (uint8_t)res; } -void uart_transmit(const uint8_t *data, uint16_t length) { sdWrite(&SERIAL_DRIVER, data, length); } +void uart_transmit(const uint8_t *data, uint16_t length) { + sdWrite(&SERIAL_DRIVER, data, length); +} -void uart_receive(uint8_t *data, uint16_t length) { sdRead(&SERIAL_DRIVER, data, length); } +void uart_receive(uint8_t *data, uint16_t length) { + sdRead(&SERIAL_DRIVER, data, length); +} -bool uart_available(void) { return !sdGetWouldBlock(&SERIAL_DRIVER); } +bool uart_available(void) { + return !sdGetWouldBlock(&SERIAL_DRIVER); +} diff --git a/platforms/chibios/drivers/usbpd_stm32g4.c b/platforms/chibios/drivers/usbpd_stm32g4.c index f16ca8aeae..0096f22f07 100644 --- a/platforms/chibios/drivers/usbpd_stm32g4.c +++ b/platforms/chibios/drivers/usbpd_stm32g4.c @@ -18,7 +18,7 @@ #ifndef USBPD_UCPD1_CFG1 # define USBPD_UCPD1_CFG1 (UCPD_CFG1_PSC_UCPDCLK_0 | UCPD_CFG1_TRANSWIN_3 | UCPD_CFG1_IFRGAP_4 | UCPD_CFG1_HBITCLKDIV_4) -#endif // USBPD_UCPD1_CFG1 +#endif // USBPD_UCPD1_CFG1 // Initialises the USBPD subsystem __attribute__((weak)) void usbpd_init(void) { @@ -64,7 +64,7 @@ __attribute__((weak)) usbpd_allowance_t usbpd_get_allowance(void) { switch (vstate_max) { case 0: case 1: - 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. + 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. case 2: return USBPD_1500MA; case 3: diff --git a/platforms/chibios/drivers/ws2812.c b/platforms/chibios/drivers/ws2812.c index 7e870661de..1b3bb59842 100644 --- a/platforms/chibios/drivers/ws2812.c +++ b/platforms/chibios/drivers/ws2812.c @@ -10,7 +10,7 @@ # define NOP_FUDGE 0.4 # else # error("NOP_FUDGE configuration required") -# define NOP_FUDGE 1 // this just pleases the compile so the above error is easier to spot +# define NOP_FUDGE 1 // this just pleases the compile so the above error is easier to spot # endif #endif @@ -25,12 +25,12 @@ // The reset gap can be 6000 ns, but depending on the LED strip it may have to be increased // to values like 600000 ns. If it is too small, the pixels will show nothing most of the time. #ifndef WS2812_RES -# define WS2812_RES (1000 * WS2812_TRST_US) // Width of the low gap between bits to cause a frame to latch +# define WS2812_RES (1000 * WS2812_TRST_US) // Width of the low gap between bits to cause a frame to latch #endif #define NUMBER_NOPS 6 #define CYCLES_PER_SEC (CPU_CLOCK / NUMBER_NOPS * NOP_FUDGE) -#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 +#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 #define NS_PER_CYCLE (NS_PER_SEC / CYCLES_PER_SEC) #define NS_TO_CYCLES(n) ((n) / NS_PER_CYCLE) @@ -67,7 +67,9 @@ void sendByte(uint8_t byte) { } } -void ws2812_init(void) { palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE); } +void ws2812_init(void) { + palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE); +} // Setleds for standard RGB void ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) { diff --git a/platforms/chibios/drivers/ws2812_pwm.c b/platforms/chibios/drivers/ws2812_pwm.c index 19ea3cfe8a..57187676d7 100644 --- a/platforms/chibios/drivers/ws2812_pwm.c +++ b/platforms/chibios/drivers/ws2812_pwm.c @@ -11,19 +11,19 @@ #endif #ifndef WS2812_PWM_DRIVER -# define WS2812_PWM_DRIVER PWMD2 // TIMx +# define WS2812_PWM_DRIVER PWMD2 // TIMx #endif #ifndef WS2812_PWM_CHANNEL -# define WS2812_PWM_CHANNEL 2 // Channel +# define WS2812_PWM_CHANNEL 2 // Channel #endif #ifndef WS2812_PWM_PAL_MODE -# define WS2812_PWM_PAL_MODE 2 // DI Pin's alternate function value +# define WS2812_PWM_PAL_MODE 2 // DI Pin's alternate function value #endif #ifndef WS2812_DMA_STREAM -# define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP +# define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP #endif #ifndef WS2812_DMA_CHANNEL -# define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP +# define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP #endif #if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && !defined(WS2812_DMAMUX_ID) # error "please consult your MCU's datasheet and specify in your config.h: #define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM?_UP" @@ -56,7 +56,7 @@ #ifndef WS2812_PWM_TARGET_PERIOD //# define WS2812_PWM_TARGET_PERIOD 800000 // Original code is 800k...? -# define WS2812_PWM_TARGET_PERIOD 80000 // TODO: work out why 10x less on f303/f4x1 +# define WS2812_PWM_TARGET_PERIOD 80000 // TODO: work out why 10x less on f303/f4x1 #endif /* --- PRIVATE CONSTANTS ---------------------------------------------------- */ @@ -259,8 +259,10 @@ write/read to/from the other buffer). void ws2812_init(void) { // Initialize led frame buffer uint32_t i; - for (i = 0; i < WS2812_COLOR_BIT_N; i++) ws2812_frame_buffer[i] = WS2812_DUTYCYCLE_0; // All color bits are zero duty cycle - for (i = 0; i < WS2812_RESET_BIT_N; i++) ws2812_frame_buffer[i + WS2812_COLOR_BIT_N] = 0; // All reset bits are zero + for (i = 0; i < WS2812_COLOR_BIT_N; i++) + ws2812_frame_buffer[i] = WS2812_DUTYCYCLE_0; // All color bits are zero duty cycle + for (i = 0; i < WS2812_RESET_BIT_N; i++) + ws2812_frame_buffer[i + WS2812_COLOR_BIT_N] = 0; // All reset bits are zero palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE); @@ -268,22 +270,22 @@ void ws2812_init(void) { //#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 static const PWMConfig ws2812_pwm_config = { .frequency = WS2812_PWM_FREQUENCY, - .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 + .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 .callback = NULL, .channels = { - [0 ... 3] = {.mode = PWM_OUTPUT_DISABLED, .callback = NULL}, // Channels default to disabled - [WS2812_PWM_CHANNEL - 1] = {.mode = WS2812_PWM_OUTPUT_MODE, .callback = NULL}, // Turn on the channel we care about + [0 ... 3] = {.mode = PWM_OUTPUT_DISABLED, .callback = NULL}, // Channels default to disabled + [WS2812_PWM_CHANNEL - 1] = {.mode = WS2812_PWM_OUTPUT_MODE, .callback = NULL}, // Turn on the channel we care about }, .cr2 = 0, - .dier = TIM_DIER_UDE, // DMA on update event for next period + .dier = TIM_DIER_UDE, // DMA on update event for next period }; //#pragma GCC diagnostic pop // Restore command-line warning options // Configure DMA // dmaInit(); // Joe added this dmaStreamAlloc(WS2812_DMA_STREAM - STM32_DMA_STREAM(0), 10, NULL, NULL); - dmaStreamSetPeripheral(WS2812_DMA_STREAM, &(WS2812_PWM_DRIVER.tim->CCR[WS2812_PWM_CHANNEL - 1])); // Ziel ist der An-Zeit im Cap-Comp-Register + dmaStreamSetPeripheral(WS2812_DMA_STREAM, &(WS2812_PWM_DRIVER.tim->CCR[WS2812_PWM_CHANNEL - 1])); // Ziel ist der An-Zeit im Cap-Comp-Register dmaStreamSetMemory0(WS2812_DMA_STREAM, ws2812_frame_buffer); dmaStreamSetTransactionSize(WS2812_DMA_STREAM, WS2812_BIT_N); 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)); @@ -302,7 +304,7 @@ void ws2812_init(void) { // 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, // disable counting, enable the channel, and then make whatever configuration changes we need. pwmStart(&WS2812_PWM_DRIVER, &ws2812_pwm_config); - 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 + 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 } void ws2812_write_led(uint16_t led_number, uint8_t r, uint8_t g, uint8_t b) { diff --git a/platforms/chibios/drivers/ws2812_spi.c b/platforms/chibios/drivers/ws2812_spi.c index ba471e0b8e..76191db165 100644 --- a/platforms/chibios/drivers/ws2812_spi.c +++ b/platforms/chibios/drivers/ws2812_spi.c @@ -42,7 +42,7 @@ # define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_0) #elif WS2812_SPI_DIVISOR == 8 # define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_1) -#elif WS2812_SPI_DIVISOR == 16 // same as default +#elif WS2812_SPI_DIVISOR == 16 // same as default # define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_1 | SPI_CR1_BR_0) #elif WS2812_SPI_DIVISOR == 32 # define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_2) @@ -53,14 +53,14 @@ #elif WS2812_SPI_DIVISOR == 256 # define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0) #else -# define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_1 | SPI_CR1_BR_0) // default +# define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_1 | SPI_CR1_BR_0) // default #endif // Use SPI circular buffer #ifdef WS2812_SPI_USE_CIRCULAR_BUFFER -# define WS2812_SPI_BUFFER_MODE 1 // circular buffer +# define WS2812_SPI_BUFFER_MODE 1 // circular buffer #else -# define WS2812_SPI_BUFFER_MODE 0 // normal buffer +# define WS2812_SPI_BUFFER_MODE 0 // normal buffer #endif #if defined(USE_GPIOV1) @@ -104,20 +104,30 @@ static void set_led_color_rgb(LED_TYPE color, int pos) { uint8_t* tx_start = &txbuf[PREAMBLE_SIZE]; #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB) - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.g, j); - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.r, j); - 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); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.g, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.r, j); + 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); #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB) - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.r, j); - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j); - 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); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.r, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j); + 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); #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.b, j); - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j); - 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); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.b, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j); + 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); #endif #ifdef RGBW - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 4 + j] = get_protocol_eq(color.w, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 4 + j] = get_protocol_eq(color.w, j); #endif } @@ -126,7 +136,7 @@ void ws2812_init(void) { #ifdef WS2812_SPI_SCK_PIN palSetLineMode(WS2812_SPI_SCK_PIN, WS2812_SCK_OUTPUT_MODE); -#endif // WS2812_SPI_SCK_PIN +#endif // WS2812_SPI_SCK_PIN // TODO: more dynamic baudrate static const SPIConfig spicfg = {WS2812_SPI_BUFFER_MODE, NULL, PAL_PORT(RGB_DI_PIN), PAL_PAD(RGB_DI_PIN), WS2812_SPI_DIVISOR_CR1_BR_X}; diff --git a/platforms/chibios/eeprom_stm32.c b/platforms/chibios/eeprom_stm32.c index acc6a48516..a15bfe09ed 100644 --- a/platforms/chibios/eeprom_stm32.c +++ b/platforms/chibios/eeprom_stm32.c @@ -133,10 +133,6 @@ */ #include "eeprom_stm32_defs.h" -#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) || !defined(FEE_MCU_FLASH_SIZE) || !defined(FEE_PAGE_BASE_ADDRESS) -# error "not implemented." -#endif - /* These bits are used for optimizing encoding of bytes, 0 and 1 */ #define FEE_WORD_ENCODING 0x8000 #define FEE_VALUE_NEXT 0x6000 @@ -144,69 +140,11 @@ #define FEE_VALUE_ENCODED 0x2000 #define FEE_BYTE_RANGE 0x80 -/* Addressable range 16KByte: 0 <-> (0x1FFF << 1) */ -#define FEE_ADDRESS_MAX_SIZE 0x4000 - /* Flash word value after erase */ #define FEE_EMPTY_WORD ((uint16_t)0xFFFF) -/* Size of combined compacted eeprom and write log pages */ -#define FEE_DENSITY_MAX_SIZE (FEE_PAGE_COUNT * FEE_PAGE_SIZE) - -#ifndef FEE_MCU_FLASH_SIZE_IGNORE_CHECK /* *TODO: Get rid of this check */ -# if FEE_DENSITY_MAX_SIZE > (FEE_MCU_FLASH_SIZE * 1024) -# pragma message STR(FEE_DENSITY_MAX_SIZE) " > " STR(FEE_MCU_FLASH_SIZE * 1024) -# error emulated eeprom: FEE_DENSITY_MAX_SIZE is greater than available flash size -# endif -#endif - -/* Size of emulated eeprom */ -#ifdef FEE_DENSITY_BYTES -# if (FEE_DENSITY_BYTES > FEE_DENSITY_MAX_SIZE) -# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) -# error emulated eeprom: FEE_DENSITY_BYTES exceeds FEE_DENSITY_MAX_SIZE -# endif -# if (FEE_DENSITY_BYTES == FEE_DENSITY_MAX_SIZE) -# pragma message STR(FEE_DENSITY_BYTES) " == " STR(FEE_DENSITY_MAX_SIZE) -# warning emulated eeprom: FEE_DENSITY_BYTES leaves no room for a write log. This will greatly increase the flash wear rate! -# endif -# if FEE_DENSITY_BYTES > FEE_ADDRESS_MAX_SIZE -# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_ADDRESS_MAX_SIZE) -# error emulated eeprom: FEE_DENSITY_BYTES is greater than FEE_ADDRESS_MAX_SIZE allows -# endif -# if ((FEE_DENSITY_BYTES) % 2) == 1 -# error emulated eeprom: FEE_DENSITY_BYTES must be even -# endif -#else -/* Default to half of allocated space used for emulated eeprom, half for write log */ -# define FEE_DENSITY_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE / 2) -#endif - -/* Size of write log */ -#ifdef FEE_WRITE_LOG_BYTES -# if ((FEE_DENSITY_BYTES + FEE_WRITE_LOG_BYTES) > FEE_DENSITY_MAX_SIZE) -# pragma message STR(FEE_DENSITY_BYTES) " + " STR(FEE_WRITE_LOG_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) -# error emulated eeprom: FEE_WRITE_LOG_BYTES exceeds remaining FEE_DENSITY_MAX_SIZE -# endif -# if ((FEE_WRITE_LOG_BYTES) % 2) == 1 -# error emulated eeprom: FEE_WRITE_LOG_BYTES must be even -# endif -#else -/* Default to use all remaining space */ -# define FEE_WRITE_LOG_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE - FEE_DENSITY_BYTES) -#endif - -/* Start of the emulated eeprom compacted flash area */ -#define FEE_COMPACTED_BASE_ADDRESS FEE_PAGE_BASE_ADDRESS -/* End of the emulated eeprom compacted flash area */ -#define FEE_COMPACTED_LAST_ADDRESS (FEE_COMPACTED_BASE_ADDRESS + FEE_DENSITY_BYTES) -/* Start of the emulated eeprom write log */ -#define FEE_WRITE_LOG_BASE_ADDRESS FEE_COMPACTED_LAST_ADDRESS -/* End of the emulated eeprom write log */ -#define FEE_WRITE_LOG_LAST_ADDRESS (FEE_WRITE_LOG_BASE_ADDRESS + FEE_WRITE_LOG_BYTES) - -#if defined(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) && (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR >= FEE_DENSITY_BYTES) -# error emulated eeprom: DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is greater than the FEE_DENSITY_BYTES available +#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) || !defined(FEE_MCU_FLASH_SIZE) || !defined(FEE_PAGE_BASE_ADDRESS) +# error "not implemented." #endif /* In-memory contents of emulated eeprom for faster access */ @@ -622,9 +560,13 @@ uint16_t EEPROM_ReadDataWord(uint16_t Address) { /***************************************************************************** * Bind to eeprom_driver.c *******************************************************************************/ -void eeprom_driver_init(void) { EEPROM_Init(); } +void eeprom_driver_init(void) { + EEPROM_Init(); +} -void eeprom_driver_erase(void) { EEPROM_Erase(); } +void eeprom_driver_erase(void) { + EEPROM_Erase(); +} void eeprom_read_block(void *buf, const void *addr, size_t len) { const uint8_t *src = (const uint8_t *)addr; diff --git a/platforms/chibios/eeprom_stm32_defs.h b/platforms/chibios/eeprom_stm32_defs.h index 66904f247f..a6ceb41355 100644 --- a/platforms/chibios/eeprom_stm32_defs.h +++ b/platforms/chibios/eeprom_stm32_defs.h @@ -20,41 +20,41 @@ #if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) # if defined(STM32F103xB) || defined(STM32F042x6) || defined(GD32VF103C8) || defined(GD32VF103CB) # ifndef FEE_PAGE_SIZE -# define FEE_PAGE_SIZE 0x400 // Page size = 1KByte +# define FEE_PAGE_SIZE 0x400 // Page size = 1KByte # endif # ifndef FEE_PAGE_COUNT -# define FEE_PAGE_COUNT 2 // How many pages are used +# define FEE_PAGE_COUNT 2 // How many pages are used # endif # elif defined(STM32F103xE) || defined(STM32F303xC) || defined(STM32F072xB) || defined(STM32F070xB) # ifndef FEE_PAGE_SIZE -# define FEE_PAGE_SIZE 0x800 // Page size = 2KByte +# define FEE_PAGE_SIZE 0x800 // Page size = 2KByte # endif # ifndef FEE_PAGE_COUNT -# define FEE_PAGE_COUNT 4 // How many pages are used +# define FEE_PAGE_COUNT 4 // How many pages are used # endif # elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xG) || defined(STM32F411xE) # ifndef FEE_PAGE_SIZE -# define FEE_PAGE_SIZE 0x4000 // Page size = 16KByte +# define FEE_PAGE_SIZE 0x4000 // Page size = 16KByte # endif # ifndef FEE_PAGE_COUNT -# define FEE_PAGE_COUNT 1 // How many pages are used +# define FEE_PAGE_COUNT 1 // How many pages are used # endif # endif #endif #if !defined(FEE_MCU_FLASH_SIZE) # if defined(STM32F042x6) -# define FEE_MCU_FLASH_SIZE 32 // Size in Kb +# define FEE_MCU_FLASH_SIZE 32 // Size in Kb # elif defined(GD32VF103C8) -# define FEE_MCU_FLASH_SIZE 64 // Size in Kb +# define FEE_MCU_FLASH_SIZE 64 // Size in Kb # elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) || defined(GD32VF103CB) -# define FEE_MCU_FLASH_SIZE 128 // Size in Kb +# define FEE_MCU_FLASH_SIZE 128 // Size in Kb # elif defined(STM32F303xC) || defined(STM32F401xC) -# define FEE_MCU_FLASH_SIZE 256 // Size in Kb +# define FEE_MCU_FLASH_SIZE 256 // Size in Kb # elif defined(STM32F103xE) || defined(STM32F401xE) || defined(STM32F411xE) -# define FEE_MCU_FLASH_SIZE 512 // Size in Kb +# define FEE_MCU_FLASH_SIZE 512 // Size in Kb # elif defined(STM32F405xG) -# define FEE_MCU_FLASH_SIZE 1024 // Size in Kb +# define FEE_MCU_FLASH_SIZE 1024 // Size in Kb # endif #endif @@ -62,7 +62,7 @@ #if !defined(FEE_PAGE_BASE_ADDRESS) # if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xG) || defined(STM32F411xE) # ifndef FEE_PAGE_BASE_ADDRESS -# define FEE_PAGE_BASE_ADDRESS 0x08004000 // bodge to force 2nd 16k page +# define FEE_PAGE_BASE_ADDRESS 0x08004000 // bodge to force 2nd 16k page # endif # else # ifndef FEE_FLASH_BASE @@ -72,3 +72,65 @@ # define FEE_PAGE_BASE_ADDRESS ((uintptr_t)(FEE_FLASH_BASE) + FEE_MCU_FLASH_SIZE * 1024 - (FEE_PAGE_COUNT * FEE_PAGE_SIZE)) # endif #endif + +/* Addressable range 16KByte: 0 <-> (0x1FFF << 1) */ +#define FEE_ADDRESS_MAX_SIZE 0x4000 + +/* Size of combined compacted eeprom and write log pages */ +#define FEE_DENSITY_MAX_SIZE (FEE_PAGE_COUNT * FEE_PAGE_SIZE) + +#ifndef FEE_MCU_FLASH_SIZE_IGNORE_CHECK /* *TODO: Get rid of this check */ +# if FEE_DENSITY_MAX_SIZE > (FEE_MCU_FLASH_SIZE * 1024) +# pragma message STR(FEE_DENSITY_MAX_SIZE) " > " STR(FEE_MCU_FLASH_SIZE * 1024) +# error emulated eeprom: FEE_DENSITY_MAX_SIZE is greater than available flash size +# endif +#endif + +/* Size of emulated eeprom */ +#ifdef FEE_DENSITY_BYTES +# if (FEE_DENSITY_BYTES > FEE_DENSITY_MAX_SIZE) +# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) +# error emulated eeprom: FEE_DENSITY_BYTES exceeds FEE_DENSITY_MAX_SIZE +# endif +# if (FEE_DENSITY_BYTES == FEE_DENSITY_MAX_SIZE) +# pragma message STR(FEE_DENSITY_BYTES) " == " STR(FEE_DENSITY_MAX_SIZE) +# warning emulated eeprom: FEE_DENSITY_BYTES leaves no room for a write log. This will greatly increase the flash wear rate! +# endif +# if FEE_DENSITY_BYTES > FEE_ADDRESS_MAX_SIZE +# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_ADDRESS_MAX_SIZE) +# error emulated eeprom: FEE_DENSITY_BYTES is greater than FEE_ADDRESS_MAX_SIZE allows +# endif +# if ((FEE_DENSITY_BYTES) % 2) == 1 +# error emulated eeprom: FEE_DENSITY_BYTES must be even +# endif +#else +/* Default to half of allocated space used for emulated eeprom, half for write log */ +# define FEE_DENSITY_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE / 2) +#endif + +/* Size of write log */ +#ifdef FEE_WRITE_LOG_BYTES +# if ((FEE_DENSITY_BYTES + FEE_WRITE_LOG_BYTES) > FEE_DENSITY_MAX_SIZE) +# pragma message STR(FEE_DENSITY_BYTES) " + " STR(FEE_WRITE_LOG_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) +# error emulated eeprom: FEE_WRITE_LOG_BYTES exceeds remaining FEE_DENSITY_MAX_SIZE +# endif +# if ((FEE_WRITE_LOG_BYTES) % 2) == 1 +# error emulated eeprom: FEE_WRITE_LOG_BYTES must be even +# endif +#else +/* Default to use all remaining space */ +# define FEE_WRITE_LOG_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE - FEE_DENSITY_BYTES) +#endif + +/* Start of the emulated eeprom compacted flash area */ +#define FEE_COMPACTED_BASE_ADDRESS FEE_PAGE_BASE_ADDRESS +/* End of the emulated eeprom compacted flash area */ +#define FEE_COMPACTED_LAST_ADDRESS (FEE_COMPACTED_BASE_ADDRESS + FEE_DENSITY_BYTES) +/* Start of the emulated eeprom write log */ +#define FEE_WRITE_LOG_BASE_ADDRESS FEE_COMPACTED_LAST_ADDRESS +/* End of the emulated eeprom write log */ +#define FEE_WRITE_LOG_LAST_ADDRESS (FEE_WRITE_LOG_BASE_ADDRESS + FEE_WRITE_LOG_BYTES) + +#if defined(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) && (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR >= FEE_DENSITY_BYTES) +# error emulated eeprom: DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is greater than the FEE_DENSITY_BYTES available +#endif diff --git a/platforms/chibios/eeprom_teensy.c b/platforms/chibios/eeprom_teensy.c index 4aaf665269..c8777febde 100644 --- a/platforms/chibios/eeprom_teensy.c +++ b/platforms/chibios/eeprom_teensy.c @@ -1,6 +1,7 @@ #include <ch.h> #include <hal.h> +#include "eeprom_teensy.h" #include "eeconfig.h" /*************************************/ @@ -42,18 +43,6 @@ #if defined(K20x) /* chip selection */ /* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */ -// The EEPROM is really RAM with a hardware-based backup system to -// flash memory. Selecting a smaller size EEPROM allows more wear -// leveling, for higher write endurance. If you edit this file, -// set this to the smallest size your application can use. Also, -// due to Freescale's implementation, writing 16 or 32 bit words -// (aligned to 2 or 4 byte boundaries) has twice the endurance -// compared to writing 8 bit bytes. -// -# ifndef EEPROM_SIZE -# define EEPROM_SIZE 32 -# endif - /* ^^^ Here be dragons: NXP AppNote AN4282 section 3.1 states that partitioning must only be done once. @@ -71,19 +60,19 @@ // Minimum EEPROM Endurance // ------------------------ -# if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word +# if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word # define EEESIZE 0x33 -# elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word +# elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word # define EEESIZE 0x34 -# elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word +# elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word # define EEESIZE 0x35 -# elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word +# elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word # define EEESIZE 0x36 -# elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word +# elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word # define EEESIZE 0x37 -# elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word +# elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word # define EEESIZE 0x38 -# elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word +# elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word # define EEESIZE 0x39 # endif @@ -99,9 +88,9 @@ void eeprom_initialize(void) { if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) { // FlexRAM is configured as traditional RAM // We need to reconfigure for EEPROM usage - FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command - FTFL->FCCOB4 = EEESIZE; // EEPROM Size - FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup + FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command + FTFL->FCCOB4 = EEESIZE; // EEPROM Size + FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup __disable_irq(); // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple... (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT)); @@ -109,7 +98,7 @@ void eeprom_initialize(void) { status = FTFL->FSTAT; if (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)) { FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)); - return; // error + return; // error } } // wait for eeprom to become ready (is this really necessary?) @@ -173,7 +162,9 @@ void eeprom_read_block(void *buf, const void *addr, uint32_t len) { * * FIXME: needs doc */ -int eeprom_is_ready(void) { return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0; } +int eeprom_is_ready(void) { + return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0; +} /** \brief flexram wait * @@ -350,8 +341,6 @@ void do_flash_cmd(volatile uint8_t *fstat) extern uint32_t __eeprom_workarea_start__; extern uint32_t __eeprom_workarea_end__; -# define EEPROM_SIZE 128 - static uint32_t flashend = 0; void eeprom_initialize(void) { @@ -499,7 +488,9 @@ void eeprom_read_block(void *buf, const void *addr, uint32_t len) { } } -int eeprom_is_ready(void) { return 1; } +int eeprom_is_ready(void) { + return 1; +} void eeprom_write_word(uint16_t *addr, uint16_t value) { uint8_t *p = (uint8_t *)addr; @@ -524,68 +515,13 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) { } #else -// No EEPROM supported, so emulate it - -# ifndef EEPROM_SIZE -# include "eeconfig.h" -# define EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO -# endif -__attribute__((aligned(4))) static uint8_t buffer[EEPROM_SIZE]; - -uint8_t eeprom_read_byte(const uint8_t *addr) { - uint32_t offset = (uint32_t)addr; - return buffer[offset]; -} - -void eeprom_write_byte(uint8_t *addr, uint8_t value) { - uint32_t offset = (uint32_t)addr; - buffer[offset] = value; -} - -uint16_t eeprom_read_word(const uint16_t *addr) { - const uint8_t *p = (const uint8_t *)addr; - return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8); -} - -uint32_t eeprom_read_dword(const uint32_t *addr) { - const uint8_t *p = (const uint8_t *)addr; - return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24); -} - -void eeprom_read_block(void *buf, const void *addr, size_t len) { - const uint8_t *p = (const uint8_t *)addr; - uint8_t * dest = (uint8_t *)buf; - while (len--) { - *dest++ = eeprom_read_byte(p++); - } -} - -void eeprom_write_word(uint16_t *addr, uint16_t value) { - uint8_t *p = (uint8_t *)addr; - eeprom_write_byte(p++, value); - eeprom_write_byte(p, value >> 8); -} - -void eeprom_write_dword(uint32_t *addr, uint32_t value) { - uint8_t *p = (uint8_t *)addr; - eeprom_write_byte(p++, value); - eeprom_write_byte(p++, value >> 8); - eeprom_write_byte(p++, value >> 16); - eeprom_write_byte(p, value >> 24); -} - -void eeprom_write_block(const void *buf, void *addr, size_t len) { - uint8_t * p = (uint8_t *)addr; - const uint8_t *src = (const uint8_t *)buf; - while (len--) { - eeprom_write_byte(p++, *src++); - } -} - +# error Unsupported Teensy EEPROM. #endif /* chip selection */ // The update functions just calls write for now, but could probably be optimized -void eeprom_update_byte(uint8_t *addr, uint8_t value) { eeprom_write_byte(addr, value); } +void eeprom_update_byte(uint8_t *addr, uint8_t value) { + eeprom_write_byte(addr, value); +} void eeprom_update_word(uint16_t *addr, uint16_t value) { uint8_t *p = (uint8_t *)addr; diff --git a/platforms/chibios/eeprom_teensy.h b/platforms/chibios/eeprom_teensy.h new file mode 100755 index 0000000000..9a14a1fa79 --- /dev/null +++ b/platforms/chibios/eeprom_teensy.h @@ -0,0 +1,25 @@ +// Copyright 2022 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include <ch.h> +#include <hal.h> + +#if defined(K20x) +/* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */ +// The EEPROM is really RAM with a hardware-based backup system to +// flash memory. Selecting a smaller size EEPROM allows more wear +// leveling, for higher write endurance. If you edit this file, +// set this to the smallest size your application can use. Also, +// due to Freescale's implementation, writing 16 or 32 bit words +// (aligned to 2 or 4 byte boundaries) has twice the endurance +// compared to writing 8 bit bytes. +// +# ifndef EEPROM_SIZE +# define EEPROM_SIZE 32 +# endif +#elif defined(KL2x) /* Teensy LC (emulated) */ +# define EEPROM_SIZE 128 +#else +# error Unsupported Teensy EEPROM. +#endif diff --git a/platforms/chibios/gd32v_compatibility.h b/platforms/chibios/gd32v_compatibility.h index f4dcfd8c55..a3148fb6d2 100644 --- a/platforms/chibios/gd32v_compatibility.h +++ b/platforms/chibios/gd32v_compatibility.h @@ -97,10 +97,10 @@ /* Serial USART redefines. */ #if HAL_USE_SERIAL # if !defined(SERIAL_USART_CR1) -# define SERIAL_USART_CR1 (USART_CTL0_PCEN | USART_CTL0_PM | USART_CTL0_WL) // parity enable, odd parity, 9 bit length +# define SERIAL_USART_CR1 (USART_CTL0_PCEN | USART_CTL0_PM | USART_CTL0_WL) // parity enable, odd parity, 9 bit length # endif # if !defined(SERIAL_USART_CR2) -# define SERIAL_USART_CR2 (USART_CTL1_STB_1) // 2 stop bits +# define SERIAL_USART_CR2 (USART_CTL1_STB_1) // 2 stop bits # endif # if !defined(SERIAL_USART_CR3) # define SERIAL_USART_CR3 0x0 diff --git a/platforms/chibios/gpio.h b/platforms/chibios/gpio.h index 4d057f1cab..eb44a18f9c 100644 --- a/platforms/chibios/gpio.h +++ b/platforms/chibios/gpio.h @@ -22,10 +22,12 @@ typedef ioline_t pin_t; /* Operation of GPIO by pin. */ -#define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT) -#define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP) -#define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN) -#define setPinOutput(pin) palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL) +#define setPinInput(pin) palSetLineMode((pin), PAL_MODE_INPUT) +#define setPinInputHigh(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLUP) +#define setPinInputLow(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLDOWN) +#define setPinOutputPushPull(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_PUSHPULL) +#define setPinOutputOpenDrain(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_OPENDRAIN) +#define setPinOutput(pin) setPinOutputPushPull(pin) #define writePinHigh(pin) palSetLine(pin) #define writePinLow(pin) palClearLine(pin) @@ -34,17 +36,3 @@ typedef ioline_t pin_t; #define readPin(pin) palReadLine(pin) #define togglePin(pin) palToggleLine(pin) - -/* Operation of GPIO by port. */ - -typedef uint16_t port_data_t; - -#define readPort(pin) palReadPort(PAL_PORT(pin)) - -#define setPortBitInput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT) -#define setPortBitInputHigh(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLUP) -#define setPortBitInputLow(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLDOWN) -#define setPortBitOutput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_OUTPUT_PUSHPULL) - -#define writePortBitLow(pin, bit) palClearLine(PAL_LINE(PAL_PORT(pin), bit)) -#define writePortBitHigh(pin, bit) palSetLine(PAL_LINE(PAL_PORT(pin), bit)) diff --git a/platforms/chibios/platform.mk b/platforms/chibios/platform.mk index 45e3377882..6fd1fd83f5 100644 --- a/platforms/chibios/platform.mk +++ b/platforms/chibios/platform.mk @@ -344,7 +344,7 @@ ifeq ($(strip $(MCU)), risc-v) ifneq ($(shell which riscv64-unknown-elf-gcc 2>/dev/null),) TOOLCHAIN = riscv64-unknown-elf- else - $(error "No RISC-V toolchain found. Can't find riscv32-unknown-elf-gcc or riscv64-unknown-elf-gcc found in your systems PATH variable. Please install a valid toolchain and make it accessible!") + $(call CATASTROPHIC_ERROR,Missing toolchain,No RISC-V toolchain found. Can't find riscv32-unknown-elf-gcc or riscv64-unknown-elf-gcc found in your systems PATH variable. Please install a valid toolchain and make it accessible!) endif endif endif diff --git a/platforms/chibios/sleep_led.c b/platforms/chibios/sleep_led.c index 477056a454..a777d60468 100644 --- a/platforms/chibios/sleep_led.c +++ b/platforms/chibios/sleep_led.c @@ -93,7 +93,7 @@ void sleep_led_init(void) { /* Reset LPTMR settings */ LPTMR0->CSR = 0; /* Set the compare value */ - LPTMR0->CMR = 0; // trigger on counter value (i.e. every time) + LPTMR0->CMR = 0; // trigger on counter value (i.e. every time) /* Set up clock source and prescaler */ /* Software PWM @@ -118,11 +118,11 @@ void sleep_led_init(void) { /* === OPTION 2 === */ # if 1 // nMHz IRC (n=4 on KL25Z, KL26Z and K20x; n=2 or 8 on KL27Z) - MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock -# if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others + MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock +# if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others MCG->MC |= MCG_MC_LIRC_DIV2_DIV2; -# endif /* KL27 */ - MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock +# endif /* KL27 */ + MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock // to work in stop mode, also MCG_C1_IREFSTEN // Divide 4MHz by 2^N (N=6) => 62500 irqs/sec => // => approx F=61, R=256, duration = 4 @@ -140,7 +140,7 @@ void sleep_led_init(void) { /* === END OPTIONS === */ /* Interrupt on TCF set (compare flag) */ - nvicEnableVector(LPTMR0_IRQn, 2); // vector, priority + nvicEnableVector(LPTMR0_IRQn, 2); // vector, priority LPTMR0->CSR |= LPTMRx_CSR_TIE; } @@ -169,21 +169,33 @@ static void gptTimerCallback(GPTDriver *gptp) { static const GPTConfig gptcfg = {1000000, gptTimerCallback, 0, 0}; /* Initialise the timer */ -void sleep_led_init(void) { gptStart(&SLEEP_LED_GPT_DRIVER, &gptcfg); } +void sleep_led_init(void) { + gptStart(&SLEEP_LED_GPT_DRIVER, &gptcfg); +} -void sleep_led_enable(void) { gptStartContinuous(&SLEEP_LED_GPT_DRIVER, gptcfg.frequency / 0xFFFF); } +void sleep_led_enable(void) { + gptStartContinuous(&SLEEP_LED_GPT_DRIVER, gptcfg.frequency / 0xFFFF); +} -void sleep_led_disable(void) { gptStopTimer(&SLEEP_LED_GPT_DRIVER); } +void sleep_led_disable(void) { + gptStopTimer(&SLEEP_LED_GPT_DRIVER); +} -void sleep_led_toggle(void) { (SLEEP_LED_GPT_DRIVER.state == GPT_READY) ? sleep_led_enable() : sleep_led_disable(); } +void sleep_led_toggle(void) { + (SLEEP_LED_GPT_DRIVER.state == GPT_READY) ? sleep_led_enable() : sleep_led_disable(); +} #else /* platform selection: not on familiar chips */ void sleep_led_init(void) {} -void sleep_led_enable(void) { led_set(1 << USB_LED_CAPS_LOCK); } +void sleep_led_enable(void) { + led_set(1 << USB_LED_CAPS_LOCK); +} -void sleep_led_disable(void) { led_set(0); } +void sleep_led_disable(void) { + led_set(0); +} void sleep_led_toggle(void) { // not implemented diff --git a/platforms/chibios/suspend.c b/platforms/chibios/suspend.c index 9310a99920..ce03433e3a 100644 --- a/platforms/chibios/suspend.c +++ b/platforms/chibios/suspend.c @@ -13,15 +13,6 @@ #include "led.h" #include "wait.h" -/** \brief suspend idle - * - * FIXME: needs doc - */ -void suspend_idle(uint8_t time) { - // TODO: this is not used anywhere - what units is 'time' in? - wait_ms(time); -} - /** \brief suspend power down * * FIXME: needs doc @@ -36,34 +27,6 @@ void suspend_power_down(void) { /** \brief suspend wakeup condition * - * FIXME: needs doc - */ -__attribute__((weak)) void matrix_power_up(void) {} -__attribute__((weak)) void matrix_power_down(void) {} -bool suspend_wakeup_condition(void) { - matrix_power_up(); - matrix_scan(); - matrix_power_down(); - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - if (matrix_get_row(r)) return true; - } - return false; -} - -/** \brief run user level code immediately after wakeup - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_wakeup_init_user(void) {} - -/** \brief run keyboard level code immediately after wakeup - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } - -/** \brief suspend wakeup condition - * * run immediately after wakeup * FIXME: needs doc */ diff --git a/platforms/chibios/syscall-fallbacks.c b/platforms/chibios/syscall-fallbacks.c index 7150a46326..86f7907bfc 100644 --- a/platforms/chibios/syscall-fallbacks.c +++ b/platforms/chibios/syscall-fallbacks.c @@ -87,9 +87,13 @@ __attribute__((weak, used)) int _kill(int pid, int sig) { return -1; } -__attribute__((weak, used)) pid_t _getpid(void) { return 1; } +__attribute__((weak, used)) pid_t _getpid(void) { + return 1; +} -__attribute__((weak, used)) void _fini(void) { return; } +__attribute__((weak, used)) void _fini(void) { + return; +} __attribute__((weak, used, noreturn)) void _exit(int i) { while (1) diff --git a/platforms/chibios/timer.c b/platforms/chibios/timer.c index 9f664e1f79..e3bdfdcc37 100644 --- a/platforms/chibios/timer.c +++ b/platforms/chibios/timer.c @@ -2,46 +2,106 @@ #include "timer.h" -static uint32_t reset_point = 0; +static uint32_t ticks_offset = 0; +static uint32_t last_ticks = 0; +static uint32_t ms_offset = 0; #if CH_CFG_ST_RESOLUTION < 32 static uint32_t last_systime = 0; static uint32_t overflow = 0; #endif -void timer_init(void) { timer_clear(); } +// Get the current system time in ticks as a 32-bit number. +// This function must be called from within a system lock zone (so that it can safely use and update the static data). +static inline uint32_t get_system_time_ticks(void) { + uint32_t systime = (uint32_t)chVTGetSystemTimeX(); -void timer_clear(void) { - reset_point = (uint32_t)chVTGetSystemTime(); #if CH_CFG_ST_RESOLUTION < 32 - last_systime = reset_point; - overflow = 0; -#endif -} - -uint16_t timer_read(void) { return (uint16_t)timer_read32(); } - -uint32_t timer_read32(void) { - uint32_t systime = (uint32_t)chVTGetSystemTime(); - -#if CH_CFG_ST_RESOLUTION < 32 - // If/when we need to support 64-bit chips, this may need to be modified to match the native bit-ness of the MCU. - // At this point, the only SysTick resolution allowed other than 32 is 16 bit. - // In the 16-bit case, at: + // If the real system timer resolution is less than 32 bits, provide the missing bits by checking for the counter + // overflow. For this to work, this function must be called at least once for every overflow of the system timer. + // In the 16-bit case, the corresponding times are: // - CH_CFG_ST_FREQUENCY = 100000, overflow will occur every ~0.65 seconds // - CH_CFG_ST_FREQUENCY = 10000, overflow will occur every ~6.5 seconds // - CH_CFG_ST_FREQUENCY = 1000, overflow will occur every ~65 seconds - // With this implementation, as long as we ensure a timer read happens at least once during the overflow period, timing should be accurate. if (systime < last_systime) { overflow += ((uint32_t)1) << CH_CFG_ST_RESOLUTION; } - last_systime = systime; - return (uint32_t)TIME_I2MS(systime - reset_point + overflow); -#else - return (uint32_t)TIME_I2MS(systime - reset_point); + systime += overflow; +#endif + + return systime; +} + +#if CH_CFG_ST_RESOLUTION < 32 +static virtual_timer_t update_timer; + +// Update the system tick counter every half of the timer overflow period; this should keep the tick counter correct +// even if something blocks timer interrupts for 1/2 of the timer overflow period. +# define UPDATE_INTERVAL (((sysinterval_t)1) << (CH_CFG_ST_RESOLUTION - 1)) + +// VT callback function to keep the overflow bits of the system tick counter updated. +static void update_fn(void *arg) { + (void)arg; + chSysLockFromISR(); + get_system_time_ticks(); + chVTSetI(&update_timer, UPDATE_INTERVAL, update_fn, NULL); + chSysUnlockFromISR(); +} +#endif + +// The highest multiple of CH_CFG_ST_FREQUENCY that fits into uint32_t. This number of ticks will necessarily +// correspond to some integer number of seconds. +#define OVERFLOW_ADJUST_TICKS ((uint32_t)((UINT32_MAX / CH_CFG_ST_FREQUENCY) * CH_CFG_ST_FREQUENCY)) + +// The time in milliseconds which corresponds to OVERFLOW_ADJUST_TICKS ticks (this is a precise conversion, because +// OVERFLOW_ADJUST_TICKS corresponds to an integer number of seconds). +#define OVERFLOW_ADJUST_MS (TIME_I2MS(OVERFLOW_ADJUST_TICKS)) + +void timer_init(void) { + timer_clear(); +#if CH_CFG_ST_RESOLUTION < 32 + chVTObjectInit(&update_timer); + chVTSet(&update_timer, UPDATE_INTERVAL, update_fn, NULL); #endif } -uint16_t timer_elapsed(uint16_t last) { return TIMER_DIFF_16(timer_read(), last); } +void timer_clear(void) { + chSysLock(); + ticks_offset = get_system_time_ticks(); + last_ticks = 0; + ms_offset = 0; + chSysUnlock(); +} + +uint16_t timer_read(void) { + return (uint16_t)timer_read32(); +} -uint32_t timer_elapsed32(uint32_t last) { return TIMER_DIFF_32(timer_read32(), last); } +uint32_t timer_read32(void) { + chSysLock(); + uint32_t ticks = get_system_time_ticks() - ticks_offset; + if (ticks < last_ticks) { + // The 32-bit tick counter overflowed and wrapped around. We cannot just extend the counter to 64 bits here, + // because TIME_I2MS() may encounter overflows when handling a 64-bit argument; therefore the solution here is + // to subtract a reasonably large number of ticks from the tick counter to bring its value below the 32-bit + // limit again, and then add the equivalent number of milliseconds to the converted value. (Adjusting just the + // converted value to account for 2**32 ticks is not possible in general, because 2**32 ticks may not correspond + // to an integer number of milliseconds). + ticks -= OVERFLOW_ADJUST_TICKS; + ticks_offset += OVERFLOW_ADJUST_TICKS; + ms_offset += OVERFLOW_ADJUST_MS; + } + last_ticks = ticks; + uint32_t ms_offset_copy = ms_offset; // read while still holding the lock to ensure a consistent value + chSysUnlock(); + + return (uint32_t)TIME_I2MS(ticks) + ms_offset_copy; +} + +uint16_t timer_elapsed(uint16_t last) { + return TIMER_DIFF_16(timer_read(), last); +} + +uint32_t timer_elapsed32(uint32_t last) { + return TIMER_DIFF_32(timer_read32(), last); +} |