mirror of
https://github.com/apache/nuttx.git
synced 2026-08-27 04:10:40 +00:00
arch/arm/stm32h5: Add LPTIM support.
Add LPTIM 1, 3, 4, 5 support. Based on STM32H7. setperiod and setcompare have been made to wait for the auto-reload value to be applied before returning. 6 is absent since generic stm32 configs for a 6th LPTIM are not present yet. 2 is absent for no good reason besides maybe that it's in a different RCC APB register. I am not adding support last-minute without more testing. The build fails noisily when LPTIM2 is enabled so the shortcoming is clear. Corrected some RCC definitions. They are needed for selecting the LPTIMx clock source. This is not done in the LPTIM driver. It is done outside and the definitions should ideally be correct for that. Signed-off-by: Liam Howatt <liamhowatt@geotab.com> Co-authored-by: Farzan Farhangian <farzanfarhangian@geotab.com>
This commit is contained in:
parent
c92b1ed9ac
commit
10d0fa4485
8 changed files with 830 additions and 24 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
168
arch/arm/src/stm32h5/hardware/stm32_lptim.h
Normal file
168
arch/arm/src/stm32h5/hardware/stm32_lptim.h
Normal file
|
|
@ -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 <nuttx/config.h>
|
||||
#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 */
|
||||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
514
arch/arm/src/stm32h5/stm32_lptim.c
Normal file
514
arch/arm/src/stm32h5/stm32_lptim.c
Normal file
|
|
@ -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 <nuttx/config.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <nuttx/debug.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#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) */
|
||||
111
arch/arm/src/stm32h5/stm32_lptim.h
Normal file
111
arch/arm/src/stm32h5/stm32_lptim.h
Normal file
|
|
@ -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 <nuttx/config.h>
|
||||
|
||||
#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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue