diff --git a/arch/arm/src/common/stm32/Kconfig.periph b/arch/arm/src/common/stm32/Kconfig.periph index 7b7ee42fb47..2b292bbb70b 100644 --- a/arch/arm/src/common/stm32/Kconfig.periph +++ b/arch/arm/src/common/stm32/Kconfig.periph @@ -752,7 +752,7 @@ config STM32_UART8 config STM32_LPTIM1 bool "LPTIM1" depends on STM32_HAVE_LPTIM1 - select STM32_LPTIM if ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32L4 || ARCH_CHIP_STM32WB + select STM32_LPTIM if ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32L4 || ARCH_CHIP_STM32WB || ARCH_CHIP_STM32H5 config STM32_TIM1 bool "TIM1" @@ -841,22 +841,22 @@ config STM32_TIM17 config STM32_LPTIM2 bool "LPTIM2" - depends on ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32U5 || ARCH_CHIP_STM32WB || ARCH_CHIP_STM32L4 && STM32_HAVE_LPTIM2 - select STM32_LPTIM if ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32L4 || ARCH_CHIP_STM32WB + depends on ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32U5 || ARCH_CHIP_STM32WB || ARCH_CHIP_STM32H5 || ARCH_CHIP_STM32L4 && STM32_HAVE_LPTIM2 + select STM32_LPTIM if ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32L4 || ARCH_CHIP_STM32WB || ARCH_CHIP_STM32H5 config STM32_LPTIM3 bool "LPTIM3" depends on STM32_HAVE_LPTIM3 - select STM32_LPTIM if ARCH_CHIP_STM32H7 + select STM32_LPTIM if ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5 config STM32_LPTIM4 bool "LPTIM4" depends on STM32_HAVE_LPTIM4 - select STM32_LPTIM if ARCH_CHIP_STM32H7 + select STM32_LPTIM if ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5 config STM32_LPTIM5 bool "LPTIM5" - depends on ARCH_CHIP_STM32H7 + depends on ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5 select STM32_LPTIM config STM32_HRTIM1 diff --git a/arch/arm/src/stm32h5/CMakeLists.txt b/arch/arm/src/stm32h5/CMakeLists.txt index 047ac1bb59a..9055fb57db2 100644 --- a/arch/arm/src/stm32h5/CMakeLists.txt +++ b/arch/arm/src/stm32h5/CMakeLists.txt @@ -88,6 +88,10 @@ if(CONFIG_STM32_TIM) list(APPEND SRCS stm32_tim.c) endif() +if(CONFIG_STM32_LPTIM) + list(APPEND SRCS stm32_lptim.c) +endif() + if(CONFIG_STM32_HAVE_HSI48) list(APPEND SRCS stm32_hsi48.c) endif() diff --git a/arch/arm/src/stm32h5/Kconfig b/arch/arm/src/stm32h5/Kconfig index 1f867433b3c..8aba6121e9b 100644 --- a/arch/arm/src/stm32h5/Kconfig +++ b/arch/arm/src/stm32h5/Kconfig @@ -14,6 +14,11 @@ config STM32_H5_PERIPHERALS select STM32_HAVE_DMA2 select STM32_HAVE_I2C1 select STM32_HAVE_I2C2 + select STM32_HAVE_LPTIM1 + select STM32_HAVE_LPTIM2 + select STM32_HAVE_LPTIM3 + select STM32_HAVE_LPTIM4 + select STM32_HAVE_LPTIM5 select STM32_HAVE_RNG select STM32_HAVE_SPI1 select STM32_HAVE_SPI2 diff --git a/arch/arm/src/stm32h5/Make.defs b/arch/arm/src/stm32h5/Make.defs index 7d35a2b939b..5bc76febc05 100644 --- a/arch/arm/src/stm32h5/Make.defs +++ b/arch/arm/src/stm32h5/Make.defs @@ -84,6 +84,10 @@ ifeq ($(CONFIG_STM32_TIM),y) CHIP_CSRCS += stm32_tim.c endif +ifeq ($(CONFIG_STM32_LPTIM),y) +CHIP_CSRCS += stm32_lptim.c +endif + ifeq ($(CONFIG_STM32_HAVE_HSI48),y) CHIP_CSRCS += stm32_hsi48.c endif diff --git a/arch/arm/src/stm32h5/hardware/stm32_lptim.h b/arch/arm/src/stm32h5/hardware/stm32_lptim.h new file mode 100644 index 00000000000..76f99394abc --- /dev/null +++ b/arch/arm/src/stm32h5/hardware/stm32_lptim.h @@ -0,0 +1,168 @@ +/**************************************************************************** + * arch/arm/src/stm32h5/hardware/stm32_lptim.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32_LPTIM_H +#define __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32_LPTIM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_LPTIM_ISR_OFFSET 0x0000 /* Interrupt and status register */ +#define STM32_LPTIM_ICR_OFFSET 0x0004 /* Interrupt clear register */ +#define STM32_LPTIM_IER_OFFSET 0x0008 /* Interrupt enable register */ +#define STM32_LPTIM_CFGR_OFFSET 0x000C /* Configuration register */ +#define STM32_LPTIM_CR_OFFSET 0x0010 /* Control register */ +#define STM32_LPTIM_CMP_OFFSET 0x0014 /* Compare register */ +#define STM32_LPTIM_ARR_OFFSET 0x0018 /* Autoreloar register */ +#define STM32_LPTIM_CNT_OFFSET 0x001C /* Counter register */ +#define STM32_LPTIM_CFGR2_OFFSET 0x0024 /* Configuration register 2 */ + +/* Register Addresses *******************************************************/ + +# define STM32_LPTIM1_ISR (STM32_LPTIM1_BASE+STM32_LPTIM_ISR_OFFSET) +# define STM32_LPTIM1_ICR (STM32_LPTIM1_BASE+STM32_LPTIM_ICR_OFFSET) +# define STM32_LPTIM1_IER (STM32_LPTIM1_BASE+STM32_LPTIM_IER_OFFSET) +# define STM32_LPTIM1_CFGR (STM32_LPTIM1_BASE+STM32_LPTIM_CFGR_OFFSET) +# define STM32_LPTIM1_CR (STM32_LPTIM1_BASE+STM32_LPTIM_CR_OFFSET) +# define STM32_LPTIM1_CMP (STM32_LPTIM1_BASE+STM32_LPTIM_CMP_OFFSET) +# define STM32_LPTIM1_ARR (STM32_LPTIM1_BASE+STM32_LPTIM_ARR_OFFSET) +# define STM32_LPTIM1_CNT (STM32_LPTIM1_BASE+STM32_LPTIM_CNT_OFFSET) +# define STM32_LPTIM1_CFGR2 (STM32_LPTIM1_BASE+STM32_LPTIM_CFGR2_OFFSET) + +# define STM32_LPTIM3_ISR (STM32_LPTIM3_BASE+STM32_LPTIM_ISR_OFFSET) +# define STM32_LPTIM3_ICR (STM32_LPTIM3_BASE+STM32_LPTIM_ICR_OFFSET) +# define STM32_LPTIM3_IER (STM32_LPTIM3_BASE+STM32_LPTIM_IER_OFFSET) +# define STM32_LPTIM3_CFGR (STM32_LPTIM3_BASE+STM32_LPTIM_CFGR_OFFSET) +# define STM32_LPTIM3_CR (STM32_LPTIM3_BASE+STM32_LPTIM_CR_OFFSET) +# define STM32_LPTIM3_CMP (STM32_LPTIM3_BASE+STM32_LPTIM_CMP_OFFSET) +# define STM32_LPTIM3_ARR (STM32_LPTIM3_BASE+STM32_LPTIM_ARR_OFFSET) +# define STM32_LPTIM3_CNT (STM32_LPTIM3_BASE+STM32_LPTIM_CNT_OFFSET) +# define STM32_LPTIM3_CFGR2 (STM32_LPTIM3_BASE+STM32_LPTIM_CFGR2_OFFSET) + +# define STM32_LPTIM4_ISR (STM32_LPTIM4_BASE+STM32_LPTIM_ISR_OFFSET) +# define STM32_LPTIM4_ICR (STM32_LPTIM4_BASE+STM32_LPTIM_ICR_OFFSET) +# define STM32_LPTIM4_IER (STM32_LPTIM4_BASE+STM32_LPTIM_IER_OFFSET) +# define STM32_LPTIM4_CFGR (STM32_LPTIM4_BASE+STM32_LPTIM_CFGR_OFFSET) +# define STM32_LPTIM4_CR (STM32_LPTIM4_BASE+STM32_LPTIM_CR_OFFSET) +# define STM32_LPTIM4_CMP (STM32_LPTIM4_BASE+STM32_LPTIM_CMP_OFFSET) +# define STM32_LPTIM4_ARR (STM32_LPTIM4_BASE+STM32_LPTIM_ARR_OFFSET) +# define STM32_LPTIM4_CNT (STM32_LPTIM4_BASE+STM32_LPTIM_CNT_OFFSET) +# define STM32_LPTIM4_CFGR2 (STM32_LPTIM4_BASE+STM32_LPTIM_CFGR2_OFFSET) + +# define STM32_LPTIM5_ISR (STM32_LPTIM5_BASE+STM32_LPTIM_ISR_OFFSET) +# define STM32_LPTIM5_ICR (STM32_LPTIM5_BASE+STM32_LPTIM_ICR_OFFSET) +# define STM32_LPTIM5_IER (STM32_LPTIM5_BASE+STM32_LPTIM_IER_OFFSET) +# define STM32_LPTIM5_CFGR (STM32_LPTIM5_BASE+STM32_LPTIM_CFGR_OFFSET) +# define STM32_LPTIM5_CR (STM32_LPTIM5_BASE+STM32_LPTIM_CR_OFFSET) +# define STM32_LPTIM5_CMP (STM32_LPTIM5_BASE+STM32_LPTIM_CMP_OFFSET) +# define STM32_LPTIM5_ARR (STM32_LPTIM5_BASE+STM32_LPTIM_ARR_OFFSET) +# define STM32_LPTIM5_CNT (STM32_LPTIM5_BASE+STM32_LPTIM_CNT_OFFSET) +# define STM32_LPTIM5_CFGR2 (STM32_LPTIM5_BASE+STM32_LPTIM_CFGR2_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Interrupt flags for ISR, ICR and IER */ + +#define LPTIM_ISR_CMPM (1 << 0) /* Bit 0: Compare match */ +#define LPTIM_ISR_ARRM (1 << 1) /* Bit 1: Autoreload match */ +#define LPTIM_ISR_EXTTRIG (1 << 2) /* Bit 2: External trigger edge event */ +#define LPTIM_ISR_CMPOK (1 << 3) /* Bit 3: Compare register update OK */ +#define LPTIM_ISR_ARROK (1 << 4) /* Bit 4: Autoreload register update OK */ +#define LPTIM_ISR_UP (1 << 5) /* Bit 5: Counter direction change down to up */ +#define LPTIM_ISR_DOWN (1 << 6) /* Bit 6: Counter direction change up to down */ + +/* Configuration register */ + +#define LPTIM_CFGR_CKSEL (1 << 0) /* Bit 0: Clock selector */ +#define LPTIM_CFGR_CKPOL_SHIFT (1) /* Bits 1-2: Clock polarity */ +#define LPTIM_CFGR_CKPOL_MASK (3 << LPTIM_CFGR_CKPOL_SHIFT) +# define LPTIM_CFGR_CKPOL_RISE (0 << LPTIM_CFGR_CKPOL_SHIFT) /* 00: Rising edge */ +# define LPTIM_CFGR_CKPOL_FALL (1 << LPTIM_CFGR_CKPOL_SHIFT) /* 01: Falling edge */ +# define LPTIM_CFGR_CKPOL_BOTH (2 << LPTIM_CFGR_CKPOL_SHIFT) /* 10: Both edges */ + +#define LPTIM_CFGR_CKFLT_SHIFT (3) /* Bits 3-4: Digital filter for clock*/ +#define LPTIM_CFGR_CKFLT_MASK (3 << LPTIM_CFGR_CKFLT_SHIFT) +# define LPTIM_CFGR_CKFLT_ANY (0 << LPTIM_CFGR_CKFLT_SHIFT) /* 00: Any */ +# define LPTIM_CFGR_CKFLT_2 (1 << LPTIM_CFGR_CKFLT_SHIFT) /* 01: 2 clocks */ +# define LPTIM_CFGR_CKFLT_4 (2 << LPTIM_CFGR_CKFLT_SHIFT) /* 10: 4 clocks */ +# define LPTIM_CFGR_CKFLT_8 (3 << LPTIM_CFGR_CKFLT_SHIFT) /* 11: 8 clocks */ + +#define LPTIM_CFGR_TRGFLT_SHIFT (6) /* Bits 6-7: digital filter for trigger */ +#define LPTIM_CFGR_TRGFLT_MASK (3 << LPTIM_CFGR_TRGFLT_SHIFT) +# define LPTIM_CFGR_TRGFLT_ANY (0 << LPTIM_CFGR_TRGFLT_SHIFT) /* 00: Any */ +# define LPTIM_CFGR_TRGFLT_2 (1 << LPTIM_CFGR_TRGFLT_SHIFT) /* 01: 2 clocks */ +# define LPTIM_CFGR_TRGFLT_4 (2 << LPTIM_CFGR_TRGFLT_SHIFT) /* 10: 4 clocks */ +# define LPTIM_CFGR_TRGFLT_8 (3 << LPTIM_CFGR_TRGFLT_SHIFT) /* 11: 8 clocks */ + +#define LPTIM_CFGR_PRESC_SHIFT (9) /* Bits 9-11: Clock prescaler */ +#define LPTIM_CFGR_PRESC_MASK (7 << LPTIM_CFGR_PRESC_SHIFT) +# define LPTIM_CFGR_PRESC_1 (0 << LPTIM_CFGR_PRESC_SHIFT) +# define LPTIM_CFGR_PRESC_2 (1 << LPTIM_CFGR_PRESC_SHIFT) +# define LPTIM_CFGR_PRESC_4 (2 << LPTIM_CFGR_PRESC_SHIFT) +# define LPTIM_CFGR_PRESC_8 (3 << LPTIM_CFGR_PRESC_SHIFT) +# define LPTIM_CFGR_PRESC_16 (4 << LPTIM_CFGR_PRESC_SHIFT) +# define LPTIM_CFGR_PRESC_32 (5 << LPTIM_CFGR_PRESC_SHIFT) +# define LPTIM_CFGR_PRESC_64 (6 << LPTIM_CFGR_PRESC_SHIFT) +# define LPTIM_CFGR_PRESC_128 (7 << LPTIM_CFGR_PRESC_SHIFT) + +#define LPTIM_CFGR_TRIGSEL_SHIFT (13) /* Bits 13-15: Trigger selector */ +#define LPTIM_CFGR_TRIGSEL_MASK (7 << LPTIM_CFGR_TRIGSEL_SHIFT) +#define LPTIM_CFGR_TRIGEN_SHIFT (17) /* Bits 17-18: Trigger enable and polarity */ +#define LPTIM_CFGR_TRIGEN_MASK (3 << LPTIM_CFGR_TRIGEN_SHIFT) +# define LPTIM_CFGR_TRIGEN_SW (0 << LPTIM_CFGR_TRIGEN_SHIFT) /* 00: software */ +# define LPTIM_CFGR_TRIGEN_RISE (1 << LPTIM_CFGR_TRIGEN_SHIFT) /* 01: rising edge */ +# define LPTIM_CFGR_TRIGEN_FALL (2 << LPTIM_CFGR_TRIGEN_SHIFT) /* 10: falling edge */ +# define LPTIM_CFGR_TRIGEN_BOTH (3 << LPTIM_CFGR_TRIGEN_SHIFT) /* 11: both edges */ + +#define LPTIM_CFGR_TIMEOUT (1 << 19) /* Bit 19: Timeout enable */ +#define LPTIM_CFGR_WAVE (1 << 20) /* Bit 20: Waveform shape */ +#define LPTIM_CFGR_WAVPOL (1 << 21) /* Bit 21: Waveform shape polarity */ +#define LPTIM_CFGR_PRELOAD (1 << 22) /* Bit 22: Registers update mode */ +#define LPTIM_CFGR_COUNTMODE (1 << 23) /* Bit 23: Counter mode enable */ +#define LPTIM_CFGR_ENC (1 << 24) /* Bit 24: Encoder mode enable */ + +/* Control register */ + +#define LPTIM_CR_ENABLE (1 << 0) /* Bit 0: Enable */ +#define LPTIM_CR_SNGSTRT (1 << 1) /* Bit 1: Start in single mode */ +#define LPTIM_CR_CNTSTRT (1 << 2) /* Bit 2: Start in continuous mode */ +#define LPTIM_CR_COUNTRST (1 << 3) /* Bit 3: Counter reset */ +#define LPTIM_CR_RSTARE (1 << 4) /* Reset after read enable */ + +/* Configuration register 2 */ + +#define LPTIM_CFGR2_IN1SEL_SHIFT (0) /* Input 1 selection */ +#define LPTIM_CFGR2_IN1SEL_MASK (3 << LPTIM_CFGR2_IN1SEL_SHIFT) +#define LPTIM_CFGR2_IN2SEL_SHIFT (4) /* Input 2 selection */ +#define LPTIM_CFGR2_IN2SEL_MASK (3 << LPTIM_CFGR2_IN2SEL_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32_LPTIM_H */ diff --git a/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h b/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h index 2303e8dfdda..979177cf62d 100644 --- a/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h +++ b/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h @@ -937,54 +937,54 @@ # define RCC_CCIPR2_LPTIM1SEL_RCCPCLK3 (0 << RCC_CCIPR2_LPTIM1SEL_SHIFT) # define RCC_CCIPR2_LPTIM1SEL_PLL2PCK (1 << RCC_CCIPR2_LPTIM1SEL_SHIFT) # define RCC_CCIPR2_LPTIM1SEL_PLL3RCK (2 << RCC_CCIPR2_LPTIM1SEL_SHIFT) -# define RCC_CCIPR2_LPTIM1SEL_HSIKERCK (3 << RCC_CCIPR2_LPTIM1SEL_SHIFT) -# define RCC_CCIPR2_LPTIM1SEL_CSIKERCK (4 << RCC_CCIPR2_LPTIM1SEL_SHIFT) -# define RCC_CCIPR2_LPTIM1SEL_LSECK (5 << RCC_CCIPR2_LPTIM1SEL_SHIFT) +# define RCC_CCIPR2_LPTIM1SEL_LSEKERCK (3 << RCC_CCIPR2_LPTIM1SEL_SHIFT) +# define RCC_CCIPR2_LPTIM1SEL_LSIKERCK (4 << RCC_CCIPR2_LPTIM1SEL_SHIFT) +# define RCC_CCIPR2_LPTIM1SEL_PERCK (5 << RCC_CCIPR2_LPTIM1SEL_SHIFT) #define RCC_CCIPR2_LPTIM2SEL_SHIFT (12) #define RCC_CCIPR2_LPTIM2SEL_MASK (7 << RCC_CCIPR2_LPTIM2SEL_SHIFT) # define RCC_CCIPR2_LPTIM2SEL_RCCPCLK1 (0 << RCC_CCIPR2_LPTIM2SEL_SHIFT) # define RCC_CCIPR2_LPTIM2SEL_PLL2PCK (1 << RCC_CCIPR2_LPTIM2SEL_SHIFT) # define RCC_CCIPR2_LPTIM2SEL_PLL3RCK (2 << RCC_CCIPR2_LPTIM2SEL_SHIFT) -# define RCC_CCIPR2_LPTIM2SEL_HSIKERCK (3 << RCC_CCIPR2_LPTIM2SEL_SHIFT) -# define RCC_CCIPR2_LPTIM2SEL_CSIKERCK (4 << RCC_CCIPR2_LPTIM2SEL_SHIFT) -# define RCC_CCIPR2_LPTIM2SEL_LSECK (5 << RCC_CCIPR2_LPTIM2SEL_SHIFT) +# define RCC_CCIPR2_LPTIM2SEL_LSEKERCK (3 << RCC_CCIPR2_LPTIM2SEL_SHIFT) +# define RCC_CCIPR2_LPTIM2SEL_LSIKERCK (4 << RCC_CCIPR2_LPTIM2SEL_SHIFT) +# define RCC_CCIPR2_LPTIM2SEL_PERCK (5 << RCC_CCIPR2_LPTIM2SEL_SHIFT) #define RCC_CCIPR2_LPTIM3SEL_SHIFT (16) #define RCC_CCIPR2_LPTIM3SEL_MASK (7 << RCC_CCIPR2_LPTIM3SEL_SHIFT) # define RCC_CCIPR2_LPTIM3SEL_RCCPCLK3 (0 << RCC_CCIPR2_LPTIM3SEL_SHIFT) # define RCC_CCIPR2_LPTIM3SEL_PLL2PCK (1 << RCC_CCIPR2_LPTIM3SEL_SHIFT) # define RCC_CCIPR2_LPTIM3SEL_PLL3RCK (2 << RCC_CCIPR2_LPTIM3SEL_SHIFT) -# define RCC_CCIPR2_LPTIM3SEL_HSIKERCK (3 << RCC_CCIPR2_LPTIM3SEL_SHIFT) -# define RCC_CCIPR2_LPTIM3SEL_CSIKERCK (4 << RCC_CCIPR2_LPTIM3SEL_SHIFT) -# define RCC_CCIPR2_LPTIM3SEL_LSECK (5 << RCC_CCIPR2_LPTIM3SEL_SHIFT) +# define RCC_CCIPR2_LPTIM3SEL_LSEKERCK (3 << RCC_CCIPR2_LPTIM3SEL_SHIFT) +# define RCC_CCIPR2_LPTIM3SEL_LSIKERCK (4 << RCC_CCIPR2_LPTIM3SEL_SHIFT) +# define RCC_CCIPR2_LPTIM3SEL_PERCK (5 << RCC_CCIPR2_LPTIM3SEL_SHIFT) #define RCC_CCIPR2_LPTIM4SEL_SHIFT (20) #define RCC_CCIPR2_LPTIM4SEL_MASK (7 << RCC_CCIPR2_LPTIM4SEL_SHIFT) # define RCC_CCIPR2_LPTIM4SEL_RCCPCLK3 (0 << RCC_CCIPR2_LPTIM4SEL_SHIFT) # define RCC_CCIPR2_LPTIM4SEL_PLL2PCK (1 << RCC_CCIPR2_LPTIM4SEL_SHIFT) # define RCC_CCIPR2_LPTIM4SEL_PLL3RCK (2 << RCC_CCIPR2_LPTIM4SEL_SHIFT) -# define RCC_CCIPR2_LPTIM4SEL_HSIKERCK (3 << RCC_CCIPR2_LPTIM4SEL_SHIFT) -# define RCC_CCIPR2_LPTIM4SEL_CSIKERCK (4 << RCC_CCIPR2_LPTIM4SEL_SHIFT) -# define RCC_CCIPR2_LPTIM4SEL_LSECK (5 << RCC_CCIPR2_LPTIM4SEL_SHIFT) +# define RCC_CCIPR2_LPTIM4SEL_LSEKERCK (3 << RCC_CCIPR2_LPTIM4SEL_SHIFT) +# define RCC_CCIPR2_LPTIM4SEL_LSIKERCK (4 << RCC_CCIPR2_LPTIM4SEL_SHIFT) +# define RCC_CCIPR2_LPTIM4SEL_PERCK (5 << RCC_CCIPR2_LPTIM4SEL_SHIFT) #define RCC_CCIPR2_LPTIM5SEL_SHIFT (24) #define RCC_CCIPR2_LPTIM5SEL_MASK (7 << RCC_CCIPR2_LPTIM5SEL_SHIFT) # define RCC_CCIPR2_LPTIM5SEL_RCCPCLK3 (0 << RCC_CCIPR2_LPTIM5SEL_SHIFT) # define RCC_CCIPR2_LPTIM5SEL_PLL2PCK (1 << RCC_CCIPR2_LPTIM5SEL_SHIFT) # define RCC_CCIPR2_LPTIM5SEL_PLL3RCK (2 << RCC_CCIPR2_LPTIM5SEL_SHIFT) -# define RCC_CCIPR2_LPTIM5SEL_HSIKERCK (3 << RCC_CCIPR2_LPTIM5SEL_SHIFT) -# define RCC_CCIPR2_LPTIM5SEL_CSIKERCK (4 << RCC_CCIPR2_LPTIM5SEL_SHIFT) -# define RCC_CCIPR2_LPTIM5SEL_LSECK (5 << RCC_CCIPR2_LPTIM5SEL_SHIFT) +# define RCC_CCIPR2_LPTIM5SEL_LSEKERCK (3 << RCC_CCIPR2_LPTIM5SEL_SHIFT) +# define RCC_CCIPR2_LPTIM5SEL_LSIKERCK (4 << RCC_CCIPR2_LPTIM5SEL_SHIFT) +# define RCC_CCIPR2_LPTIM5SEL_PERCK (5 << RCC_CCIPR2_LPTIM5SEL_SHIFT) #define RCC_CCIPR2_LPTIM6SEL_SHIFT (28) #define RCC_CCIPR2_LPTIM6SEL_MASK (7 << RCC_CCIPR2_LPTIM6SEL_SHIFT) # define RCC_CCIPR2_LPTIM6SEL_RCCPCLK3 (0 << RCC_CCIPR2_LPTIM6SEL_SHIFT) # define RCC_CCIPR2_LPTIM6SEL_PLL2PCK (1 << RCC_CCIPR2_LPTIM6SEL_SHIFT) # define RCC_CCIPR2_LPTIM6SEL_PLL3RCK (2 << RCC_CCIPR2_LPTIM6SEL_SHIFT) -# define RCC_CCIPR2_LPTIM6SEL_HSIKERCK (3 << RCC_CCIPR2_LPTIM6SEL_SHIFT) -# define RCC_CCIPR2_LPTIM6SEL_CSIKERCK (4 << RCC_CCIPR2_LPTIM6SEL_SHIFT) -# define RCC_CCIPR2_LPTIM6SEL_LSECK (5 << RCC_CCIPR2_LPTIM6SEL_SHIFT) +# define RCC_CCIPR2_LPTIM6SEL_LSEKERCK (3 << RCC_CCIPR2_LPTIM6SEL_SHIFT) +# define RCC_CCIPR2_LPTIM6SEL_LSIKERCK (4 << RCC_CCIPR2_LPTIM6SEL_SHIFT) +# define RCC_CCIPR2_LPTIM6SEL_PERCK (5 << RCC_CCIPR2_LPTIM6SEL_SHIFT) /* Kernel Clock Configuration register 3 */ diff --git a/arch/arm/src/stm32h5/stm32_lptim.c b/arch/arm/src/stm32h5/stm32_lptim.c new file mode 100644 index 00000000000..1cda112a199 --- /dev/null +++ b/arch/arm/src/stm32h5/stm32_lptim.c @@ -0,0 +1,514 @@ +/**************************************************************************** + * arch/arm/src/stm32h5/stm32_lptim.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "arm_internal.h" +#include "stm32_rcc.h" +#include "stm32_gpio.h" +#include "stm32_lptim.h" + +#if defined(CONFIG_STM32_LPTIM1) || defined(CONFIG_STM32_LPTIM2) || \ + defined(CONFIG_STM32_LPTIM3) || defined(CONFIG_STM32_LPTIM4) || \ + defined(CONFIG_STM32_LPTIM5) + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +/* Low-power timer methods */ + +static void stm32_lptim_setcfgr(struct stm32_lptim_dev_s *dev, + uint32_t regval); +static void stm32_lptim_setperiod(struct stm32_lptim_dev_s *dev, + uint32_t period); +static void stm32_lptim_setcompare(struct stm32_lptim_dev_s *dev, + uint32_t cmp); +static uint32_t stm32_lptim_getcounter(struct stm32_lptim_dev_s *dev); +static int stm32_lptim_setinput(struct stm32_lptim_dev_s *dev, + uint32_t input, uint32_t mux); +static void stm32_lptim_enable(struct stm32_lptim_dev_s *dev, bool on); +static void stm32_lptim_start(struct stm32_lptim_dev_s *dev, + stm32_lptim_start_mode_t mode); +static void stm32_lptim_resetcounter(struct stm32_lptim_dev_s *dev); +static void stm32_lptim_enablerar(struct stm32_lptim_dev_s *dev, + bool on); + +static int stm32_lptim_setisr(struct stm32_lptim_dev_s *dev, + xcpt_t handler, void *arg, int source); +static void stm32_lptim_enableint(struct stm32_lptim_dev_s *dev, + int source); +static void stm32_lptim_disableint(struct stm32_lptim_dev_s *dev, + int source); +static void stm32_lptim_ackint(struct stm32_lptim_dev_s *dev, + int source); + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct stm32_lptim_ops_s stm32_lptim_ops = +{ + .setcfgr = &stm32_lptim_setcfgr, + .setperiod = &stm32_lptim_setperiod, + .setcompare = &stm32_lptim_setcompare, + .getcounter = &stm32_lptim_getcounter, + .setinput = &stm32_lptim_setinput, + .enable = &stm32_lptim_enable, + .start = &stm32_lptim_start, + .resetcounter = &stm32_lptim_resetcounter, + .enablerar = &stm32_lptim_enablerar, + .setisr = &stm32_lptim_setisr, + .enableint = &stm32_lptim_enableint, + .disableint = &stm32_lptim_disableint, + .ackint = &stm32_lptim_ackint +}; + +#ifdef CONFIG_STM32_LPTIM1 +struct stm32_lptim_dev_s stm32_lptim1_priv = +{ + .ops = &stm32_lptim_ops, + .base = STM32_LPTIM1_BASE, +}; +#endif +#ifdef CONFIG_STM32_LPTIM2 +struct stm32_lptim_dev_s stm32_lptim2_priv = +{ + .ops = &stm32_lptim_ops, + .base = STM32_LPTIM2_BASE, +}; +#endif +#ifdef CONFIG_STM32_LPTIM3 +struct stm32_lptim_dev_s stm32_lptim3_priv = +{ + .ops = &stm32_lptim_ops, + .base = STM32_LPTIM3_BASE, +}; +#endif +#ifdef CONFIG_STM32_LPTIM4 +struct stm32_lptim_dev_s stm32_lptim4_priv = +{ + .ops = &stm32_lptim_ops, + .base = STM32_LPTIM4_BASE, +}; +#endif +#ifdef CONFIG_STM32_LPTIM5 +struct stm32_lptim_dev_s stm32_lptim5_priv = +{ + .ops = &stm32_lptim_ops, + .base = STM32_LPTIM5_BASE, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Get a 32-bit register value by offset. + */ + +static inline uint32_t stm32_getreg32(struct stm32_lptim_dev_s *dev, + uint8_t offset) +{ + return getreg32(dev->base + offset); +} + +/* Put a 32-bit register value by offset. + */ + +static inline void stm32_putreg32(struct stm32_lptim_dev_s *dev, + uint8_t offset, uint32_t value) +{ + putreg32(value, dev->base + offset); +} + +static void stm32_lptim_setcfgr(struct stm32_lptim_dev_s *dev, + uint32_t regval) +{ + stm32_putreg32(dev, STM32_LPTIM_CFGR_OFFSET, regval); +} + +static void stm32_lptim_setperiod(struct stm32_lptim_dev_s *dev, + uint32_t period) +{ + uint32_t timeout; + + /* For STM32H5: Clear ARROK flag BEFORE writing ARR when timer is enabled + * This ensures we wait for the new value to be loaded + */ + + if (stm32_getreg32(dev, STM32_LPTIM_CR_OFFSET) & LPTIM_CR_ENABLE) + { + stm32_putreg32(dev, STM32_LPTIM_ICR_OFFSET, LPTIM_ISR_ARROK); + } + + stm32_putreg32(dev, STM32_LPTIM_ARR_OFFSET, period); + + /* Wait for ARROK flag when timer is enabled */ + + if (stm32_getreg32(dev, STM32_LPTIM_CR_OFFSET) & LPTIM_CR_ENABLE) + { + timeout = 10000; + while (!(stm32_getreg32(dev, STM32_LPTIM_ISR_OFFSET) & LPTIM_ISR_ARROK) + && timeout > 0) + { + timeout--; + } + } +} + +static void stm32_lptim_setcompare(struct stm32_lptim_dev_s *dev, + uint32_t cmp) +{ + uint32_t timeout; + + /* For STM32H5: Clear CMPOK flag BEFORE writing CMP when timer is enabled */ + + if (stm32_getreg32(dev, STM32_LPTIM_CR_OFFSET) & LPTIM_CR_ENABLE) + { + stm32_putreg32(dev, STM32_LPTIM_ICR_OFFSET, LPTIM_ISR_CMPOK); + } + + stm32_putreg32(dev, STM32_LPTIM_CMP_OFFSET, cmp); + + /* Wait for CMPOK flag when timer is enabled */ + + if (stm32_getreg32(dev, STM32_LPTIM_CR_OFFSET) & LPTIM_CR_ENABLE) + { + timeout = 10000; + while (!(stm32_getreg32(dev, STM32_LPTIM_ISR_OFFSET) & LPTIM_ISR_CMPOK) + && timeout > 0) + { + timeout--; + } + } +} + +static uint32_t stm32_lptim_getcounter(struct stm32_lptim_dev_s *dev) +{ + /* For a reliable LPTIM_CNT register read access, two consecutive + * read accesses must be performed and compared + */ + + uint32_t cnt1; + uint32_t cnt2; + + cnt2 = stm32_getreg32(dev, STM32_LPTIM_CNT_OFFSET); + + do + { + cnt1 = cnt2; + cnt2 = stm32_getreg32(dev, STM32_LPTIM_CNT_OFFSET); + } + while (cnt1 != cnt2); + + return cnt1; +} + +static int stm32_lptim_setinput(struct stm32_lptim_dev_s *dev, + uint32_t input, uint32_t mux) +{ + switch (dev->base) + { +#ifdef CONFIG_STM32_LPTIM1 + case STM32_LPTIM1_BASE: + if (input == 0) + { + modifyreg32(dev->base + STM32_LPTIM_CFGR2_OFFSET, + LPTIM_CFGR2_IN1SEL_MASK, mux); + } + else + { + modifyreg32(dev->base + STM32_LPTIM_CFGR2_OFFSET, + LPTIM_CFGR2_IN2SEL_MASK, + mux << LPTIM_CFGR2_IN2SEL_SHIFT); + } + break; +#endif +#ifdef CONFIG_STM32_LPTIM3 + case STM32_LPTIM3_BASE: + modifyreg32(dev->base + STM32_LPTIM_CFGR2_OFFSET, + LPTIM_CFGR2_IN1SEL_MASK, mux); + break; +#endif + default: + return -EINVAL; + } + + return OK; +} + +static void stm32_lptim_enable(struct stm32_lptim_dev_s *dev, bool on) +{ + uint32_t val = stm32_getreg32(dev, STM32_LPTIM_CR_OFFSET); + + if (on) + { + val |= LPTIM_CR_ENABLE; + } + else + { + val &= ~LPTIM_CR_ENABLE; + } + + stm32_putreg32(dev, STM32_LPTIM_CR_OFFSET, val); +} + +static void stm32_lptim_start(struct stm32_lptim_dev_s *dev, + stm32_lptim_start_mode_t mode) +{ + uint32_t val = stm32_getreg32(dev, STM32_LPTIM_CR_OFFSET); + + switch (mode) + { + case STM32_LPTIM_MODE_CONTINUOUS: + val |= LPTIM_CR_CNTSTRT; + break; + case STM32_LPTIM_MODE_SINGLE: + val |= LPTIM_CR_SNGSTRT; + break; + } + + stm32_putreg32(dev, STM32_LPTIM_CR_OFFSET, val); +} + +static void stm32_lptim_resetcounter(struct stm32_lptim_dev_s *dev) +{ + uint32_t val = stm32_getreg32(dev, STM32_LPTIM_CR_OFFSET); + val |= LPTIM_CR_COUNTRST; + stm32_putreg32(dev, STM32_LPTIM_CR_OFFSET, val); +} + +static void stm32_lptim_enablerar(struct stm32_lptim_dev_s *dev, bool on) +{ + uint32_t val = stm32_getreg32(dev, STM32_LPTIM_CR_OFFSET); + + if (on) + { + val |= LPTIM_CR_RSTARE; + } + else + { + val &= ~LPTIM_CR_RSTARE; + } + + stm32_putreg32(dev, STM32_LPTIM_CR_OFFSET, val); +} + +static int stm32_lptim_setisr(struct stm32_lptim_dev_s *dev, + xcpt_t handler, void *arg, int source) +{ + int vectorno; + + DEBUGASSERT(dev != NULL); + DEBUGASSERT(source == 0); + + switch (dev->base) + { +#ifdef CONFIG_STM32_LPTIM1 + case STM32_LPTIM1_BASE: + vectorno = STM32_IRQ_LPTIM1; + break; +#endif +#ifdef CONFIG_STM32_LPTIM2 + case STM32_LPTIM2_BASE: + vectorno = STM32_IRQ_LPTIM2; + break; +#endif +#ifdef CONFIG_STM32_LPTIM3 + case STM32_LPTIM3_BASE: + vectorno = STM32_IRQ_LPTIM3; + break; +#endif +#ifdef CONFIG_STM32_LPTIM4 + case STM32_LPTIM4_BASE: + vectorno = STM32_IRQ_LPTIM4; + break; +#endif +#ifdef CONFIG_STM32_LPTIM5 + case STM32_LPTIM5_BASE: + vectorno = STM32_IRQ_LPTIM5; + break; +#endif + + default: + return -EINVAL; + } + + /* Disable interrupt when callback is removed */ + + if (!handler) + { + up_disable_irq(vectorno); + irq_detach(vectorno); + return OK; + } + + /* Otherwise set callback and enable interrupt */ + + irq_attach(vectorno, handler, arg); + up_enable_irq(vectorno); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(vectorno, NVIC_SYSH_PRIORITY_DEFAULT); +#endif + + return OK; +} + +static void stm32_lptim_enableint(struct stm32_lptim_dev_s *dev, + int source) +{ + DEBUGASSERT(dev != NULL); + + uint32_t val = stm32_getreg32(dev, STM32_LPTIM_IER_OFFSET); + val |= source; + stm32_putreg32(dev, STM32_LPTIM_IER_OFFSET, val); +} + +static void stm32_lptim_disableint(struct stm32_lptim_dev_s *dev, + int source) +{ + DEBUGASSERT(dev != NULL); + + uint32_t val = stm32_getreg32(dev, STM32_LPTIM_IER_OFFSET); + val &= ~source; + stm32_putreg32(dev, STM32_LPTIM_IER_OFFSET, val); +} + +static void stm32_lptim_ackint(struct stm32_lptim_dev_s *dev, int source) +{ + stm32_putreg32(dev, STM32_LPTIM_ICR_OFFSET, source); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +struct stm32_lptim_dev_s *stm32_lptim_init(int lptimer) +{ + struct stm32_lptim_dev_s *dev = NULL; + + /* Get structure and enable power */ + + switch (lptimer) + { +#ifdef CONFIG_STM32_LPTIM1 + case 1: + dev = &stm32_lptim1_priv; + modifyreg32(STM32_RCC_APB3ENR, 0, RCC_APB3ENR_LPTIM1EN); + break; +#endif +#ifdef CONFIG_STM32_LPTIM3 + case 3: + dev = &stm32_lptim3_priv; + modifyreg32(STM32_RCC_APB3ENR, 0, RCC_APB3ENR_LPTIM3EN); + break; +#endif +#ifdef CONFIG_STM32_LPTIM4 + case 4: + dev = &stm32_lptim4_priv; + modifyreg32(STM32_RCC_APB3ENR, 0, RCC_APB3ENR_LPTIM4EN); + break; +#endif +#ifdef CONFIG_STM32_LPTIM5 + case 5: + dev = &stm32_lptim5_priv; + modifyreg32(STM32_RCC_APB3ENR, 0, RCC_APB3ENR_LPTIM5EN); + break; +#endif +#ifdef CONFIG_STM32_LPTIM6 + case 6: + dev = &stm32_lptim6_priv; + modifyreg32(STM32_RCC_APB3ENR, 0, RCC_APB3ENR_LPTIM6EN); + break; +#endif + default: + return NULL; + } + + return dev; +} + +int stm32_lptim_deinit(struct stm32_lptim_dev_s * dev) +{ + DEBUGASSERT(dev != NULL); + + /* Disable power */ + + switch (dev->base) + { +#ifdef CONFIG_STM32_LPTIM1 + case STM32_LPTIM1_BASE: + modifyreg32(STM32_RCC_APB3ENR, RCC_APB3ENR_LPTIM1EN, 0); + break; +#endif +#ifdef CONFIG_STM32_LPTIM3 + case STM32_LPTIM3_BASE: + modifyreg32(STM32_RCC_APB3ENR, RCC_APB3ENR_LPTIM3EN, 0); + break; +#endif +#ifdef CONFIG_STM32_LPTIM4 + case STM32_LPTIM4_BASE: + modifyreg32(STM32_RCC_APB3ENR, RCC_APB3ENR_LPTIM4EN, 0); + break; +#endif +#ifdef CONFIG_STM32_LPTIM5 + case STM32_LPTIM5_BASE: + modifyreg32(STM32_RCC_APB3ENR, RCC_APB3ENR_LPTIM5EN, 0); + break; +#endif +#ifdef CONFIG_STM32_LPTIM6 + case STM32_LPTIM6_BASE: + modifyreg32(STM32_RCC_APB3ENR, RCC_APB3ENR_LPTIM6EN, 0); + break; +#endif + default: + return -EINVAL; + } + + return OK; +} + +#endif /* defined(CONFIG_STM32_LPTIM1 || ... || CONFIG_STM32_LPTIM5) */ diff --git a/arch/arm/src/stm32h5/stm32_lptim.h b/arch/arm/src/stm32h5/stm32_lptim.h new file mode 100644 index 00000000000..634be00defc --- /dev/null +++ b/arch/arm/src/stm32h5/stm32_lptim.h @@ -0,0 +1,111 @@ +/**************************************************************************** + * arch/arm/src/stm32h5/stm32_lptim.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32H5_STM32_LPTIM_H +#define __ARCH_ARM_SRC_STM32H5_STM32_LPTIM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "hardware/stm32_lptim.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +typedef enum +{ + STM32_LPTIM_MODE_CONTINUOUS = 0x00, + STM32_LPTIM_MODE_SINGLE = 0x01 +} stm32_lptim_start_mode_t; + +/* LPTIM Device Structure */ + +struct stm32_lptim_dev_s +{ + const struct stm32_lptim_ops_s *ops; + uint32_t base; +}; + +/* LPTIM Operations */ + +struct stm32_lptim_ops_s +{ + void (*setcfgr)(struct stm32_lptim_dev_s *dev, uint32_t regval); + void (*setperiod)(struct stm32_lptim_dev_s *dev, uint32_t period); + void (*setcompare)(struct stm32_lptim_dev_s *dev, uint32_t cmp); + uint32_t (*getcounter)(struct stm32_lptim_dev_s *dev); + int (*setinput)(struct stm32_lptim_dev_s *dev, uint32_t input, + uint32_t mux); + void (*enable)(struct stm32_lptim_dev_s *dev, bool on); + void (*start)(struct stm32_lptim_dev_s *dev, + stm32_lptim_start_mode_t mode); + void (*resetcounter)(struct stm32_lptim_dev_s *dev); + void (*enablerar)(struct stm32_lptim_dev_s *dev, bool on); + + /* Low-power timer interrupts */ + + int (*setisr)(struct stm32_lptim_dev_s *dev, xcpt_t handler, + void *arg, int source); + void (*enableint)(struct stm32_lptim_dev_s *dev, int source); + void (*disableint)(struct stm32_lptim_dev_s *dev, int source); + void (*ackint)(struct stm32_lptim_dev_s *dev, int source); +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Power-up low power timer and get its structure */ + +struct stm32_lptim_dev_s *stm32_lptim_init(int lptimer); + +/* Power-down low power timer, mark it as unused */ + +int stm32_lptim_deinit(struct stm32_lptim_dev_s *dev); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32H5_STM32_LPTIM_H */