diff --git a/arch/arm/src/stm32h7/Kconfig b/arch/arm/src/stm32h7/Kconfig index db108ba4eef..3f2c153d0a5 100644 --- a/arch/arm/src/stm32h7/Kconfig +++ b/arch/arm/src/stm32h7/Kconfig @@ -405,6 +405,10 @@ config STM32H7_TIM bool default n +config STM32H7_LPTIM + bool + default n + config STM32H7_RTC bool "RTC" default n @@ -711,6 +715,35 @@ config STM32H7_TIM17 endmenu # STM32H7 Timer Selection +menu "STM32H7 Low-power Timer Selection" + +config STM32H7_LPTIM1 + bool "LPTIM1" + default n + select STM32H7_LPTIM + +config STM32H7_LPTIM2 + bool "LPTIM2" + default n + select STM32H7_LPTIM + +config STM32H7_LPTIM3 + bool "LPTIM3" + default n + select STM32H7_LPTIM + +config STM32H7_LPTIM4 + bool "LPTIM4" + default n + select STM32H7_LPTIM + +config STM32H7_LPTIM5 + bool "LPTIM5" + default n + select STM32H7_LPTIM + +endmenu # STM32H7 Timer Selection + menu "STM32H7 U[S]ART Selection" config STM32H7_USART1 diff --git a/arch/arm/src/stm32h7/Make.defs b/arch/arm/src/stm32h7/Make.defs index 2085559f52b..b10ff694dbb 100644 --- a/arch/arm/src/stm32h7/Make.defs +++ b/arch/arm/src/stm32h7/Make.defs @@ -185,6 +185,10 @@ ifeq ($(CONFIG_STM32H7_TIM),y) CHIP_CSRCS += stm32_tim.c endif +ifeq ($(CONFIG_STM32H7_LPTIM),y) +CHIP_CSRCS += stm32_lptim.c +endif + ifeq ($(CONFIG_STM32H7_PWM),y) CHIP_CSRCS += stm32_pwm.c endif diff --git a/arch/arm/src/stm32h7/hardware/stm32_lptim.h b/arch/arm/src/stm32h7/hardware/stm32_lptim.h new file mode 100644 index 00000000000..cae2f8e24d8 --- /dev/null +++ b/arch/arm/src/stm32h7/hardware/stm32_lptim.h @@ -0,0 +1,176 @@ +/**************************************************************************** + * arch/arm/src/stm32h7/hardware/stm32_lptim.h + * + * 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_STM32H7_HARDWARE_STM32_LPTIM_H +#define __ARCH_ARM_SRC_STM32H7_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_LPTIM2_ISR (STM32_LPTIM2_BASE+STM32_LPTIM_ISR_OFFSET) +# define STM32_LPTIM2_ICR (STM32_LPTIM2_BASE+STM32_LPTIM_ICR_OFFSET) +# define STM32_LPTIM2_IER (STM32_LPTIM2_BASE+STM32_LPTIM_IER_OFFSET) +# define STM32_LPTIM2_CFGR (STM32_LPTIM2_BASE+STM32_LPTIM_CFGR_OFFSET) +# define STM32_LPTIM2_CR (STM32_LPTIM2_BASE+STM32_LPTIM_CR_OFFSET) +# define STM32_LPTIM2_CMP (STM32_LPTIM2_BASE+STM32_LPTIM_CMP_OFFSET) +# define STM32_LPTIM2_ARR (STM32_LPTIM2_BASE+STM32_LPTIM_ARR_OFFSET) +# define STM32_LPTIM2_CNT (STM32_LPTIM2_BASE+STM32_LPTIM_CNT_OFFSET) +# define STM32_LPTIM2_CFGR2 (STM32_LPTIM2_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_IxR_CMPM (1 << 0) /* Bit 0: Compare match */ +#define LPTIM_IxR_ARRM (1 << 1) /* Bit 1: Autoreload match */ +#define LPTIM_IxR_EXTTRIG (1 << 2) /* Bit 2: External trigger edge event */ +#define LPTIM_IxR_CMPOK (1 << 3) /* Bit 3: Compare register update OK */ +#define LPTIM_IxR_ARROK (1 << 4) /* Bit 4: Autoreload register update OK */ +#define LPTIM_IxR_UP (1 << 5) /* Bit 5: Counter direction change down to up */ +#define LPTIM_IxR_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_STM32H7_HARDWARE_STM32_LPTIM_H */ diff --git a/arch/arm/src/stm32h7/stm32_lptim.c b/arch/arm/src/stm32h7/stm32_lptim.c new file mode 100644 index 00000000000..a00ae222765 --- /dev/null +++ b/arch/arm/src/stm32h7/stm32_lptim.c @@ -0,0 +1,471 @@ +/**************************************************************************** + * arch/arm/src/stm32h7/stm32_lptim.c + * + * 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 "arm_arch.h" + +#include "stm32_rcc.h" +#include "stm32_gpio.h" +#include "stm32_lptim.h" + +#if defined(CONFIG_STM32H7_LPTIM1) || defined(CONFIG_STM32H7_LPTIM2) || \ + defined(CONFIG_STM32H7_LPTIM3) || defined(CONFIG_STM32H7_LPTIM4) || \ + defined(CONFIG_STM32H7_LPTIM5) + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +/* Low-power timer methods */ + +static void stm32_lptim_setcfgr(FAR struct stm32_lptim_dev_s *dev, + uint32_t regval); +static void stm32_lptim_setperiod(FAR struct stm32_lptim_dev_s *dev, + uint32_t period); +static void stm32_lptim_setcompare(FAR struct stm32_lptim_dev_s *dev, + uint32_t cmp); +static uint32_t stm32_lptim_getcounter(FAR struct stm32_lptim_dev_s *dev); +static int stm32_lptim_setinput(FAR struct stm32_lptim_dev_s *dev, + uint32_t input, uint32_t mux); +static void stm32_lptim_enable(FAR struct stm32_lptim_dev_s *dev, bool on); +static void stm32_lptim_start(FAR struct stm32_lptim_dev_s *dev, + stm32_lptim_start_mode_t mode); +static void stm32_lptim_resetcounter(FAR struct stm32_lptim_dev_s *dev); +static void stm32_lptim_enablerar(FAR struct stm32_lptim_dev_s *dev, + bool on); + +static int stm32_lptim_setisr(FAR struct stm32_lptim_dev_s *dev, + xcpt_t handler, void *arg, int source); +static void stm32_lptim_enableint(FAR struct stm32_lptim_dev_s *dev, + int source); +static void stm32_lptim_disableint(FAR struct stm32_lptim_dev_s *dev, + int source); +static void stm32_lptim_ackint(FAR 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_STM32H7_LPTIM1 +struct stm32_lptim_dev_s stm32_lptim1_priv = +{ + .ops = &stm32_lptim_ops, + .base = STM32_LPTIM1_BASE, +}; +#endif +#ifdef CONFIG_STM32H7_LPTIM2 +struct stm32_lptim_dev_s stm32_lptim2_priv = +{ + .ops = &stm32_lptim_ops, + .base = STM32_LPTIM2_BASE, +}; +#endif +#ifdef CONFIG_STM32H7_LPTIM3 +struct stm32_lptim_dev_s stm32_lptim3_priv = +{ + .ops = &stm32_lptim_ops, + .base = STM32_LPTIM3_BASE, +}; +#endif +#ifdef CONFIG_STM32H7_LPTIM4 +struct stm32_lptim_dev_s stm32_lptim4_priv = +{ + .ops = &stm32_lptim_ops, + .base = STM32_LPTIM4_BASE, +}; +#endif +#ifdef CONFIG_STM32H7_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(FAR 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(FAR struct stm32_lptim_dev_s *dev, + uint8_t offset, uint32_t value) +{ + putreg32(value, dev->base + offset); +} + +static void stm32_lptim_setcfgr(FAR struct stm32_lptim_dev_s *dev, + uint32_t regval) +{ + stm32_putreg32(dev, STM32_LPTIM_CFGR_OFFSET, regval); +} + +static void stm32_lptim_setperiod(FAR struct stm32_lptim_dev_s *dev, + uint32_t period) +{ + stm32_putreg32(dev, STM32_LPTIM_ARR_OFFSET, period); +} + +static void stm32_lptim_setcompare(FAR struct stm32_lptim_dev_s *dev, + uint32_t cmp) +{ + stm32_putreg32(dev, STM32_LPTIM_CMP_OFFSET, cmp); +} + +static uint32_t stm32_lptim_getcounter(FAR 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(FAR struct stm32_lptim_dev_s *dev, + uint32_t input, uint32_t mux) +{ + switch (dev->base) + { +#if defined(CONFIG_STM32H7_LPTIM1) || defined(CONFIG_STM32H7_LPTIM2) + case STM32_LPTIM1_BASE: + case STM32_LPTIM2_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_STM32H7_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(FAR 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(FAR 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(FAR 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(FAR 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(FAR 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_STM32H7_LPTIM1 + case STM32_LPTIM1_BASE: + vectorno = STM32_IRQ_LPTIM1; + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM2 + case STM32_LPTIM2_BASE: + vectorno = STM32_IRQ_LPTIM2; + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM3 + case STM32_LPTIM3_BASE: + vectorno = STM32_IRQ_LPTIM3; + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM4 + case STM32_LPTIM4_BASE: + vectorno = STM32_IRQ_LPTIM4; + break; +#endif +#ifdef CONFIG_STM32H7_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(FAR 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(FAR 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(FAR struct stm32_lptim_dev_s *dev, int source) +{ + stm32_putreg32(dev, STM32_LPTIM_ICR_OFFSET, source); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +FAR 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_STM32H7_LPTIM1 + case 1: + dev = &stm32_lptim1_priv; + modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_LPTIM1EN); + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM2 + case 2: + dev = &stm32_lptim2_priv; + modifyreg32(STM32_RCC_APB4ENR, 0, RCC_APB4ENR_LPTIM2EN); + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM3 + case 3: + dev = &stm32_lptim3_priv; + modifyreg32(STM32_RCC_APB4ENR, 0, RCC_APB4ENR_LPTIM3EN); + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM4 + case 4: + dev = &stm32_lptim4_priv; + modifyreg32(STM32_RCC_APB4ENR, 0, RCC_APB4ENR_LPTIM4EN); + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM5 + case 5: + dev = &stm32_lptim5_priv; + modifyreg32(STM32_RCC_APB4ENR, 0, RCC_APB4ENR_LPTIM5EN); + break; +#endif + default: + return NULL; + } + + return dev; +} + +int stm32_lptim_deinit(FAR struct stm32_lptim_dev_s * dev) +{ + DEBUGASSERT(dev != NULL); + + /* Disable power */ + + switch (dev->base) + { +#ifdef CONFIG_STM32H7_LPTIM1 + case STM32_LPTIM1_BASE: + modifyreg32(STM32_RCC_APB1LLPENR, RCC_APB1LENR_LPTIM1EN, 0); + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM2 + case STM32_LPTIM2_BASE: + modifyreg32(STM32_RCC_APB4LPENR, RCC_APB4ENR_LPTIM2EN, 0); + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM3 + case STM32_LPTIM3_BASE: + modifyreg32(STM32_RCC_APB4LPENR, RCC_APB4ENR_LPTIM3EN, 0); + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM4 + case STM32_LPTIM4_BASE: + modifyreg32(STM32_RCC_APB4LPENR, RCC_APB4ENR_LPTIM4EN, 0); + break; +#endif +#ifdef CONFIG_STM32H7_LPTIM5 + case STM32_LPTIM5_BASE: + modifyreg32(STM32_RCC_APB4LPENR, RCC_APB4ENR_LPTIM5EN, 0); + break; +#endif + default: + return -EINVAL; + } + + return OK; +} + +#endif /* defined(CONFIG_STM32H7_LPTIM1 || ... || CONFIG_STM32H7_LPTIM5) */ diff --git a/arch/arm/src/stm32h7/stm32_lptim.h b/arch/arm/src/stm32h7/stm32_lptim.h new file mode 100644 index 00000000000..f16256b0ad1 --- /dev/null +++ b/arch/arm/src/stm32h7/stm32_lptim.h @@ -0,0 +1,109 @@ +/**************************************************************************** + * arch/arm/src/stm32h7/stm32_lptim.h + * + * 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_STM32H7_STM32_LPTIM_H +#define __ARCH_ARM_SRC_STM32H7_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)(FAR struct stm32_lptim_dev_s *dev, uint32_t regval); + void (*setperiod)(FAR struct stm32_lptim_dev_s *dev, uint32_t period); + void (*setcompare)(FAR struct stm32_lptim_dev_s *dev, uint32_t cmp); + uint32_t (*getcounter)(FAR struct stm32_lptim_dev_s *dev); + int (*setinput)(FAR struct stm32_lptim_dev_s *dev, uint32_t input, + uint32_t mux); + void (*enable)(FAR struct stm32_lptim_dev_s *dev, bool on); + void (*start)(FAR struct stm32_lptim_dev_s *dev, + stm32_lptim_start_mode_t mode); + void (*resetcounter)(FAR struct stm32_lptim_dev_s *dev); + void (*enablerar)(FAR struct stm32_lptim_dev_s *dev, bool on); + + /* Low-power timer interrupts */ + + int (*setisr)(FAR struct stm32_lptim_dev_s *dev, xcpt_t handler, + void *arg, int source); + void (*enableint)(FAR struct stm32_lptim_dev_s *dev, int source); + void (*disableint)(FAR struct stm32_lptim_dev_s *dev, int source); + void (*ackint)(FAR struct stm32_lptim_dev_s *dev, int source); +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Power-up low power timer and get its structure */ + +FAR struct stm32_lptim_dev_s *stm32_lptim_init(int lptimer); + +/* Power-down low power timer, mark it as unused */ + +int stm32_lptim_deinit(FAR struct stm32_lptim_dev_s *dev); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32H7_STM32_LPTIM_H */