/**************************************************************************** * arch/arm/src/stm32/stm32_hrtim.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 "chip.h" #include "stm32.h" #include "stm32_gpio.h" #include "stm32_hrtim.h" #if defined(CONFIG_STM32_HRTIM1) /* Only STM32F33XXX */ #if defined(CONFIG_STM32_STM32F33XX) #if defined(CONFIG_STM32_HRTIM_TIMA_PWM) || defined(CONFIG_STM32_HRTIM_TIMA_DAC) || \ defined(CONFIG_STM32_HRTIM_TIMA_CAP) || defined(CONFIG_STM32_HRTIM_TIMA_IRQ) || \ defined(CONFIG_STM32_HRTIM_TIMA_DT) || defined(CONFIG_STM32_HRTIM_TIMA_CHOP) # ifndef CONFIG_STM32_HRTIM_TIMA # error "CONFIG_STM32_HRTIM_TIMA must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIMB_PWM) || defined(CONFIG_STM32_HRTIM_TIMB_DAC) || \ defined(CONFIG_STM32_HRTIM_TIMB_CAP) || defined(CONFIG_STM32_HRTIM_TIMB_IRQ) || \ defined(CONFIG_STM32_HRTIM_TIMB_DT) || defined(CONFIG_STM32_HRTIM_TIMB_CHOP) # ifndef CONFIG_STM32_HRTIM_TIMB # error "CONFIG_STM32_HRTIM_TIMB must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIMC_PWM) || defined(CONFIG_STM32_HRTIM_TIMC_DAC) || \ defined(CONFIG_STM32_HRTIM_TIMC_CAP) || defined(CONFIG_STM32_HRTIM_TIMC_IRQ) || \ defined(CONFIG_STM32_HRTIM_TIMC_DT) || defined(CONFIG_STM32_HRTIM_TIMC_CHOP) # ifndef CONFIG_STM32_HRTIM_TIMC # error "CONFIG_STM32_HRTIM_TIMC must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIMD_PWM) || defined(CONFIG_STM32_HRTIM_TIMD_DAC) || \ defined(CONFIG_STM32_HRTIM_TIMD_CAP) || defined(CONFIG_STM32_HRTIM_TIMD_IRQ) || \ defined(CONFIG_STM32_HRTIM_TIMD_DT) || defined(CONFIG_STM32_HRTIM_TIMD_CHOP) # ifndef CONFIG_STM32_HRTIM_TIMD # error "CONFIG_STM32_HRTIM_TIMD must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIME_PWM) || defined(CONFIG_STM32_HRTIM_TIME_DAC) || \ defined(CONFIG_STM32_HRTIM_TIME_CAP) || defined(CONFIG_STM32_HRTIM_TIME_IRQ) || \ defined(CONFIG_STM32_HRTIM_TIME_DT) || defined(CONFIG_STM32_HRTIM_TIME_CHOP) # ifndef CONFIG_STM32_HRTIM_TIME # error "CONFIG_STM32_HRTIM_TIME must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_PWM) #if !defined(CONFIG_STM32_HRTIM_TIMA_PWM) && !defined(CONFIG_STM32_HRTIM_TIMB_PWM) && \ !defined(CONFIG_STM32_HRTIM_TIMC_PWM) && !defined(CONFIG_STM32_HRTIM_TIMD_PWM) && \ !defined(CONFIG_STM32_HRTIM_TIME_PWM) # warning "CONFIG_STM32_HRTIM_PWM enabled but no timer selected" # endif #endif #if defined(CONFIG_STM32_HRTIM_DAC) #if !defined(CONFIG_STM32_HRTIM_MASTER_DAC) && !defined(CONFIG_STM32_HRTIM_TIMA_DAC) && \ !defined(CONFIG_STM32_HRTIM_TIMB_DAC) && !defined(CONFIG_STM32_HRTIM_TIMC_DAC) && \ !defined(CONFIG_STM32_HRTIM_TIMD_DAC) && !defined(CONFIG_STM32_HRTIM_TIME_DAC) # warning "CONFIG_STM32_HRTIM_DAC enabled but no timer selected" # endif #endif #if defined(CONFIG_STM32_HRTIM_CAPTURE) #if !defined(CONFIG_STM32_HRTIM_TIMA_CAP) && !defined(CONFIG_STM32_HRTIM_TIMB_CAP) && \ !defined(CONFIG_STM32_HRTIM_TIMC_CAP) && !defined(CONFIG_STM32_HRTIM_TIMD_CAP) && \ !defined(CONFIG_STM32_HRTIM_TIME_CAP) # warning "CONFIG_STM32_HRTIM_CAPTURE enabled but no timer selected" # endif #endif #if defined(CONFIG_STM32_HRTIM_INTERRUPTS) #if !defined(CONFIG_STM32_HRTIM_MASTER_IRQ) && !defined(CONFIG_STM32_HRTIM_TIMA_IRQ) && \ !defined(CONFIG_STM32_HRTIM_TIMB_IRQ) && !defined(CONFIG_STM32_HRTIM_TIMC_IRQ) && \ !defined(CONFIG_STM32_HRTIM_TIMD_IRQ) && !defined(CONFIG_STM32_HRTIM_TIME_IRQ) && \ !defined(CONFIG_STM32_HRTIM_COMMON_IRQ) # warning "CONFIG_STM32_HRTIM_INTERRUPTS enabled but no timer selected" # endif #endif #if defined(CONFIG_STM32_HRTIM_DEADTIME) #if !defined(CONFIG_STM32_HRTIM_TIMA_DT) && !defined(CONFIG_STM32_HRTIM_TIMB_DT) && \ !defined(CONFIG_STM32_HRTIM_TIMC_DT) && !defined(CONFIG_STM32_HRTIM_TIMD_DT) && \ !defined(CONFIG_STM32_HRTIM_TIME_DT) # warning "CONFIG_STM32_HRTIM_DEADTIME enabled but no timer selected" # endif #endif #if defined(CONFIG_STM32_HRTIM_CHOPPER) #if !defined(CONFIG_STM32_HRTIM_TIMA_CHOP) && !defined(CONFIG_STM32_HRTIM_TIMB_CHOP) && \ !defined(CONFIG_STM32_HRTIM_TIMC_CHOP) && !defined(CONFIG_STM32_HRTIM_TIMD_CHOP) && \ !defined(CONFIG_STM32_HRTIM_TIME_CHOP) # warning "CONFIG_STM32_HRTIM_CHOPPER enabled but no timer selected" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIMA_PWM) || defined(CONFIG_STM32_HRTIM_TIMB_PWM) || \ defined(CONFIG_STM32_HRTIM_TIMC_PWM) || defined(CONFIG_STM32_HRTIM_TIMD_PWM) || \ defined(CONFIG_STM32_HRTIM_TIME_PWM) # ifndef CONFIG_STM32_HRTIM_PWM # error "CONFIG_STM32_HRTIM_PWM must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_MASTER_DAC) || defined(CONFIG_STM32_HRTIM_TIMA_DAC) || \ defined(CONFIG_STM32_HRTIM_TIMB_DAC) || defined(CONFIG_STM32_HRTIM_TIMC_DAC) || \ defined(CONFIG_STM32_HRTIM_TIMD_DAC) || defined(CONFIG_STM32_HRTIM_TIME_DAC) # ifndef CONFIG_STM32_HRTIM_DAC # error "CONFIG_STM32_HRTIM_DAC must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIMA_CAP) || defined(CONFIG_STM32_HRTIM_TIMB_CAP) || \ defined(CONFIG_STM32_HRTIM_TIMC_CAP) || defined(CONFIG_STM32_HRTIM_TIMD_CAP) || \ defined(CONFIG_STM32_HRTIM_TIME_CAP) # ifndef CONFIG_STM32_HRTIM_CAPTURE # error "CONFIG_STM32_HRTIM_CAPTURE must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIMA_IRQ) || defined(CONFIG_STM32_HRTIM_TIMB_IRQ) || \ defined(CONFIG_STM32_HRTIM_TIMC_IRQ) || defined(CONFIG_STM32_HRTIM_TIMD_IRQ) || \ defined(CONFIG_STM32_HRTIM_TIME_IRQ) # ifndef CONFIG_STM32_HRTIM_INTERRUPTS # error "CONFIG_STM32_HRTIM_INTERRUPTS must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIMA_DT) || defined(CONFIG_STM32_HRTIM_TIMB_DT) || \ defined(CONFIG_STM32_HRTIM_TIMC_DT) || defined(CONFIG_STM32_HRTIM_TIMD_DT) || \ defined(CONFIG_STM32_HRTIM_TIME_DT) # ifndef CONFIG_STM32_HRTIM_DEADTIME # error "CONFIG_STM32_HRTIM_DEADTIME must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIMA_CHOP) || defined(CONFIG_STM32_HRTIM_TIMB_CHOP) || \ defined(CONFIG_STM32_HRTIM_TIMC_CHOP) || defined(CONFIG_STM32_HRTIM_TIMD_CHOP) || \ defined(CONFIG_STM32_HRTIM_TIME_CHOP) # ifndef CONFIG_STM32_HRTIM_CHOPPER # error "CONFIG_STM32_HRTIM_CHOPPER must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIMA_PSHPLL) || defined(CONFIG_STM32_HRTIM_TIMB_PSHPLL) || \ defined(CONFIG_STM32_HRTIM_TIMC_PSHPLL) || defined(CONFIG_STM32_HRTIM_TIMD_PSHPLL) || \ defined(CONFIG_STM32_HRTIM_TIME_PSHPLL) # ifndef CONFIG_STM32_HRTIM_PUSHPULL # error "CONFIG_STM32_HRTIM_PUSHPULL must be set" # endif #endif #if defined(CONFIG_STM32_HRTIM_TIMA_DT) && defined(CONFIG_STM32_HRTIM_TIMA_PSHPLL) # error "The deadtime cannot be used simultaneously with the push-pull mode" #endif #if defined(CONFIG_STM32_HRTIM_TIMB_DT) && defined(CONFIG_STM32_HRTIM_TIMB_PSHPLL) # error "The deadtime cannot be used simultaneously with the push-pull mode" #endif #if defined(CONFIG_STM32_HRTIM_TIMC_DT) && defined(CONFIG_STM32_HRTIM_TIMC_PSHPLL) # error "The deadtime cannot be used simultaneously with the push-pull mode" #endif #if defined(CONFIG_STM32_HRTIM_TIMD_DT) && defined(CONFIG_STM32_HRTIM_TIMD_PSHPLL) # error "The deadtime cannot be used simultaneously with the push-pull mode" #endif #if defined(CONFIG_STM32_HRTIM_TIME_DT) && defined(CONFIG_STM32_HRTIM_TIME_PSHPLL) # error "The deadtime cannot be used simultaneously with the push-pull mode" #endif #if defined(CONFIG_STM32_HRTIM_ADC1_TRG1) || defined(CONFIG_STM32_HRTIM_ADC1_TRG2) || \ defined(CONFIG_STM32_HRTIM_ADC1_TRG3) || defined(CONFIG_STM32_HRTIM_ADC1_TRG4) || \ defined(CONFIG_STM32_HRTIM_ADC2_TRG1) || defined(CONFIG_STM32_HRTIM_ADC2_TRG2) || \ defined(CONFIG_STM32_HRTIM_ADC2_TRG3) || defined(CONFIG_STM32_HRTIM_ADC2_TRG4) # define HRTIM_HAVE_ADC #endif #if defined(CONFIG_STM32_HRTIM_ADC1_TRG1) || defined(CONFIG_STM32_HRTIM_ADC2_TRG1) # define HRTIM_HAVE_ADC_TRG1 #endif #if defined(CONFIG_STM32_HRTIM_ADC1_TRG2) || defined(CONFIG_STM32_HRTIM_ADC2_TRG2) # define HRTIM_HAVE_ADC_TRG2 #endif #if defined(CONFIG_STM32_HRTIM_ADC1_TRG3) || defined(CONFIG_STM32_HRTIM_ADC2_TRG3) # define HRTIM_HAVE_ADC_TRG3 #endif #if defined(CONFIG_STM32_HRTIM_ADC1_TRG4) || defined(CONFIG_STM32_HRTIM_ADC2_TRG4) # define HRTIM_HAVE_ADC_TRG4 #endif /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ /* HRTIM default configuration **********************************************/ #if defined(CONFIG_STM32_HRTIM_MASTER) && !defined(HRTIM_MASTER_MODE) # warning "HRTIM_MASTER_MODE is not set. Set the default value 0" # define HRTIM_MASTER_MODE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMA) && !defined( HRTIM_TIMA_MODE) # warning "HRTIM_TIMA_MODE is not set. Set the default value 0" # define HRTIM_TIMA_MODE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMB) && !defined(HRTIM_TIMB_MODE) # warning "HRTIM_TIMB_MODE is not set. Set the default value 0" # define HRTIM_TIMB_MODE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMC) && !defined(HRTIM_TIMC_MODE) # warning "HRTIM_TIMC_MODE is not set. Set the default value 0" # define HRTIM_TIMC_MODE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMD) && !defined(HRTIM_TIMD_MODE) # warning "HRTIM_TIMD_MODE is not set. Set the default value 0" # define HRTIM_TIMD_MODE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIME) && !defined(HRTIM_TIME_MODE) # warning "HRTIM_TIME_MODE is not set. Set the default value 0" # define HRTIM_TIME_MODE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMA) && !defined(HRTIM_TIMA_UPDATE) # warning "HRTIM_TIMA_UPDATE is not set. Set the default value 0" # define HRTIM_TIMA_UPDATE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMB) && !defined(HRTIM_TIMB_UPDATE) # warning "HRTIM_TIMB_UPDATE is not set. Set the default value 0" # define HRTIM_TIMB_UPDATE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMC) && !defined(HRTIM_TIMC_UPDATE) # warning "HRTIM_TIMC_UPDATE is not set. Set the default value 0" # define HRTIM_TIMC_UPDATE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMD) && !defined(HRTIM_TIMD_UPDATE) # warning "HRTIM_TIMD_UPDATE is not set. Set the default value 0" # define HRTIM_TIMD_UPDATE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIME) && !defined(HRTIM_TIME_UPDATE) # warning "HRTIM_TIME_UPDATE is not set. Set the default value 0" # define HRTIM_TIME_UPDATE 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMA) && !defined( HRTIM_TIMA_RESET) # warning "HRTIM_TIMA_RESET is not set. Set the default value 0" # define HRTIM_TIMA_RESET 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMB) && !defined(HRTIM_TIMB_RESET) # warning "HRTIM_TIMB_RESET is not set. Set the default value 0" # define HRTIM_TIMB_RESET 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMC) && !defined(HRTIM_TIMC_RESET) # warning "HRTIM_TIMC_RESET is not set. Set the default value 0" # define HRTIM_TIMC_RESET 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMD) && !defined(HRTIM_TIMD_RESET) # warning "HRTIM_TIMD_RESET is not set. Set the default value 0" # define HRTIM_TIMD_RESET 0 #endif #if defined(CONFIG_STM32_HRTIM_TIME) && !defined(HRTIM_TIME_RESET) # warning "HRTIM_TIME_RESET is not set. Set the default value 0" # define HRTIM_TIME_RESET 0 #endif #ifndef HRTIM_IRQ_COMMON # define HRTIM_IRQ_COMMON 0 #endif #if defined(CONFIG_STM32_HRTIM_TIMA) && !defined(HRTIM_TIMA_CH1_POL) # define HRTIM_TIMA_CH1_POL HRTIM_OUT_POL_POS #endif #if defined(CONFIG_STM32_HRTIM_TIMA) && !defined(HRTIM_TIMA_CH2_POL) # define HRTIM_TIMA_CH2_POL HRTIM_OUT_POL_POS #endif #if defined(CONFIG_STM32_HRTIM_TIMB) && !defined(HRTIM_TIMB_CH1_POL) # define HRTIM_TIMB_CH1_POL HRTIM_OUT_POL_POS #endif #if defined(CONFIG_STM32_HRTIM_TIMB) && !defined(HRTIM_TIMB_CH2_POL) # define HRTIM_TIMB_CH2_POL HRTIM_OUT_POL_POS #endif #if defined(CONFIG_STM32_HRTIM_TIMC) && !defined(HRTIM_TIMC_CH1_POL) # define HRTIM_TIMC_CH1_POL HRTIM_OUT_POL_POS #endif #if defined(CONFIG_STM32_HRTIM_TIMC) && !defined(HRTIM_TIMC_CH2_POL) # define HRTIM_TIMC_CH2_POL HRTIM_OUT_POL_POS #endif #if defined(CONFIG_STM32_HRTIM_TIMD) && !defined(HRTIM_TIMD_CH1_POL) # define HRTIM_TIMD_CH1_POL HRTIM_OUT_POL_POS #endif #if defined(CONFIG_STM32_HRTIM_TIMD) && !defined(HRTIM_TIMD_CH2_POL) # define HRTIM_TIMD_CH2_POL HRTIM_OUT_POL_POS #endif #if defined(CONFIG_STM32_HRTIM_TIME) && !defined(HRTIM_TIME_CH1_POL) # define HRTIM_TIME_CH1_POL HRTIM_OUT_POL_POS #endif #if defined(CONFIG_STM32_HRTIM_TIME) && !defined(HRTIM_TIME_CH2_POL) # define HRTIM_TIME_CH2_POL HRTIM_OUT_POL_POS #endif /**************************************************************************** * Private Types ****************************************************************************/ #ifdef CONFIG_STM32_HRTIM_PWM /* HRTIM Slave Timer Single Output Set/Reset Configuration */ struct stm32_hrtim_timout_s { uint32_t set; /* Set events */ uint32_t rst; /* Reset events */ uint8_t pol:1; /* Output polarisation */ }; /* HRTIM Slave Timer Chopper Configuration */ #ifdef CONFIG_STM32_HRTIM_CHOPPER struct stm32_hrtim_chopper_s { uint16_t start_pulse:4; /* Chopper start pulsewidth */ uint16_t freq:4; /* Chopper carrier frequency value */ uint16_t duty:3; /* Chopper duty cycle */ uint16_t _res:5; /* Reserved */ }; #endif /* HRTIM Slave Timer Deadtime Configuration */ #ifdef CONFIG_STM32_HRTIM_DEADTIME struct stm32_hrtim_deadtime_s { uint8_t en:1; /* Enable deadtime for timer */ uint8_t fsign_lock:1; /* Deadtime falling sing lock */ uint8_t rsign_lock:1; /* Deadtime rising sing lock */ uint8_t falling_lock:1; /* Deadtime falling value lock */ uint8_t rising_lock:1; /* Deadtime rising value lock */ uint8_t fsign:1; /* Deadtime falling sign */ uint8_t rsign:1; /* Deadtime rising sign */ uint8_t prescaler:3; /* Deadtime prescaler */ uint16_t rising:9; /* Deadtime rising value */ uint16_t falling:9; /* Deadtime falling value */ }; #endif /* HRTIM Timer Burst Mode Configuration */ struct stm32_hrtim_tim_burst_s { uint8_t ch1_en:1; /* Enable burst mode operation for CH1 */ uint8_t ch1_state:1; /* CH1 IDLE state */ uint8_t ch2_en:1; /* Enable burst mode operation for CH2 */ uint8_t ch2_state:1; /* CH2 IDLE state */ uint8_t res:4; }; /* HRTIM Timer PWM structure */ struct stm32_hrtim_pwm_s { uint8_t pushpull:1; uint8_t res:7; struct stm32_hrtim_timout_s ch1; /* Channel 1 Set/Reset configuration */ struct stm32_hrtim_timout_s ch2; /* Channel 2 Set/Reset configuration */ #ifdef CONFIG_STM32_HRTIM_BURST struct stm32_hrtim_tim_burst_s burst; #endif #ifdef CONFIG_STM32_HRTIM_CHOPPER struct stm32_hrtim_chopper_s chp; #endif #ifdef CONFIG_STM32_HRTIM_DEADTIME struct stm32_hrtim_deadtime_s dt; #endif }; #endif /* HRTIM TIMER Capture structure */ #ifdef CONFIG_STM32_HRTIM_CAPTURE struct stm32_hrtim_capture_s { uint32_t cap1; /* Capture 1 configuration */ uint32_t cap2; /* Capture 2 configuration */ }; #endif /* Common data structure for Master Timer and Slave Timers */ struct stm32_hrtim_timcmn_s { uint32_t base; /* The base address of the timer */ uint64_t fclk; /* The frequency of the peripheral clock * that drives the timer module. */ uint8_t prescaler:3; /* Prescaler */ uint8_t mode; /* Timer mode */ uint8_t dac:2; /* DAC triggering */ uint8_t reserved:3; #ifdef CONFIG_STM32_HRTIM_INTERRUPTS uint16_t irq; /* interrupts configuration */ #endif #ifdef CONFIG_STM32_HRTIM_DMA uint16_t dma; #endif #ifdef CONFIG_STM32_HRTIM_DMABURST uint32_t dmaburst; #endif }; /* Master Timer and Slave Timers structure */ struct stm32_hrtim_tim_s { struct stm32_hrtim_timcmn_s tim; /* Common Timer data */ FAR void *priv; /* Timer private data */ }; /* Master Timer private data structure */ struct stm32_hrtim_master_priv_s { uint32_t reserved; /* reserved for future use */ }; /* Slave Timer (A-E) private data structure */ struct stm32_hrtim_slave_priv_s { #ifdef CONFIG_STM32_HRTIM_FAULTS uint8_t flt; /* Faults configuration. * First five bits are fault sources, * last bit is lock configuration. */ #ifdef CONFIG_STM32_HRTIM_AUTODELAYED uint8_t auto_delayed; /* Auto-delayed mode configuration */ #endif #endif uint16_t update; /* Update configuration */ uint64_t reset; /* Timer reset events */ #ifdef CONFIG_STM32_HRTIM_PWM struct stm32_hrtim_pwm_s pwm; /* PWM configuration */ #endif #ifdef CONFIG_STM32_HRTIM_CAPTURE struct stm32_hrtim_capture_s cap; /* Capture configuration */ #endif }; #ifdef CONFIG_STM32_HRTIM_FAULTS /* Structure describes single HRTIM Fault configuration */ struct stm32_hrtim_fault_cfg_s { uint8_t pol:1; /* Fault polarity */ uint8_t src:1; /* Fault source */ uint8_t filter:4; /* Fault filter */ uint8_t lock:1; /* Fault lock */ uint8_t _res:1; /* Reserved */ }; /* Structure describes HRTIM Faults configuration */ struct stm32_hrtim_faults_s { #ifdef CONFIG_STM32_HRTIM_FAULT1 struct stm32_hrtim_fault_cfg_s flt1; #endif #ifdef CONFIG_STM32_HRTIM_FAULT2 struct stm32_hrtim_fault_cfg_s flt2; #endif #ifdef CONFIG_STM32_HRTIM_FAULT3 struct stm32_hrtim_fault_cfg_s flt3; #endif #ifdef CONFIG_STM32_HRTIM_FAULT4 struct stm32_hrtim_fault_cfg_s flt4; #endif #ifdef CONFIG_STM32_HRTIM_FAULT5 struct stm32_hrtim_fault_cfg_s flt5; #endif }; #endif #ifdef CONFIG_STM32_HRTIM_EVENTS /* Structure describes single HRTIM External Event configuration */ struct stm32_hrtim_eev_cfg_s { uint8_t filter:4; /* External Event filter */ uint8_t src:4; /* External Event source */ uint8_t pol:1; /* External Event polarity */ uint8_t sen:1; /* External Event sensitivity */ uint8_t mode:1; /* External Event mode */ uint8_t _res:5; }; /* Structure describes HRTIM External Events configuration */ struct stm32_hrtim_eev_s { #ifdef CONFIG_STM32_HRTIM_EEV1 struct stm32_hrtim_eev_cfg_s eev1; #endif #ifdef CONFIG_STM32_HRTIM_EEV2 struct stm32_hrtim_eev_cfg_s eev2; #endif #ifdef CONFIG_STM32_HRTIM_EEV3 struct stm32_hrtim_eev_cfg_s eev3; #endif #ifdef CONFIG_STM32_HRTIM_EEV4 struct stm32_hrtim_eev_cfg_s eev4; #endif #ifdef CONFIG_STM32_HRTIM_EEV5 struct stm32_hrtim_eev_cfg_s eev5; #endif #ifdef CONFIG_STM32_HRTIM_EEV6 struct stm32_hrtim_eev_cfg_s eev6; #endif #ifdef CONFIG_STM32_HRTIM_EEV7 struct stm32_hrtim_eev_cfg_s eev7; #endif #ifdef CONFIG_STM32_HRTIM_EEV8 struct stm32_hrtim_eev_cfg_s eev8; #endif #ifdef CONFIG_STM32_HRTIM_EEV9 struct stm32_hrtim_eev_cfg_s eev9; #endif #ifdef CONFIG_STM32_HRTIM_EEV10 struct stm32_hrtim_eev_cfg_s eev10; #endif }; #endif #ifdef HRTIM_HAVE_ADC /* Structure describes HRTIM ADC triggering configuration */ struct stm32_hrtim_adc_s { #ifdef HRTIM_HAVE_ADC_TRG1 uint32_t trg1; #endif #ifdef HRTIM_HAVE_ADC_TRG2 uint32_t trg2; #endif #ifdef HRTIM_HAVE_ADC_TRG3 uint32_t trg3; #endif #ifdef HRTIM_HAVE_ADC_TRG4 uint32_t trg4; #endif }; #endif /* Structure describes HRTIM Burst mode configuratione */ #ifdef CONFIG_STM32_HRTIM_BURST struct stm32_hrtim_burst_s { uint8_t clk:4; /* Burst mode clock source */ uint8_t presc:4; /* Prescaler for f_HRTIM clock */ uint32_t trg; /* Burst mode triggers */ }; #endif /* This structure describes the configuration of HRTIM device */ struct stm32_hrtim_s { uint32_t base; /* Base address of HRTIM block */ struct stm32_hrtim_tim_s *master; /* Master Timer */ #ifdef CONFIG_STM32_HRTIM_TIMA struct stm32_hrtim_tim_s *tima; /* HRTIM Timer A */ #endif #ifdef CONFIG_STM32_HRTIM_TIMB struct stm32_hrtim_tim_s *timb; /* HRTIM Timer B */ #endif #ifdef CONFIG_STM32_HRTIM_TIMC struct stm32_hrtim_tim_s *timc; /* HRTIM Timer C */ #endif #ifdef CONFIG_STM32_HRTIM_TIMD struct stm32_hrtim_tim_s *timd; /* HRTIM Timer D */ #endif #ifdef CONFIG_STM32_HRTIM_TIME struct stm32_hrtim_tim_s *time; /* HRTIM Timer E */ #endif #ifdef CONFIG_STM32_HRTIM_FAULTS struct stm32_hrtim_faults_s *flt; /* Faults configuration */ #endif #ifdef CONFIG_STM32_HRTIM_EVENTS struct stm32_hrtim_eev_s *eev; /* External Events configuration */ #endif #ifdef HRTIM_HAVE_ADC struct stm32_hrtim_adc_s *adc; /* ADC triggering configuration */ #endif #ifdef CONFIG_STM32_HRTIM_BURST struct stm32_hrtim_burst_s *burst; /* Burst mode configuration */ #endif #ifdef CONFIG_STM32_HRTIM_INTERRUPTS uint32_t irq; /* Common interrupts configuration */ #endif }; /**************************************************************************** * Private Function Prototypes ****************************************************************************/ #ifndef CONFIG_STM32_HRTIM_DISABLE_CHARDRV /* HRTIM Driver Methods */ static int stm32_hrtim_open(FAR struct file *filep); static int stm32_hrtim_close(FAR struct file *filep); static int stm32_hrtim_ioctl(FAR struct file *filep, int cmd, unsigned long arg); #endif /* HRTIM Register access */ static uint32_t hrtim_cmn_getreg(FAR struct stm32_hrtim_s *priv, uint32_t offset); static void hrtim_cmn_putreg(FAR struct stm32_hrtim_s *priv, uint32_t offset, uint32_t value); #ifdef CONFIG_STM32_HRTIM_BURST static void hrtim_cmn_modifyreg(FAR struct stm32_hrtim_s *priv, uint32_t offset, uint32_t clrbits, uint32_t setbits); #endif static void hrtim_tim_putreg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint32_t offset, uint32_t value); static void hrtim_tim_modifyreg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint32_t offset, uint32_t clrbits, uint32_t setbits); #ifdef CONFIG_DEBUG_TIMER_INFO static void hrtim_dumpregs(FAR struct stm32_hrtim_s *priv, uint8_t timer, FAR const char *msg); #else # define hrtim_dumpregs(priv, timer, msg) #endif /* HRTIM helper */ static uint32_t hrtim_tim_getreg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint32_t offset); static FAR struct stm32_hrtim_tim_s * hrtim_tim_get(FAR struct stm32_hrtim_s *priv, uint8_t timer); #if defined(CONFIG_STM32_HRTIM_PWM) || defined(CONFIG_STM32_HRTIM_FAULTS) static FAR struct stm32_hrtim_slave_priv_s * hrtim_slave_get(FAR struct stm32_hrtim_s *priv, uint8_t timer); #endif static uint32_t hrtim_base_get(FAR struct stm32_hrtim_s *priv, uint8_t timer); /* Configuration */ static int hrtim_dll_cal(FAR struct stm32_hrtim_s *priv); static int hrtim_tim_clock_config(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint8_t pre); static int hrtim_tim_clocks_config(FAR struct stm32_hrtim_s *priv); #if defined(CONFIG_STM32_HRTIM_PWM) || defined(CONFIG_STM32_HRTIM_SYNC) static int hrtim_gpios_config(FAR struct stm32_hrtim_s *priv); #endif #if defined(CONFIG_STM32_HRTIM_CAPTURE) static int hrtim_capture_config(FAR struct stm32_hrtim_s *priv); static uint16_t hrtim_capture_get(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t index); static int hrtim_soft_capture(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t index); #endif #if defined(CONFIG_STM32_HRTIM_SYNC) static int hrtim_synch_config(FAR struct stm32_hrtim_s *priv); #endif #if defined(CONFIG_STM32_HRTIM_PWM) static int hrtim_outputs_config(FAR struct stm32_hrtim_s *priv); static int hrtim_outputs_enable(FAR struct hrtim_dev_s *dev, uint16_t outputs, bool state); static int hrtim_output_set_set(FAR struct hrtim_dev_s *dev, uint16_t output, uint32_t set); static int hrtim_output_rst_set(FAR struct hrtim_dev_s *dev, uint16_t output, uint32_t rst); #endif #ifdef HRTIM_HAVE_ADC static int hrtim_adc_config(FAR struct stm32_hrtim_s *priv); #endif #ifdef CONFIG_STM32_HRTIM_DAC static int hrtim_dac_config(FAR struct stm32_hrtim_s *priv); #endif #ifdef CONFIG_STM32_HRTIM_DMA static int hrtim_dma_cfg(FAR struct stm32_hrtim_s *priv); static int hrtim_tim_dma_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint16_t dma); #endif #ifdef CONFIG_STM32_HRTIM_DEADTIME static int hrtim_deadtime_update(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t dt, uint16_t value); static uint16_t hrtim_deadtime_get(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t dt); static int hrtim_tim_deadtime_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer); static int hrtim_deadtime_config(FAR struct stm32_hrtim_s *priv); #endif #ifdef CONFIG_STM32_HRTIM_CHOPPER static int hrtim_chopper_enable(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t chan, bool state); static int hrtim_tim_chopper_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer); static int hrtim_chopper_config(FAR struct stm32_hrtim_s *priv); #endif #ifdef CONFIG_STM32_HRTIM_BURST static int hrtim_burst_enable(FAR struct hrtim_dev_s *dev, bool state); static int hrtim_burst_cmp_update(FAR struct hrtim_dev_s *dev, uint16_t cmp); static int hrtim_burst_per_update(FAR struct hrtim_dev_s *dev, uint16_t per); static uint16_t hrtim_burst_cmp_get(FAR struct hrtim_dev_s *dev); static uint16_t hrtim_burst_per_get(FAR struct hrtim_dev_s *dev); static int hrtim_burst_pre_update(FAR struct hrtim_dev_s *dev, uint8_t pre); static int hrtim_burst_pre_get(FAR struct hrtim_dev_s *dev); static int hrtim_burst_config(FAR struct stm32_hrtim_s *priv); #endif #ifdef CONFIG_STM32_HRTIM_FAULTS static int hrtim_faults_config(FAR struct stm32_hrtim_s *priv); static int hrtim_flt_cfg(FAR struct stm32_hrtim_s *priv, uint8_t index); static int hrtim_tim_faults_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer); #endif #ifdef CONFIG_STM32_HRTIM_EVENTS static int hrtim_events_config(FAR struct stm32_hrtim_s *priv); static int hrtim_eev_cfg(FAR struct stm32_hrtim_s *priv, uint8_t index); #endif #ifdef CONFIG_STM32_HRTIM_INTERRUPTS static int hrtim_irq_config(FAR struct stm32_hrtim_s *priv); static uint16_t hrtim_irq_get(FAR struct hrtim_dev_s *dev, uint8_t timer); static int hrtim_irq_ack(FAR struct hrtim_dev_s *dev, uint8_t timer, int source); #endif static int hrtim_cmp_update(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t index, uint16_t cmp); static int hrtim_per_update(FAR struct hrtim_dev_s *dev, uint8_t timer, uint16_t per); static int hrtim_rep_update(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t rep); static uint16_t hrtim_per_get(FAR struct hrtim_dev_s *dev, uint8_t timer); static uint16_t hrtim_cmp_get(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t index); static uint64_t hrtim_fclk_get(FAR struct hrtim_dev_s *dev, uint8_t timer); static int hrtim_soft_update(FAR struct hrtim_dev_s *dev, uint8_t timer); static int hrtim_soft_reset(FAR struct hrtim_dev_s *dev, uint8_t timer); static int hrtim_tim_freq_set(FAR struct hrtim_dev_s *dev, uint8_t timer, uint64_t freq); static int hrtim_tim_enable(FAR struct hrtim_dev_s *dev, uint8_t timers, bool state); static int hrtim_tim_reset_set(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint64_t reset); static int hrtim_reset_config(FAR struct stm32_hrtim_s *priv); static int hrtim_tim_update_set(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint16_t update); static int hrtim_update_config(FAR struct stm32_hrtim_s *priv); static void hrtim_tim_mode_set(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint8_t mode); static void hrtim_mode_config(FAR struct stm32_hrtim_s *priv); /* Initialization */ static int stm32_hrtimconfig(FAR struct stm32_hrtim_s *priv); /**************************************************************************** * Private Data ****************************************************************************/ #ifndef CONFIG_STM32_HRTIM_DISABLE_CHARDRV static const struct file_operations hrtim_fops = { stm32_hrtim_open, /* open */ stm32_hrtim_close, /* close */ NULL, /* read */ NULL, /* write */ NULL, /* seek */ stm32_hrtim_ioctl, /* ioctl */ NULL /* poll */ #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS , NULL /* unlink */ #endif }; #endif /* CONFIG_STM32_HRTIM_DISABLE_CHARDRV */ /* Master Timer data */ static struct stm32_hrtim_tim_s g_master = { .tim = { .base = STM32_HRTIM1_MASTER_BASE, /* If MASTER is disabled, we need only MASTER base */ #ifdef CONFIG_STM32_HRTIM_MASTER .fclk = HRTIM_CLOCK / (1 << HRTIM_MASTER_PRESCALER), .prescaler = HRTIM_MASTER_PRESCALER, .mode = HRTIM_MASTER_MODE, # ifdef CONFIG_STM32_HRTIM_MASTER_DAC .dac = HRTIM_MASTER_DAC, # endif # ifdef CONFIG_STM32_HRTIM_MASTER_IRQ .irq = HRTIM_MASTER_IRQ # endif # ifdef CONFIG_STM32_HRTIM_MASTER_DMA .dma = HRTIM_MASTER_DMA # endif #endif }, .priv = NULL, }; #ifdef CONFIG_STM32_HRTIM_TIMA /* Timer A private data */ static struct stm32_hrtim_slave_priv_s g_tima_priv = { .update = HRTIM_TIMA_UPDATE, .reset = HRTIM_TIMA_RESET, #ifdef CONFIG_STM32_HRTIM_TIMA_PWM .pwm = { #ifdef CONFIG_STM32_HRTIM_TIMA_PSHPLL .pushpull = 1, #endif #ifdef CONFIG_STM32_HRTIM_TIMA_PWM_CH1 .ch1 = { .set = HRTIM_TIMA_CH1_SET, .rst = HRTIM_TIMA_CH1_RST, .pol = HRTIM_TIMA_CH1_POL }, #endif #ifdef CONFIG_STM32_HRTIM_TIMA_PWM_CH2 .ch2 = { .set = HRTIM_TIMA_CH2_SET, .rst = HRTIM_TIMA_CH2_RST, .pol = HRTIM_TIMA_CH2_POL }, #endif #ifdef CONFIG_STM32_HRTIM_TIMA_BURST .burst = { # ifdef CONFIG_STM32_HRTIM_TIMA_BURST_CH1 .ch1_en = 1, .ch1_state = HRTIM_TIMA_CH1_IDLE_STATE, # else .ch1_en = 0, # endif # ifdef CONFIG_STM32_HRTIM_TIMA_BURST_CH2 .ch2_en = 1, .ch2_state = HRTIM_TIMA_CH2_IDLE_STATE # else .ch2_en = 0, # endif }, #endif #ifdef CONFIG_STM32_HRTIM_TIMA_CHOP .chp = { .start_pulse = HRTIM_TIMA_CHOP_START, .duty = HRTIM_TIMA_CHOP_DUTY, .freq = HRTIM_TIMA_CHOP_FREQ }, #endif #ifdef CONFIG_STM32_HRTIM_TIMA_DT .dt = { .en = 1, .fsign_lock = HRTIM_TIMA_DT_FSLOCK, .rsign_lock = HRTIM_TIMA_DT_RSLOCK, .falling_lock = HRTIM_TIMA_DT_FVLOCK, .rising_lock = HRTIM_TIMA_DT_RVLOCK, .fsign = HRTIM_TIMA_DT_FSIGN, .rsign = HRTIM_TIMA_DT_RSIGN, .prescaler = HRTIM_TIMA_DT_PRESCALER } #endif }, #endif #ifdef CONFIG_STM32_HRTIM_TIMA_CAP .cap = { .cap1 = HRTIM_TIMA_CAPTURE1, .cap2 = HRTIM_TIMA_CAPTURE2, } #endif }; /* Timer A data */ static struct stm32_hrtim_tim_s g_tima = { .tim = { .base = STM32_HRTIM1_TIMERA_BASE, .fclk = HRTIM_CLOCK / (1 << HRTIM_TIMA_PRESCALER), .prescaler = HRTIM_TIMA_PRESCALER, .mode = HRTIM_TIMA_MODE, #ifdef CONFIG_STM32_HRTIM_TIMA_DAC .dac = HRTIM_TIMA_DAC, #endif #ifdef CONFIG_STM32_HRTIM_TIMA_IRQ .irq = HRTIM_TIMA_IRQ, #endif #ifdef CONFIG_STM32_HRTIM_TIMA_DMA .dma = HRTIM_TIMA_DMA #endif }, .priv = &g_tima_priv }; #endif #ifdef CONFIG_STM32_HRTIM_TIMB /* Timer B private data */ static struct stm32_hrtim_slave_priv_s g_timb_priv = { .update = HRTIM_TIMB_UPDATE, .reset = HRTIM_TIMB_RESET, #ifdef CONFIG_STM32_HRTIM_TIMB_PWM .pwm = { #ifdef CONFIG_STM32_HRTIM_TIMB_PSHPLL .pushpull = 1, #endif #ifdef CONFIG_STM32_HRTIM_TIMB_PWM_CH1 .ch1 = { .set = HRTIM_TIMB_CH1_SET, .rst = HRTIM_TIMB_CH1_RST, .pol = HRTIM_TIMB_CH1_POL }, #endif #ifdef CONFIG_STM32_HRTIM_TIMB_PWM_CH2 .ch2 = { .set = HRTIM_TIMB_CH2_SET, .rst = HRTIM_TIMB_CH2_RST, .pol = HRTIM_TIMB_CH2_POL }, #endif #ifdef CONFIG_STM32_HRTIM_TIMB_BURST .burst = { # ifdef CONFIG_STM32_HRTIM_TIMB_BURST_CH1 .ch1_en = 1, .ch1_state = HRTIM_TIMB_CH1_IDLE_STATE, # else .ch1_en = 0, # endif # ifdef CONFIG_STM32_HRTIM_TIMB_BURST_CH2 .ch2_en = 1, .ch2_state = HRTIM_TIMB_CH2_IDLE_STATE # else .ch2_en = 0, # endif }, #endif #ifdef CONFIG_STM32_HRTIM_TIMB_CHOP .chp = { .start_pulse = HRTIM_TIMB_CHOP_START, .duty = HRTIM_TIMB_CHOP_DUTY, .freq = HRTIM_TIMB_CHOP_FREQ }, #endif #ifdef CONFIG_STM32_HRTIM_TIMB_DT .dt = { .en = 1, .fsign_lock = HRTIM_TIMB_DT_FSLOCK, .rsign_lock = HRTIM_TIMB_DT_RSLOCK, .falling_lock = HRTIM_TIMB_DT_FVLOCK, .rising_lock = HRTIM_TIMB_DT_RVLOCK, .fsign = HRTIM_TIMB_DT_FSIGN, .rsign = HRTIM_TIMB_DT_RSIGN, .prescaler = HRTIM_TIMB_DT_PRESCALER } #endif }, #endif #ifdef CONFIG_STM32_HRTIM_TIMB_CAP .cap = { .cap1 = HRTIM_TIMB_CAPTURE1, .cap2 = HRTIM_TIMB_CAPTURE2, } #endif }; /* Timer B data */ static struct stm32_hrtim_tim_s g_timb = { .tim = { .base = STM32_HRTIM1_TIMERB_BASE, .fclk = HRTIM_CLOCK / (1 << HRTIM_TIMB_PRESCALER), .prescaler = HRTIM_TIMB_PRESCALER, .mode = HRTIM_TIMB_MODE, #ifdef CONFIG_STM32_HRTIM_TIMB_DAC .dac = HRTIM_TIMB_DAC, #endif #ifdef CONFIG_STM32_HRTIM_TIMB_IRQ .irq = HRTIM_TIMB_IRQ, #endif #ifdef CONFIG_STM32_HRTIM_TIMB_DMA .dma = HRTIM_TIMB_DMA #endif }, .priv = &g_timb_priv }; #endif #ifdef CONFIG_STM32_HRTIM_TIMC /* Timer C private data */ static struct stm32_hrtim_slave_priv_s g_timc_priv = { .update = HRTIM_TIMC_UPDATE, .reset = HRTIM_TIMC_RESET, #ifdef CONFIG_STM32_HRTIM_TIMC_PWM .pwm = { #ifdef CONFIG_STM32_HRTIM_TIMC_PSHPLL .pushpull = 1, #endif #ifdef CONFIG_STM32_HRTIM_TIMC_PWM_CH1 .ch1 = { .set = HRTIM_TIMC_CH1_SET, .rst = HRTIM_TIMC_CH1_RST, .pol = HRTIM_TIMC_CH1_POL }, #endif #ifdef CONFIG_STM32_HRTIM_TIMC_PWM_CH2 .ch2 = { .set = HRTIM_TIMC_CH2_SET, .rst = HRTIM_TIMC_CH2_RST, .pol = HRTIM_TIMC_CH2_POL }, #endif #ifdef CONFIG_STM32_HRTIM_TIMC_BURST .burst = { # ifdef CONFIG_STM32_HRTIM_TIMC_BURST_CH1 .ch1_en = 1, .ch1_state = HRTIM_TIMC_CH1_IDLE_STATE, # else .ch1_en = 0, # endif # ifdef CONFIG_STM32_HRTIM_TIMC_BURST_CH2 .ch2_en = 1, .ch2_state = HRTIM_TIMC_CH2_IDLE_STATE # else .ch2_en = 0, # endif }, #endif #ifdef CONFIG_STM32_HRTIM_TIMC_CHOP .chp = { .start_pulse = HRTIM_TIMC_CHOP_START, .duty = HRTIM_TIMC_CHOP_DUTY, .freq = HRTIM_TIMC_CHOP_FREQ }, #endif #ifdef CONFIG_STM32_HRTIM_TIMC_DT .dt = { .en = 1, .fsign_lock = HRTIM_TIMC_DT_FSLOCK, .rsign_lock = HRTIM_TIMC_DT_RSLOCK, .falling_lock = HRTIM_TIMC_DT_FVLOCK, .rising_lock = HRTIM_TIMC_DT_RVLOCK, .fsign = HRTIM_TIMC_DT_FSIGN, .rsign = HRTIM_TIMC_DT_RSIGN, .prescaler = HRTIM_TIMC_DT_PRESCALER } #endif }, #endif #ifdef CONFIG_STM32_HRTIM_TIMC_CAP .cap = { .cap1 = HRTIM_TIMC_CAPTURE1, .cap2 = HRTIM_TIMC_CAPTURE2, } #endif }; /* Timer C data */ static struct stm32_hrtim_tim_s g_timc = { .tim = { .base = STM32_HRTIM1_TIMERC_BASE, .fclk = HRTIM_CLOCK / (1 << HRTIM_TIMC_PRESCALER), .prescaler = HRTIM_TIMC_PRESCALER, .mode = HRTIM_TIMC_MODE, #ifdef CONFIG_STM32_HRTIM_TIMC_DAC .dac = HRTIM_TIMC_DAC, #endif #ifdef CONFIG_STM32_HRTIM_TIMC_IRQ .irq = HRTIM_TIMC_IRQ, #endif #ifdef CONFIG_STM32_HRTIM_TIMC_DMA .dma = HRTIM_TIMC_DMA #endif }, .priv = &g_timc_priv }; #endif #ifdef CONFIG_STM32_HRTIM_TIMD /* Timer D private data */ static struct stm32_hrtim_slave_priv_s g_timd_priv = { .update = HRTIM_TIMD_UPDATE, .reset = HRTIM_TIMD_RESET, #ifdef CONFIG_STM32_HRTIM_TIMD_PWM .pwm = { #ifdef CONFIG_STM32_HRTIM_TIMD_PSHPLL .pushpull = 1, #endif #ifdef CONFIG_STM32_HRTIM_TIMD_PWM_CH1 .ch1 = { .set = HRTIM_TIMD_CH1_SET, .rst = HRTIM_TIMD_CH1_RST, .pol = HRTIM_TIMD_CH1_POL }, #endif #ifdef CONFIG_STM32_HRTIM_TIMD_PWM_CH2 .ch2 = { .set = HRTIM_TIMD_CH2_SET, .rst = HRTIM_TIMD_CH2_RST, .pol = HRTIM_TIMD_CH2_POL }, #endif #ifdef CONFIG_STM32_HRTIM_TIMD_BURST .burst = { # ifdef CONFIG_STM32_HRTIM_TIMD_BURST_CH1 .ch1_en = 1, .ch1_state = HRTIM_TIMD_CH1_IDLE_STATE, # else .ch1_en = 0, # endif # ifdef CONFIG_STM32_HRTIM_TIMD_BURST_CH2 .ch2_en = 1, .ch2_state = HRTIM_TIMD_CH2_IDLE_STATE # else .ch2_en = 0, # endif }, #endif #ifdef CONFIG_STM32_HRTIM_TIMD_CHOP .chp = { .start_pulse = HRTIM_TIMD_CHOP_START, .duty = HRTIM_TIMD_CHOP_DUTY, .freq = HRTIM_TIMD_CHOP_FREQ }, #endif #ifdef CONFIG_STM32_HRTIM_TIMD_DT .dt = { .en = 1, .fsign_lock = HRTIM_TIMD_DT_FSLOCK, .rsign_lock = HRTIM_TIMD_DT_RSLOCK, .falling_lock = HRTIM_TIMD_DT_FVLOCK, .rising_lock = HRTIM_TIMD_DT_RVLOCK, .fsign = HRTIM_TIMD_DT_FSIGN, .rsign = HRTIM_TIMD_DT_RSIGN, .prescaler = HRTIM_TIMD_DT_PRESCALER } #endif }, #endif #ifdef CONFIG_STM32_HRTIM_TIMD_CAP .cap = { .cap1 = HRTIM_TIMD_CAPTURE1, .cap2 = HRTIM_TIMD_CAPTURE2, } #endif }; /* Timer D data */ static struct stm32_hrtim_tim_s g_timd = { .tim = { .base = STM32_HRTIM1_TIMERD_BASE, .fclk = HRTIM_CLOCK / (1 << HRTIM_TIMD_PRESCALER), .prescaler = HRTIM_TIMD_PRESCALER, .mode = HRTIM_TIMD_MODE, #ifdef CONFIG_STM32_HRTIM_TIMD_DAC .dac = HRTIM_TIMD_DAC, #endif #ifdef CONFIG_STM32_HRTIM_TIMD_IRQ .irq = HRTIM_TIMD_IRQ, #endif #ifdef CONFIG_STM32_HRTIM_TIMD_DMA .dma = HRTIM_TIMD_DMA #endif }, .priv = &g_timd_priv }; #endif #ifdef CONFIG_STM32_HRTIM_TIME /* Timer E private data */ static struct stm32_hrtim_slave_priv_s g_time_priv = { .update = HRTIM_TIME_UPDATE, .reset = HRTIM_TIME_RESET, #ifdef CONFIG_STM32_HRTIM_TIME_PWM .pwm = { #ifdef CONFIG_STM32_HRTIM_TIME_PSHPLL .pushpull = 1, #endif #ifdef CONFIG_STM32_HRTIM_TIME_PWM_CH1 .ch1 = { .set = HRTIM_TIME_CH1_SET, .rst = HRTIM_TIME_CH1_RST, .pol = HRTIM_TIME_CH1_POL }, #endif #ifdef CONFIG_STM32_HRTIM_TIME_PWM_CH2 .ch2 = { .set = HRTIM_TIME_CH2_SET, .rst = HRTIM_TIME_CH2_RST, .pol = HRTIM_TIME_CH1_POL }, #endif #ifdef CONFIG_STM32_HRTIM_TIME_BURST .burst = { # ifdef CONFIG_STM32_HRTIM_TIME_BURST_CH1 .ch1_en = 1, .ch1_state = HRTIM_TIME_CH1_IDLE_STATE, # else .ch1_en = 0, # endif # ifdef CONFIG_STM32_HRTIM_TIME_BURST_CH2 .ch2_en = 1, .ch2_state = HRTIM_TIME_CH2_IDLE_STATE # else .ch2_en = 0, # endif }, #endif #ifdef CONFIG_STM32_HRTIM_TIME_CHOP .chp = { .start_pulse = HRTIM_TIME_CHOP_START, .duty = HRTIM_TIME_CHOP_DUTY, .freq = HRTIM_TIME_CHOP_FREQ }, #endif #ifdef CONFIG_STM32_HRTIM_TIME_DT .dt = { .en = 1, .fsign_lock = HRTIM_TIME_DT_FSLOCK, .rsign_lock = HRTIM_TIME_DT_RSLOCK, .falling_lock = HRTIM_TIME_DT_FVLOCK, .rising_lock = HRTIM_TIME_DT_RVLOCK, .fsign = HRTIM_TIME_DT_FSIGN, .rsign = HRTIM_TIME_DT_RSIGN, .prescaler = HRTIM_TIME_DT_PRESCALER } #endif }, #endif #ifdef CONFIG_STM32_HRTIM_TIME_CAP .cap = { .cap1 = HRTIM_TIME_CAPTURE1, .cap2 = HRTIM_TIME_CAPTURE2, } #endif }; /* Timer E data */ static struct stm32_hrtim_tim_s g_time = { .tim = { .base = STM32_HRTIM1_TIMERE_BASE, .fclk = HRTIM_CLOCK / (1 << HRTIM_TIME_PRESCALER), .prescaler = HRTIM_TIME_PRESCALER, .mode = HRTIM_TIME_MODE, #ifdef CONFIG_STM32_HRTIM_TIME_DAC .dac = HRTIM_TIME_DAC, #endif #ifdef CONFIG_STM32_HRTIM_TIME_IRQ .irq = HRTIM_TIME_IRQ, #endif #ifdef CONFIG_STM32_HRTIM_TIME_DMA .dma = HRTIM_TIME_DMA #endif }, .priv = &g_time_priv }; #endif /* Faults data */ #ifdef CONFIG_STM32_HRTIM_FAULTS struct stm32_hrtim_faults_s g_flt = { #ifdef CONFIG_STM32_HRTIM_FAULT1 .flt1 = { .pol = HRTIM_FAULT1_POL, .src = HRTIM_FAULT1_SRC, .filter = HRTIM_FAULT1_FILTER, .lock = HRTIM_FAULT1_LOCK, }, #endif #ifdef CONFIG_STM32_HRTIM_FAULT2 .flt2 = { .pol = HRTIM_FAULT2_POL, .src = HRTIM_FAULT2_SRC, .filter = HRTIM_FAULT2_FILTER, .lock = HRTIM_FAULT2_LOCK, }, #endif #ifdef CONFIG_STM32_HRTIM_FAULT3 .flt3 = { .pol = HRTIM_FAULT3_POL, .src = HRTIM_FAULT3_SRC, .filter = HRTIM_FAULT3_FILTER, .lock = HRTIM_FAULT3_LOCK, }, #endif #ifdef CONFIG_STM32_HRTIM_FAULT4 .flt2 = { .pol = HRTIM_FAULT4_POL, .src = HRTIM_FAULT4_SRC, .filter = HRTIM_FAULT4_FILTER, .lock = HRTIM_FAULT4_LOCK, }, #endif #ifdef CONFIG_STM32_HRTIM_FAULT5 .flt2 = { .pol = HRTIM_FAULT5_POL, .src = HRTIM_FAULT5_SRC, .filter = HRTIM_FAULT5_FILTER, .lock = HRTIM_FAULT5_LOCK, }, #endif }; #endif /* External Events data */ #ifdef CONFIG_STM32_HRTIM_EVENTS struct stm32_hrtim_eev_s g_eev = { #ifdef CONFIG_STM32_HRTIM_EEV1 .eev1 = { .filter = HRTIM_EEV1_FILTER, .src = HRTIM_EEV1_SRC, .pol = HRTIM_EEV1_POL, .sen = HRTIM_EEV1_SEN, .mode = HRTIM_EEV1_MODE, } #endif #ifdef CONFIG_STM32_HRTIM_EEV2 .eev2 = { .filter = HRTIM_EEV2_FILTER, .src = HRTIM_EEV2_SRC, .pol = HRTIM_EEV2_POL, .sen = HRTIM_EEV2_SEN, .mode = HRTIM_EEV2_MODE, } #endif #ifdef CONFIG_STM32_HRTIM_EEV3 .eev3 = { .filter = HRTIM_EEV3_FILTER, .src = HRTIM_EEV3_SRC, .pol = HRTIM_EEV3_POL, .sen = HRTIM_EEV3_SEN, .mode = HRTIM_EEV3_MODE, } #endif #ifdef CONFIG_STM32_HRTIM_EEV4 .eev4 = { .filter = HRTIM_EEV4_FILTER, .src = HRTIM_EEV4_SRC, .pol = HRTIM_EEV4_POL, .sen = HRTIM_EEV4_SEN, .mode = HRTIM_EEV4_MODE, } #endif #ifdef CONFIG_STM32_HRTIM_EEV5 .eev5 = { .filter = HRTIM_EEV5_FILTER, .src = HRTIM_EEV5_SRC, .pol = HRTIM_EEV5_POL, .sen = HRTIM_EEV5_SEN, .mode = HRTIM_EEV5_MODE, } #endif #ifdef CONFIG_STM32_HRTIM_EEV6 .eev6 = { .filter = HRTIM_EEV6_FILTER, .src = HRTIM_EEV6_SRC, .pol = HRTIM_EEV6_POL, .sen = HRTIM_EEV6_SEN, .mode = HRTIM_EEV6_MODE, } #endif #ifdef CONFIG_STM32_HRTIM_EEV7 .eev7 = { .filter = HRTIM_EEV7_FILTER, .src = HRTIM_EEV7_SRC, .pol = HRTIM_EEV7_POL, .sen = HRTIM_EEV7_SEN, .mode = HRTIM_EEV7_MODE, } #endif #ifdef CONFIG_STM32_HRTIM_EEV8 .eev8 = { .filter = HRTIM_EEV8_FILTER, .src = HRTIM_EEV8_SRC, .pol = HRTIM_EEV8_POL, .sen = HRTIM_EEV8_SEN, .mode = HRTIM_EEV8_MODE, } #endif #ifdef CONFIG_STM32_HRTIM_EEV9 .eev9 = { .filter = HRTIM_EEV9_FILTER, .src = HRTIM_EEV9_SRC, .pol = HRTIM_EEV9_POL, .sen = HRTIM_EEV9_SEN, .mode = HRTIM_EEV9_MODE, } #endif #ifdef CONFIG_STM32_HRTIM_EEV10 .eev10 = { .filter = HRTIM_EEV10_FILTER, .src = HRTIM_EEV10_SRC, .pol = HRTIM_EEV10_POL, .sen = HRTIM_EEV10_SEN, .mode = HRTIM_EEV10_MODE, } #endif }; #endif /* ADC triggering data */ #ifdef HRTIM_HAVE_ADC struct stm32_hrtim_adc_s g_adc = { #ifdef HRTIM_HAVE_ADC_TRG1 .trg1 = HRTIM_ADC_TRG1, #endif #ifdef HRTIM_HAVE_ADC_TRG2 .trg2 = HRTIM_ADC_TRG2, #endif #ifdef HRTIM_HAVE_ADC_TRG3 .trg3 = HRTIM_ADC_TRG3, #endif #ifdef HRTIM_HAVE_ADC_TRG4 .trg4 = HRTIM_ADC_TRG4 #endif }; #endif /* Burst mode data */ #ifdef CONFIG_STM32_HRTIM_BURST struct stm32_hrtim_burst_s g_burst = { .clk = HRTIM_BURST_CLOCK, .presc = HRTIM_BURST_PRESCALER, .trg = HRTIM_BURST_TRIGGERS }; #endif /* HRTIM1 private data */ static struct stm32_hrtim_s g_hrtim1priv = { .master = &g_master, .base = STM32_HRTIM1_BASE, #ifdef CONFIG_STM32_HRTIM_TIMA .tima = &g_tima, #endif #ifdef CONFIG_STM32_HRTIM_TIMB .timb = &g_timb, #endif #ifdef CONFIG_STM32_HRTIM_TIMC .timc = &g_timc, #endif #ifdef CONFIG_STM32_HRTIM_TIMD .timd = &g_timd, #endif #ifdef CONFIG_STM32_HRTIM_TIME .time = &g_time, #endif #ifdef CONFIG_STM32_HRTIM_FAULTS .flt = &g_flt, #endif #ifdef CONFIG_STM32_HRTIM_EVENTS .eev = &g_eev, #endif #ifdef HRTIM_HAVE_ADC .adc = &g_adc, #endif #ifdef CONFIG_STM32_HRTIM_BURST .burst = &g_burst, #endif #ifdef CONFIG_STM32_HRTIM_COMMON_IRQ .irq = HRTIM_IRQ_COMMON, #endif }; /* HRTIM interface */ static const struct stm32_hrtim_ops_s g_hrtim1ops = { .cmp_update = hrtim_cmp_update, .per_update = hrtim_per_update, .rep_update = hrtim_rep_update, .per_get = hrtim_per_get, .cmp_get = hrtim_cmp_get, .fclk_get = hrtim_fclk_get, .soft_update = hrtim_soft_update, .soft_reset = hrtim_soft_reset, .freq_set = hrtim_tim_freq_set, .tim_enable = hrtim_tim_enable, #ifdef CONFIG_STM32_HRTIM_INTERRUPTS .irq_ack = hrtim_irq_ack, .irq_get = hrtim_irq_get, #endif #ifdef CONFIG_STM32_HRTIM_PWM .outputs_enable = hrtim_outputs_enable, .output_rst_set = hrtim_output_rst_set, .output_set_set = hrtim_output_set_set, #endif #ifdef CONFIG_STM32_HRTIM_BURST .burst_enable = hrtim_burst_enable, .burst_cmp_set = hrtim_burst_cmp_update, .burst_per_set = hrtim_burst_per_update, .burst_pre_set = hrtim_burst_pre_update, .burst_cmp_get = hrtim_burst_cmp_get, .burst_per_get = hrtim_burst_per_get, .burst_pre_get = hrtim_burst_pre_get, #endif #ifdef CONFIG_STM32_HRTIM_CHOPPER .chopper_enable = hrtim_chopper_enable, #endif #ifdef CONFIG_STM32_HRTIM_DEADTIME .deadtime_update = hrtim_deadtime_update, .deadtime_get = hrtim_deadtime_get, #endif #ifdef CONFIG_STM32_HRTIM_CAPTURE .capture_get = hrtim_capture_get, .soft_capture = hrtim_soft_capture, #endif }; /* HRTIM device structure */ struct hrtim_dev_s g_hrtim1dev = { .hd_ops = &g_hrtim1ops, .hd_priv = &g_hrtim1priv, .initialized = false, }; /**************************************************************************** * Private Functions ****************************************************************************/ #ifndef CONFIG_STM32_HRTIM_DISABLE_CHARDRV /**************************************************************************** * Name: stm32_hrtim_open * * Description: * This function is called whenever the HRTIM device is opened. * ****************************************************************************/ static int stm32_hrtim_open(FAR struct file *filep) { #warning "stm32_hrtim_open: missing logic" return OK; } /**************************************************************************** * Name: stm32_hrtim_close * * Description: * This function is called when the HRTIM device is closed. * ****************************************************************************/ static int stm32_hrtim_close(FAR struct file *filep) { #warning "smt32_hrtim_close: missing logic" return OK; } /**************************************************************************** * Name: stm32_hrtim_ioctl * * Description: * The standard ioctl method. This is where ALL of the HRTIM work is done. * ****************************************************************************/ static int stm32_hrtim_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR struct inode *inode = filep->f_inode; FAR struct hrtim_dev_s *dev; FAR struct stm32_hrtim_s *hrtim; int ret; tmrinfo("cmd: %d arg: %ld\n", cmd, arg); dev = inode->i_private; DEBUGASSERT(dev != NULL); hrtim = dev->hd_priv; UNUSED(hrtim); #warning "smt32_hrtim_ioctl: missing logic" /* Handle HRTIM ioctl commands */ switch (cmd) { default: { ret = -ENOTTY; break; } } return ret; } #endif /* CONFIG_STM32_HRTIM_DISABLE_CHARDRV */ /**************************************************************************** * Name: hrtim_cmn_getreg * * Description: * Read the value of an HRTIM register. * * Input Parameters: * priv - A reference to the HRTIM block * offset - The offset to the register to read * * Returned Value: * The current contents of the specified register * ****************************************************************************/ static uint32_t hrtim_cmn_getreg(FAR struct stm32_hrtim_s *priv, uint32_t offset) { return getreg32(priv->base + STM32_HRTIM_CMN_OFFSET + offset); } /**************************************************************************** * Name: hrtim_cmn_putreg * * Description: * Write a value to an HRTIM register. * * Input Parameters: * priv - A reference to the HRTIM block * offset - The offset to the register to write to * value - The value to write to the register * * Returned Value: * None * ****************************************************************************/ static void hrtim_cmn_putreg(FAR struct stm32_hrtim_s *priv, uint32_t offset, uint32_t value) { putreg32(value, priv->base + STM32_HRTIM_CMN_OFFSET + offset); } /**************************************************************************** * Name: hrtim__modifyreg * * Description: * Modify the value of an HRTIM register (not atomic). * * Input Parameters: * priv - A reference to the HRTIM block * offset - The offset to the register to modify * clrbits - The bits to clear * setbits - The bits to set * * Returned Value: * None * ****************************************************************************/ #ifdef CONFIG_STM32_HRTIM_BURST static void hrtim_cmn_modifyreg(FAR struct stm32_hrtim_s *priv, uint32_t offset, uint32_t clrbits, uint32_t setbits) { hrtim_cmn_putreg(priv, offset, (hrtim_cmn_getreg(priv, offset) & ~clrbits) | setbits); } #endif /**************************************************************************** * Name: hrtim_tim_get * * Description: * Get Timer data structure for given HRTIM Timer index * * Input Parameters: * priv - A reference to the HRTIM block * timer - An HRTIM Timer index to get * * Returned Value: * Pointer to timer structure on success, NULL on failure * ****************************************************************************/ static FAR struct stm32_hrtim_tim_s * hrtim_tim_get(FAR struct stm32_hrtim_s *priv, uint8_t timer) { FAR struct stm32_hrtim_tim_s *tim; switch (timer) { case HRTIM_TIMER_MASTER: { tim = priv->master; break; } #ifdef CONFIG_STM32_HRTIM_TIMA case HRTIM_TIMER_TIMA: { tim = priv->tima; break; } #endif #ifdef CONFIG_STM32_HRTIM_TIMB case HRTIM_TIMER_TIMB: { tim = priv->timb; break; } #endif #ifdef CONFIG_STM32_HRTIM_TIMC case HRTIM_TIMER_TIMC: { tim = priv->timc; break; } #endif #ifdef CONFIG_STM32_HRTIM_TIMD case HRTIM_TIMER_TIMD: { tim = priv->timd; break; } #endif #ifdef CONFIG_STM32_HRTIM_TIME case HRTIM_TIMER_TIME: { tim = priv->time; break; } #endif default: { tmrerr("ERROR: No such timer index: %d\n", timer); tim = NULL; } } return tim; } /**************************************************************************** * Name: hrtim_slave_get * * Description: * Get Slave private data structure for given HRTIM Timer index * * Input Parameters: * priv - A reference to the HRTIM block * timer - An HRTIM Slave Timer index to get * * Returned Value: * Pointer to slave structure success, NULL on failure * ****************************************************************************/ #if defined(CONFIG_STM32_HRTIM_PWM) || defined(CONFIG_STM32_HRTIM_FAULTS) static FAR struct stm32_hrtim_slave_priv_s * hrtim_slave_get(FAR struct stm32_hrtim_s *priv, uint8_t timer) { FAR struct stm32_hrtim_tim_s *tim; FAR struct stm32_hrtim_slave_priv_s *slave; /* Sanity checking */ if (timer == HRTIM_TIMER_MASTER || timer == HRTIM_TIMER_COMMON) { slave = NULL; goto errout; } /* Get Timer data structure */ tim = hrtim_tim_get(priv, timer); if (tim == NULL) { slave = NULL; goto errout; } /* Get Slave Timer data */ slave = (struct stm32_hrtim_slave_priv_s *)tim->priv; errout: return slave; } #endif /**************************************************************************** * Name: hrtim_base_get * * Description: * Get base address offset for given HRTIM Timer index * * Input Parameters: * priv - A reference to the HRTIM block * timer - An HRTIM Timer index to get * * Returned Value: * Base address offset for given Timer index * ****************************************************************************/ static uint32_t hrtim_base_get(FAR struct stm32_hrtim_s *priv, uint8_t timer) { FAR struct stm32_hrtim_tim_s *tim; uint32_t base = 0; tim = hrtim_tim_get(priv, timer); if (tim == NULL) { base = 0; goto errout; } base = tim->tim.base; errout: return base; } /**************************************************************************** * Name: hrtim_tim_getreg * * Description: * Read the value of an HRTIM Timer register. * * Input Parameters: * priv - A reference to the HRTIM block * tim - An HRTIM timer index * offset - The offset to the register to read * * Returned Value: * The current contents of the specified register * ****************************************************************************/ static uint32_t hrtim_tim_getreg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint32_t offset) { uint32_t base = 0; base = hrtim_base_get(priv, timer); if (base < 0) { return 0; } return getreg32(base + offset); } /**************************************************************************** * Name: hrtim_tim_putreg * * Description: * Write a value to an HRTIM Timer register. * * Input Parameters: * priv - A reference to the HRTIM block * timer - An HRTIM Timer index * offset - The offset to the register to write to * value - The value to write to the register * * Returned Value: * None * ****************************************************************************/ static void hrtim_tim_putreg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint32_t offset, uint32_t value) { uint32_t base = 0; base = hrtim_base_get(priv, timer); if (base > 0) { putreg32(value, base + offset); } } /**************************************************************************** * Name: hrtim_tim_modifyreg * * Description: * Modify the value of an HRTIM Timer register (not atomic). * * Input Parameters: * priv - A reference to the HRTIM block * timer - An HRTIM Timer index * offset - The offset to the register to modify * clrbits - The bits to clear * setbits - The bits to set * * Returned Value: * None * ****************************************************************************/ static void hrtim_tim_modifyreg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint32_t offset, uint32_t clrbits, uint32_t setbits) { hrtim_tim_putreg(priv, timer, offset, (hrtim_tim_getreg(priv, timer, offset) & ~clrbits) | setbits); } #ifdef CONFIG_DEBUG_TIMER_INFO static void hrtim_dumpregs(FAR struct stm32_hrtim_s *priv, uint8_t timer, FAR const char *msg) { tmrinfo("%s:\n", msg); switch (timer) { case HRTIM_TIMER_MASTER: { tmrinfo("\tCR:\t0x%08x\tISR:\t0x%08x\tICR:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_ISR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_ICR_OFFSET)); tmrinfo("\tDIER:\t0x%08x\tCNTR:\t0x%08x\tPER:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_DIER_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CNTR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_PER_OFFSET)); tmrinfo("\tREP:\t0x%08x\tCMP1:\t0x%08x\tCMP2:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_REPR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CMP1R_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CMP2R_OFFSET)); tmrinfo("\tCMP3:\t0x%08x\tCMP4:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CMP3R_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CMP4R_OFFSET)); break; } #ifdef CONFIG_STM32_HRTIM_TIMA case HRTIM_TIMER_TIMA: #endif #ifdef CONFIG_STM32_HRTIM_TIMB case HRTIM_TIMER_TIMB: #endif #ifdef CONFIG_STM32_HRTIM_TIMC case HRTIM_TIMER_TIMC: #endif #ifdef CONFIG_STM32_HRTIM_TIMD case HRTIM_TIMER_TIMD: #endif #ifdef CONFIG_STM32_HRTIM_TIME case HRTIM_TIMER_TIME: #endif { tmrinfo("\tCR:\t0x%08x\tISR:\t0x%08x\tICR:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_ISR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_ICR_OFFSET)); tmrinfo("\tDIER:\t0x%08x\tCNTR:\t0x%08x\tPER:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_DIER_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CNTR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_PER_OFFSET)); tmrinfo("\tREP:\t0x%08x\tCMP1:\t0x%08x\tCMP1C:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_REPR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CMP1R_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CMP1CR_OFFSET)); tmrinfo("\tCMP2:\t0x%08x\tCMP3:\t0x%08x\tCMP4:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CMP2R_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CMP3R_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CMP4R_OFFSET)); tmrinfo("\tCPT1:\t0x%08x\tCPT2:\t0x%08x\tDTR:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CPT1R_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CPT2R_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_DTR_OFFSET)); tmrinfo("\tSET1:\t0x%08x\tRST1:\t0x%08x\tSET2:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_SET1R_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_RST1R_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_SET2R_OFFSET)); tmrinfo("\tRST2:\t0x%08x\tEEF1:\t0x%08x\tEEF2:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_RST2R_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_EEFR1_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_EEFR2_OFFSET)); tmrinfo("\tRSTR:\t0x%08x\tCHPR:\t0x%08x\tCPT1C:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_RSTR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CHPR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CPT1CR_OFFSET)); tmrinfo("\tCPT2C:\t0x%08x\tOUT:\t0x%08x\tFLT:\t0x%08x\n", hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CPT2CR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_OUTR_OFFSET), hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_FLTR_OFFSET)); break; } case HRTIM_TIMER_COMMON: { tmrinfo("\tCR1:\t0x%08x\tCR2:\t0x%08x\tISR:\t0x%08x\n", hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_CR1_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_CR2_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_ISR_OFFSET)); tmrinfo("\tICR:\t0x%08x\tIER:\t0x%08x\tOENR:\t0x%08x\n", hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_ICR_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_IER_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_OENR_OFFSET)); tmrinfo("\tODISR:\t0x%08x\tODSR:\t0x%08x\tBMCR:\t0x%08x\n", hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_ODISR_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_ODSR_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BMCR_OFFSET)); tmrinfo("\tBMTRG:\t0x%08x\tBMCMPR:\t0x%08x\tBMPER:\t0x%08x\n", hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BMTRGR_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BMCMPR_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BMPER_OFFSET)); tmrinfo("\tADC1R:\t0x%08x\tADC2R:\t0x%08x\tADC3R:\t0x%08x\n", hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_ADC1R_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_ADC2R_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_ADC3R_OFFSET)); tmrinfo("\tADC4R:\t0x%08x\tDLLCR:\t0x%08x\tFLTIN1:\t0x%08x\n", hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_ADC4R_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_DLLCR_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_FLTINR1_OFFSET)); tmrinfo("\tFLTIN2:\t0x%08x\tBDMUPD:\t0x%08x\tBDTAUP:\t0x%08x\n", hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_FLTINR2_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BDMUPDR_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BDTAUPR_OFFSET)); tmrinfo("\tBDTBUP: 0x%08x\tBDTCUP:\t0x%08x\tBDTDUP:\t0x%08x\n", hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BDTBUPR_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BDTCUPR_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BDTDUPR_OFFSET)); tmrinfo("\tBDTEUP:\t0x%08x\tBDMAD:\t0x%08x\n", hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BDTEUPR_OFFSET), hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BDMADR_OFFSET)); break; } default: { tmrerr("ERROR: No such timer index: %d\n", timer); break; } } } #endif /**************************************************************************** * Name: hrtim_dll_cal * * Description: * Calibrate HRTIM DLL * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_dll_cal(FAR struct stm32_hrtim_s *priv) { uint32_t regval = 0; #ifdef CONFIG_STM32_HRTIM_PERIODIC_CAL /* Configure calibration rate */ regval |= HRTIM_DLLCR_CAL_RATE; /* Enable Periodic calibration */ regval |= HRTIM_DLLCR_CALEN; /* CALEN must not be set simultaneously with CAL bit */ hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_DLLCR_OFFSET, regval); #endif /* DLL Calibration Start */ regval |= HRTIM_DLLCR_CAL; hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_DLLCR_OFFSET, regval); while ((hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_ISR_OFFSET) & HRTIM_ISR_DLLRDY) == 0); return OK; } /**************************************************************************** * Name: hrtim_tim_clock_config * * Description: * Configure HRTIM Timer clock * * Input Parameters: * priv - A reference to the HRTIM structure * timer - An HRTIM Timer index * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_tim_clock_config(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint8_t pre) { int ret = OK; uint32_t regval = 0; regval = hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET); switch (pre) { case HRTIM_PRESCALER_1: { regval |= HRTIM_CMNCR_CKPSC_NODIV; break; } case HRTIM_PRESCALER_2: { regval |= HRTIM_CMNCR_CKPSC_d2; break; } case HRTIM_PRESCALER_4: { regval |= HRTIM_CMNCR_CKPSC_d4; break; } case HRTIM_PRESCALER_8: { regval |= HRTIM_CMNCR_CKPSC_d8; break; } case HRTIM_PRESCALER_16: { regval |= HRTIM_CMNCR_CKPSC_d16; break; } case HRTIM_PRESCALER_32: { regval |= HRTIM_CMNCR_CKPSC_d32; break; } case HRTIM_PRESCALER_64: { regval |= HRTIM_CMNCR_CKPSC_d64; break; } case HRTIM_PRESCALER_128: { regval |= HRTIM_CMNCR_CKPSC_d128; break; } default: { tmrerr("ERROR: invalid prescaler value %d for timer %d\n", timer, pre); ret = -EINVAL; goto errout; } } /* Write prescaler configuration */ hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET, regval); errout: return ret; } /**************************************************************************** * Name: hrtim_tim_clocks_config * * Description: * Configure HRTIM Timers Clocks * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_tim_clocks_config(FAR struct stm32_hrtim_s *priv) { int ret = OK; /* Configure Master Timer clock */ #ifdef CONFIG_STM32_HRTIM_MASTER ret = hrtim_tim_clock_config(priv, HRTIM_TIMER_MASTER, HRTIM_MASTER_PRESCALER); if (ret < 0) { goto errout; } #endif /* Configure Timer A clock */ #ifdef CONFIG_STM32_HRTIM_TIMA ret = hrtim_tim_clock_config(priv, HRTIM_TIMER_TIMA, HRTIM_TIMA_PRESCALER); if (ret < 0) { goto errout; } #endif /* Configure Timer B clock */ #ifdef CONFIG_STM32_HRTIM_TIMB ret = hrtim_tim_clock_config(priv, HRTIM_TIMER_TIMB, HRTIM_TIMB_PRESCALER); if (ret < 0) { goto errout; } #endif /* Configure Timer C clock */ #ifdef CONFIG_STM32_HRTIM_TIMC ret = hrtim_tim_clock_config(priv, HRTIM_TIMER_TIMC, HRTIM_TIMC_PRESCALER); if (ret < 0) { goto errout; } #endif /* Configure Timer D clock */ #ifdef CONFIG_STM32_HRTIM_TIMD ret = hrtim_tim_clock_config(priv, HRTIM_TIMER_TIMD, HRTIM_TIMD_PRESCALER); if (ret < 0) { goto errout; } #endif /* Configure Timer E clock */ #ifdef CONFIG_STM32_HRTIM_TIME ret = hrtim_tim_clock_config(priv, HRTIM_TIMER_TIME, HRTIM_TIME_PRESCALER); if (ret < 0) { goto errout; } #endif errout: return ret; } /**************************************************************************** * Name: hrtim_gpios_config * * Description: * Configure HRTIM GPIO * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ #if defined(CONFIG_STM32_HRTIM_PWM) || defined(CONFIG_STM32_HRTIM_SYNC) static int hrtim_gpios_config(FAR struct stm32_hrtim_s *priv) { #ifdef CONFIG_STM32_HRTIM_EVENTS FAR struct stm32_hrtim_eev_s *eev = priv->eev; #endif #ifdef CONFIG_STM32_HRTIM_FAULTS FAR struct stm32_hrtim_faults_s *flt = priv->flt; #endif /* Configure Timer A Outputs */ #ifdef CONFIG_STM32_HRTIM_TIMA_PWM_CH1 stm32_configgpio(GPIO_HRTIM1_CHA1); #endif #ifdef CONFIG_STM32_HRTIM_TIMA_PWM_CH2 stm32_configgpio(GPIO_HRTIM1_CHA2); #endif /* Configure Timer B Outputs */ #ifdef CONFIG_STM32_HRTIM_TIMB_PWM_CH1 stm32_configgpio(GPIO_HRTIM1_CHB1); #endif #ifdef CONFIG_STM32_HRTIM_TIMB_PWM_CH2 stm32_configgpio(GPIO_HRTIM1_CHB2); #endif /* Configure Timer C Outputs */ #ifdef CONFIG_STM32_HRTIM_TIMC_PWM_CH1 stm32_configgpio(GPIO_HRTIM1_CHC1); #endif #ifdef CONFIG_STM32_HRTIM_TIMC_PWM_CH2 stm32_configgpio(GPIO_HRTIM1_CHC2); #endif /* Configure Timer D Outputs */ #ifdef CONFIG_STM32_HRTIM_TIMD_PWM_CH1 stm32_configgpio(GPIO_HRTIM1_CHD1); #endif #ifdef CONFIG_STM32_HRTIM_TIMD_PWM_CH2 stm32_configgpio(GPIO_HRTIM1_CHD2); #endif /* Configure Timer E Outputs */ #ifdef CONFIG_STM32_HRTIM_TIME_PWM_CH1 stm32_configgpio(GPIO_HRTIM1_CHE1); #endif #ifdef CONFIG_STM32_HRTIM_TIME_PWM_CH2 stm32_configgpio(GPIO_HRTIM1_CHE2); #endif /* Configure SCOUT */ #ifdef CONFIG_STM32_HRTIM_SCOUT stm32_configgpio(GPIO_HRTIM1_SCOUT); #endif /* Configure SCIN */ #ifdef CONFIG_STM32_HRTIM_SCIN stm32_configgpio(GPIO_HRTIM1_SCIN); #endif /* Configure Faults Inputs */ #ifdef CONFIG_STM32_HRTIM_FAULT1 if (flt->flt1.src == HRTIM_FAULT_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_FLT1); } #endif #ifdef CONFIG_STM32_HRTIM_FAULT2 if (flt->flt2.src == HRTIM_FAULT_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_FLT2); } #endif #ifdef CONFIG_STM32_HRTIM_FAULT3 if (flt->flt3.src == HRTIM_FAULT_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_FLT3); } #endif #ifdef CONFIG_STM32_HRTIM_FAULT4 if (flt->flt4.src == HRTIM_FAULT_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_FLT4); } #endif #ifdef CONFIG_STM32_HRTIM_FAULT5 if (flt->flt5.src == HRTIM_FAULT_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_FLT5); } #endif /* Configure External Events Inputs */ #ifdef CONFIG_STM32_HRTIM_EEV1 if (eev->eev1.src == HRTIM_EEV_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_EEV1); } #endif #ifdef CONFIG_STM32_HRTIM_EEV2 if (eev->eev2.src == HRTIM_EEV_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_EEV2); } #endif #ifdef CONFIG_STM32_HRTIM_EEV3 if (eev->eev3.src == HRTIM_EEV_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_EEV3); } #endif #ifdef CONFIG_STM32_HRTIM_EEV4 if (eev->eev4.src == HRTIM_EEV_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_EEV4); } #endif #ifdef CONFIG_STM32_HRTIM_EEV5 if (eev->eev5.src == HRTIM_EEV_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_EEV5); } #endif #ifdef CONFIG_STM32_HRTIM_EEV6 if (eev->eev6.src == HRTIM_EEV_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_EEV6); } #endif #ifdef CONFIG_STM32_HRTIM_EEV7 if (eev->eev7.src == HRTIM_EEV_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_EEV7); } #endif #ifdef CONFIG_STM32_HRTIM_EEV8 if (eev->eev8.src == HRTIM_EEV_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_EEV8); } #endif #ifdef CONFIG_STM32_HRTIM_EEV9 if (eev->eev9.src == HRTIM_EEV_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_EEV9); } #endif #ifdef CONFIG_STM32_HRTIM_EEV10 if (eev->eev10.src == HRTIM_EEV_SRC_PIN) { stm32_configgpio(GPIO_HRTIM1_EEV10); } #endif return OK; } #endif #if defined(CONFIG_STM32_HRTIM_CAPTURE) /**************************************************************************** * Name: hrtim_tim_capture_cfg * * Description: * Configure HRTIM Captures * * Input Parameters: * priv - A reference to the HRTIM block * timer - HRTIM Timer index * capture - capture triggers configuration * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_tim_capture_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint8_t index, uint32_t capture) { int ret = OK; uint32_t offset = 0; /* Sanity checking */ if (timer == HRTIM_TIMER_MASTER || timer == HRTIM_TIMER_COMMON) { ret = -EINVAL; goto errout; } switch (index) { case HRTIM_CAPTURE1: { offset = STM32_HRTIM_TIM_CPT1CR_OFFSET; break; } case HRTIM_CAPTURE2: { offset = STM32_HRTIM_TIM_CPT2CR_OFFSET; break; } default: { ret = -EINVAL; goto errout; } } hrtim_tim_putreg(priv, timer, offset, capture); errout: return ret; } /**************************************************************************** * Name: hrtim_capture_config * * Description: * Configure HRTIM Captures * * Input Parameters: * priv - A reference to the HRTIM block * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_capture_config(FAR struct stm32_hrtim_s *priv) { FAR struct stm32_hrtim_slave_priv_s *slave; #ifdef CONFIG_STM32_HRTIM_TIMA_CAP slave = (struct stm32_hrtim_slave_priv_s *)priv->tima->priv; hrtim_tim_capture_cfg(priv, HRTIM_TIMER_TIMA, HRTIM_CAPTURE1, slave->cap.cap1); hrtim_tim_capture_cfg(priv, HRTIM_TIMER_TIMA, HRTIM_CAPTURE2, slave->cap.cap2); #endif #ifdef CONFIG_STM32_HRTIM_TIMB_CAP slave = (struct stm32_hrtim_slave_priv_s *)priv->timb->priv; hrtim_tim_capture_cfg(priv, HRTIM_TIMER_TIMB, HRTIM_CAPTURE1, slave->cap.cap1); hrtim_tim_capture_cfg(priv, HRTIM_TIMER_TIMB, HRTIM_CAPTURE2, slave->cap.cap2); #endif #ifdef CONFIG_STM32_HRTIM_TIMC_CAP slave = (struct stm32_hrtim_slave_priv_s *)priv->timc->priv; hrtim_tim_capture_cfg(priv, HRTIM_TIMER_TIMC, HRTIM_CAPTURE1, slave->cap.cap1); hrtim_tim_capture_cfg(priv, HRTIM_TIMER_TIMC, HRTIM_CAPTURE2, slave->cap.cap2); #endif #ifdef CONFIG_STM32_HRTIM_TIMD_CAP slave = (struct stm32_hrtim_slave_priv_s *)priv->timd->priv; hrtim_tim_capture_cfg(priv, HRTIM_TIMER_TIMD, HRTIM_CAPTURE1, slave->cap.cap1); hrtim_tim_capture_cfg(priv, HRTIM_TIMER_TIMD, HRTIM_CAPTURE2, slave->cap.cap2); #endif #ifdef CONFIG_STM32_HRTIM_TIME_CAP slave = (struct stm32_hrtim_slave_priv_s *)priv->time->priv; hrtim_tim_capture_cfg(priv, HRTIM_TIMER_TIME, HRTIM_CAPTURE1, slave->cap.cap1); hrtim_tim_capture_cfg(priv, HRTIM_TIMER_TIME, HRTIM_CAPTURE2, slave->cap.cap2); #endif return OK; } /**************************************************************************** * Name: hrtim_capture_get * * Description: * Get HRTIM Timer Capture register * * Input Parameters: * priv - A reference to the HRTIM block * timer - HRTIM Timer index * index - Capture register index * * Returned Value: * Timer Capture value on success, 0 on failure * ****************************************************************************/ static uint16_t hrtim_capture_get(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t index) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; uint32_t regval = 0; uint32_t offset = 0; switch (index) { case HRTIM_CAPTURE1: { offset = STM32_HRTIM_TIM_CPT1R_OFFSET; break; } case HRTIM_CAPTURE2: { offset = STM32_HRTIM_TIM_CPT2R_OFFSET; break; } default: { regval = 0; goto errout; } } regval = (uint16_t)hrtim_tim_getreg(priv, timer, offset); errout: return regval; } /**************************************************************************** * Name: hrtim_soft_capture * * Description: * HRTIM Timer software capture tirgger. * * Input Parameters: * dev - HRTIM device structure * timer - HRTIM Timer indexes * index - HRTIM capture index * * Returned Value: * 0 on success; a negated errno value on failure * ****************************************************************************/ static int hrtim_soft_capture(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t index) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; uint32_t offset = 0; switch (index) { case HRTIM_CAPTURE1: { offset = STM32_HRTIM_TIM_CPT1CR_OFFSET; break; } case HRTIM_CAPTURE2: { offset = STM32_HRTIM_TIM_CPT2CR_OFFSET; break; } default: { goto errout; } } /* Modify register */ hrtim_tim_modifyreg(priv, timer, offset, 0, HRTIM_TIMCPT12CR_SWCPT); errout: return OK; } #endif /**************************************************************************** * Name: hrtim_synch_config * * Description: * Configure HRTIM Synchronization Input/Output * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ #if defined(CONFIG_STM32_HRTIM_SYNC) static int hrtim_synch_config(FAR struct stm32_hrtim_s *priv) { #warning "hrtim_synch_config: missing logic" return OK; } #endif /**************************************************************************** * Name: hrtim_tim_outputs_config * * Description: * Configure HRTIM Slave Timer Outputs (CH1 and CH2) * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ #if defined(CONFIG_STM32_HRTIM_PWM) static int hrtim_tim_outputs_config(FAR struct stm32_hrtim_s *priv, uint8_t timer) { FAR struct stm32_hrtim_slave_priv_s *slave; uint32_t regval = 0; int ret = OK; /* Get Slave Timer data structure */ slave = hrtim_slave_get(priv, timer); if (slave == NULL) { ret = -EINVAL; goto errout; } /* Configure CH1 SET events */ regval = slave->pwm.ch1.set; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_SET1R_OFFSET, regval); /* Configure CH1 RESET events */ regval = slave->pwm.ch1.rst; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_RST1R_OFFSET, regval); /* Configure CH2 SET events */ regval = slave->pwm.ch2.set; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_SET2R_OFFSET, regval); /* Configure CH2 RESET events */ regval = slave->pwm.ch2.rst; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_RST2R_OFFSET, regval); /* Now we configure OUT register */ regval = 0; #ifdef CONFIG_STM32_HRTIM_BURST /* Configure IDLE state for output 1 */ if (slave->pwm.burst.ch1_en) { /* Set IDLE mode */ regval |= HRTIM_TIMOUT_IDLEM1; /* Set Idle state */ regval |= ((slave->pwm.burst.ch1_state & HRTIM_IDLE_ACTIVE) ? HRTIM_TIMOUT_IDLES1 : 0); } /* Configure IDLE state for output 2 */ if (slave->pwm.burst.ch2_en) { /* Set IDLE mode */ regval |= HRTIM_TIMOUT_IDLEM1; /* Set Idle state */ regval |= ((slave->pwm.burst.ch2_state & HRTIM_IDLE_ACTIVE) ? HRTIM_TIMOUT_IDLES1 : 0); } #endif #ifdef CONFIG_STM32_HRTIM_DEADTIME if (slave->pwm.dt.en == 1) { /* Set deadtime enable */ regval |= HRTIM_TIMOUT_DTEN; /* TODO: deadtime upon burst mode Idle entry */ } #endif /* Configure Output 1 polarisation */ regval |= ((slave->pwm.ch1.pol & HRTIM_OUT_POL_NEG) ? HRTIM_TIMOUT_POL1 : 0); /* Configure Output 2 polarisation */ regval |= ((slave->pwm.ch2.pol & HRTIM_OUT_POL_NEG) ? HRTIM_TIMOUT_POL2 : 0); /* Write HRTIM Slave Timer Output register */ hrtim_tim_modifyreg(priv, timer, STM32_HRTIM_TIM_OUTR_OFFSET, 0, regval); #ifdef CONFIG_STM32_HRTIM_PUSHPULL if (slave->pwm.pushpull == 1) { /* Enable push-pull mode */ hrtim_tim_modifyreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET, 0, HRTIM_TIMCR_PSHPLL); } #endif errout: return ret; } #endif /**************************************************************************** * Name: hrtim_outputs_config * * Description: * Configure HRTIM Outputs * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ #if defined(CONFIG_STM32_HRTIM_PWM) static int hrtim_outputs_config(FAR struct stm32_hrtim_s *priv) { int ret = OK; /* Configure HRTIM TIMER A Outputs */ #ifdef CONFIG_STM32_HRTIM_TIMA_PWM ret = hrtim_tim_outputs_config(priv, HRTIM_TIMER_TIMA); if (ret < 0) { goto errout; } #endif /* Configure HRTIM TIMER B Outputs */ #ifdef CONFIG_STM32_HRTIM_TIMB_PWM ret = hrtim_tim_outputs_config(priv, HRTIM_TIMER_TIMB); if (ret < 0) { goto errout; } #endif /* Configure HRTIM TIMER C Outputs */ #ifdef CONFIG_STM32_HRTIM_TIMC_PWM ret = hrtim_tim_outputs_config(priv, HRTIM_TIMER_TIMC); if (ret < 0) { goto errout; } #endif /* Configure HRTIM TIMER D Outputs */ #ifdef CONFIG_STM32_HRTIM_TIMD_PWM ret = hrtim_tim_outputs_config(priv, HRTIM_TIMER_TIMD); if (ret < 0) { goto errout; } #endif /* Configure HRTIM TIMER E Outputs */ #ifdef CONFIG_STM32_HRTIM_TIME_PWM ret = hrtim_tim_outputs_config(priv, HRTIM_TIMER_TIME); if (ret < 0) { goto errout; } #endif errout: return ret; } /**************************************************************************** * Name: hrtim_outputs_enable * * Description: * Enable/disable HRTIM outputs (bulk operation) * * Input Parameters: * dev - HRTIM device structure * outputs - outputs to set * state - Enable/disable operation * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_outputs_enable(FAR struct hrtim_dev_s *dev, uint16_t outputs, bool state) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; uint32_t offset = 0; /* Get register offset */ if (state == true) { offset = STM32_HRTIM_CMN_OENR_OFFSET; } else { offset = STM32_HRTIM_CMN_ODISR_OFFSET; } /* Write register */ hrtim_cmn_putreg(priv, offset, outputs); return OK; } /**************************************************************************** * Name: output_tim_index_get ****************************************************************************/ static uint8_t output_tim_index_get(uint16_t output) { uint8_t timer = 0; switch (output) { #ifdef CONFIG_STM32_HRTIM_TIMA case HRTIM_OUT_TIMA_CH1: case HRTIM_OUT_TIMA_CH2: { timer = HRTIM_TIMER_TIMA; break; } #endif #ifdef CONFIG_STM32_HRTIM_TIMB case HRTIM_OUT_TIMB_CH1: case HRTIM_OUT_TIMB_CH2: { timer = HRTIM_TIMER_TIMB; break; } #endif #ifdef CONFIG_STM32_HRTIM_TIMC case HRTIM_OUT_TIMC_CH1: case HRTIM_OUT_TIMC_CH2: { timer = HRTIM_TIMER_TIMC; break; } #endif #ifdef CONFIG_STM32_HRTIM_TIMD case HRTIM_OUT_TIMD_CH1: case HRTIM_OUT_TIMD_CH2: { timer = HRTIM_TIMER_TIMD; break; } #endif #ifdef CONFIG_STM32_HRTIM_TIME case HRTIM_OUT_TIME_CH1: case HRTIM_OUT_TIME_CH2: { timer = HRTIM_TIMER_TIME; break; } #endif default: { timer = 0; break; } } return timer; } /**************************************************************************** * Name: output_tim_ch_get ****************************************************************************/ static uint8_t output_tim_ch_get(uint16_t output) { uint8_t ch = 0; switch (output) { #ifdef CONFIG_STM32_HRTIM_TIMA case HRTIM_OUT_TIMA_CH1: #endif #ifdef CONFIG_STM32_HRTIM_TIMB case HRTIM_OUT_TIMB_CH1: #endif #ifdef CONFIG_STM32_HRTIM_TIMC case HRTIM_OUT_TIMC_CH1: #endif #ifdef CONFIG_STM32_HRTIM_TIMD case HRTIM_OUT_TIMD_CH1: #endif #ifdef CONFIG_STM32_HRTIM_TIME case HRTIM_OUT_TIME_CH1: #endif { ch = HRTIM_OUT_CH1; break; } #ifdef CONFIG_STM32_HRTIM_TIMA case HRTIM_OUT_TIMA_CH2: #endif #ifdef CONFIG_STM32_HRTIM_TIMB case HRTIM_OUT_TIMB_CH2: #endif #ifdef CONFIG_STM32_HRTIM_TIMC case HRTIM_OUT_TIMC_CH2: #endif #ifdef CONFIG_STM32_HRTIM_TIMD case HRTIM_OUT_TIMD_CH2: #endif #ifdef CONFIG_STM32_HRTIM_TIME case HRTIM_OUT_TIME_CH2: #endif { ch = HRTIM_OUT_CH2; break; } default: { ch = 0; break; } } return ch; } /**************************************************************************** * Name: hrtim_output_set_set ****************************************************************************/ static int hrtim_output_set_set(FAR struct hrtim_dev_s *dev, uint16_t output, uint32_t set) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; FAR struct stm32_hrtim_slave_priv_s *slave; uint8_t timer = 0; int ret = OK; /* Get timer index from output */ timer = output_tim_index_get(output); /* Get Slave Timer data structure */ slave = hrtim_slave_get(priv, timer); if (slave == NULL) { ret = -EINVAL; goto errout; } /* Set new SET value */ switch (output_tim_ch_get(output)) { case HRTIM_OUT_CH1: { slave->pwm.ch1.set = set; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_SET1R_OFFSET, set); break; } case HRTIM_OUT_CH2: { slave->pwm.ch2.set = set; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_SET2R_OFFSET, set); break; } default: { ret = -EINVAL; goto errout; } } errout: return ret; } /**************************************************************************** * Name: hrtim_output_rst_set ****************************************************************************/ static int hrtim_output_rst_set(FAR struct hrtim_dev_s *dev, uint16_t output, uint32_t rst) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; FAR struct stm32_hrtim_slave_priv_s *slave; uint8_t timer = 0; int ret = OK; /* Get timer index from output */ timer = output_tim_index_get(output); /* Get Salve Timer data structure */ slave = hrtim_slave_get(priv, timer); if (slave == NULL) { ret = -EINVAL; goto errout; } /* Set new RST value */ switch (output_tim_ch_get(output)) { case HRTIM_OUT_CH1: { slave->pwm.ch1.rst = rst; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_RST1R_OFFSET, rst); } case HRTIM_OUT_CH2: { slave->pwm.ch2.rst = rst; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_RST2R_OFFSET, rst); } default: { ret = -EINVAL; goto errout; } } errout: return ret; } #endif /**************************************************************************** * Name: hrtim_adc_config * * Description: * Configure HRTIM ADC triggers * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ #ifdef HRTIM_HAVE_ADC static int hrtim_adc_config(FAR struct stm32_hrtim_s *priv) { /* Configure ADC Trigger 1 */ #ifdef HRTIM_HAVE_ADC_TRG1 hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_ADC1R_OFFSET, priv->adc->trg1); #endif /* Configure ADC Trigger 2 */ #ifdef HRTIM_HAVE_ADC_TRG2 hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_ADC2R_OFFSET, priv->adc->trg2); #endif /* Configure ADC Trigger 3 */ #ifdef HRTIM_HAVE_ADC_TRG3 hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_ADC3R_OFFSET, priv->adc->trg3); #endif /* Configure ADC Trigger 4 */ #ifdef HRTIM_HAVE_ADC_TRG4 hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_ADC4R_OFFSET, priv->adc->trg4); #endif return OK; } #endif #ifdef CONFIG_STM32_HRTIM_DAC /**************************************************************************** * Name: hrtim_tim_dac_cfg * * Description: * Configure single HRTIM Timer DAC synchronization event * * Input Parameters: * priv - A reference to the HRTIM structure * timer - Timer index * dac - DAC synchronisation event configuration * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_tim_dac_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint8_t dac) { FAR struct stm32_hrtim_tim_s *tim; uint32_t regval = 0; tim = hrtim_tim_get(priv, timer); regval = hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET); regval |= (dac << HRTIM_CMNCR_DACSYNC_SHIFT); hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET, regval); return OK; } /**************************************************************************** * Name: hrtim_dac_config * * Description: * Configure HRTIM DAC synchronization * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_dac_config(FAR struct stm32_hrtim_s *priv) { FAR struct stm32_hrtim_timcmn_s *tim; /* Configure DAC synchronization for Master Timer */ #ifdef CONFIG_STM32_HRTIM_MASTER_DAC tim = (struct stm32_hrtim_timcmn_s *)priv->master; hrtim_tim_dac_cfg(priv, HRTIM_TIMER_MASTER, tim->dac); #endif /* Configure DAC synchronization for Timer A */ #ifdef CONFIG_STM32_HRTIM_TIMA_DAC tim = (struct stm32_hrtim_timcmn_s *)priv->tima; hrtim_tim_dac_cfg(priv, HRTIM_TIMER_TIMA, tim->dac); #endif /* Configure DAC synchronization for Timer B */ #ifdef CONFIG_STM32_HRTIM_TIMB_DAC tim = (struct stm32_hrtim_timcmn_s *)priv->timb; hrtim_tim_dac_cfg(priv, HRTIM_TIMER_TIMB, tim->dac); #endif /* Configure DAC synchronization for Timer C */ #ifdef CONFIG_STM32_HRTIM_TIMC_DAC tim = (struct stm32_hrtim_timcmn_s *)priv->timc; hrtim_tim_dac_cfg(priv, HRTIM_TIMER_TIMC, tim->dac); #endif /* Configure DAC synchronization for Timer D */ #ifdef CONFIG_STM32_HRTIM_TIMD_DAC tim = (struct stm32_hrtim_timcmn_s *)priv->timd; hrtim_tim_dac_cfg(priv, HRTIM_TIMER_TIMD, tim->dac); #endif /* Configure DAC synchronization for Timer E */ #ifdef CONFIG_STM32_HRTIM_TIME_DAC tim = (struct stm32_hrtim_timcmn_s *)priv->time; hrtim_tim_dac_cfg(priv, HRTIM_TIMER_TIME, tim->dac); #endif return OK; } #endif #ifdef CONFIG_STM32_HRTIM_DMA /**************************************************************************** * Name: hrtim_dma_cfg ****************************************************************************/ static int hrtim_tim_dma_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint16_t dma) { int ret = OK; uint32_t regval = 0; /* Sanity checking */ if (timer == HRTIM_TIMER_COMMON) { ret = -EINVAL; goto errout; } if (timer == HRTIM_TIMER_MASTER) { /* Master support first 7 DMA requests */ if (dma > 0x7f) { tmrerr("ERROR: invalid DMA requests 0x%04X for timer %d\n", dma, timer); ret = -EINVAL; goto errout; } } else { if (dma & HRTIM_DMA_SYNC) { tmrerr("ERROR: timer %d does not support 0x%04X DMA request\n", timer, HRTIM_DMA_SYNC); ret = -EINVAL; goto errout; } } /* DMA configuration occupies upper half of the DIER register */ regval = dma << 16; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_DIER_OFFSET, regval); errout: return ret; } /**************************************************************************** * Name: hrtim_dma_cfg ****************************************************************************/ static int hrtim_dma_cfg(FAR struct stm32_hrtim_s *priv) { #ifdef CONFIG_STM32_HRTIM_MASTER_DMA hrtim_tim_dma_cfg(priv, HRTIM_TIMER_MASTER, priv->master->tim.dma); #endif #ifdef CONFIG_STM32_HRTIM_TIMA_DMA hrtim_tim_dma_cfg(priv, HRTIM_TIMER_TIMA, priv->tima->tim.dma); #endif #ifdef CONFIG_STM32_HRTIM_TIMB_DMA hrtim_tim_dma_cfg(priv, HRTIM_TIMER_TIMB, priv->timb->tim.dma); #endif #ifdef CONFIG_STM32_HRTIM_TIMC_DMA hrtim_tim_dma_cfg(priv, HRTIM_TIMER_TIMC, priv->timc->tim.dma); #endif #ifdef CONFIG_STM32_HRTIM_TIMD_DMA hrtim_tim_dma_cfg(priv, HRTIM_TIMER_TIMD, priv->timd->tim.dma); #endif #ifdef CONFIG_STM32_HRTIM_TIME_DMA hrtim_tim_dma_cfg(priv, HRTIM_TIMER_TIME, priv->time->tim.dma); #endif return OK; } #endif /* CONFIG_STM32_HRTIM_DAM */ #ifdef CONFIG_STM32_HRTIM_DEADTIME /**************************************************************************** * Name: hrtim_deadtime_update ****************************************************************************/ static int hrtim_deadtime_update(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t dt, uint16_t value) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; int ret = OK; uint32_t regval = 0; uint32_t shift = 0; uint32_t mask = 0; /* For safety reasons we saturate deadtime value if it exceeds * the acceptable range. */ if (value > 0x1ff) { value = 0x1ff; } /* Get shift value */ switch (dt) { case HRTIM_DT_EDGE_RISING: { shift = HRTIM_TIMDT_DTR_SHIFT; mask = HRTIM_TIMDT_DTR_MASK; break; } case HRTIM_DT_EDGE_FALLING: { shift = HRTIM_TIMDT_DTF_SHIFT; mask = HRTIM_TIMDT_DTF_MASK; break; } default: { ret = -EINVAL; goto errout; } } regval = value << shift; /* Update register */ hrtim_tim_modifyreg(priv, timer, STM32_HRTIM_TIM_DTR_OFFSET, mask, regval); errout: return ret; } /**************************************************************************** * Name: hrtim_deadtime_get ****************************************************************************/ static uint16_t hrtim_deadtime_get(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t dt) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; uint16_t regval = 0; uint32_t shift = 0; uint32_t mask = 0; /* Get shift value */ switch (dt) { case HRTIM_DT_EDGE_RISING: { shift = HRTIM_TIMDT_DTR_SHIFT; mask = HRTIM_TIMDT_DTR_MASK; break; } case HRTIM_DT_EDGE_FALLING: { shift = HRTIM_TIMDT_DTF_SHIFT; mask = HRTIM_TIMDT_DTF_MASK; break; } default: { regval = 0; goto errout; } } /* Get Deadtime Register */ regval = hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_DTR_OFFSET); /* Get Deadtime value */ regval = (regval & mask) >> shift; errout: return regval; } /**************************************************************************** * Name: hrtim_tim_deadtime_cfg ****************************************************************************/ static int hrtim_tim_deadtime_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer) { FAR struct stm32_hrtim_slave_priv_s *slave; uint32_t regval = 0; int ret = OK; /* Sanity checking */ if (timer == HRTIM_TIMER_MASTER || timer == HRTIM_TIMER_COMMON) { ret = -EINVAL; goto errout; } /* Get Slave Timer data structure */ slave = hrtim_slave_get(priv, timer); if (slave == NULL) { ret = -EINVAL; goto errout; } /* Configure deadtime prescaler */ regval |= slave->pwm.dt.prescaler << HRTIM_TIMDT_DTPRSC_SHIFT; /* Configure rising deadtime */ regval |= slave->pwm.dt.rising << HRTIM_TIMDT_DTR_SHIFT; /* Configure falling deadtime */ regval |= slave->pwm.dt.falling << HRTIM_TIMDT_DTF_SHIFT; /* Configure falling deadtime sign */ if (slave->pwm.dt.fsign == HRTIM_DT_SIGN_NEGATIVE) { regval |= HRTIM_TIMDT_SDTF; } /* Configure risign deadtime sign */ if (slave->pwm.dt.rsign == HRTIM_DT_SIGN_NEGATIVE) { regval |= HRTIM_TIMDT_SDTR; } /* Configure falling sing lock */ if (slave->pwm.dt.fsign_lock == HRTIM_DT_LOCK) { regval |= HRTIM_TIMDT_DTFSLK; } /* Configure rising sing lock */ if (slave->pwm.dt.rsign_lock == HRTIM_DT_LOCK) { regval |= HRTIM_TIMDT_DTRSLK; } /* Configure rising value lock */ if (slave->pwm.dt.rising_lock == HRTIM_DT_LOCK) { regval |= HRTIM_TIMDT_DTRLK; } /* Configure falling value lock */ if (slave->pwm.dt.falling_lock == HRTIM_DT_LOCK) { regval |= HRTIM_TIMDT_DTFLK; } /* TODO: configure default deadtime values */ /* Write register */ hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_DTR_OFFSET, regval); errout: return ret; } /**************************************************************************** * Name: hrtim_deadtime_config ****************************************************************************/ static int hrtim_deadtime_config(FAR struct stm32_hrtim_s *priv) { /* Configure Timer A deadtime */ #ifdef CONFIG_STM32_HRTIM_TIMA_DT hrtim_tim_deadtime_cfg(priv, HRTIM_TIMER_TIMA); #endif /* Configure Timer B deadtime */ #ifdef CONFIG_STM32_HRTIM_TIMB_DT hrtim_tim_deadtime_cfg(priv, HRTIM_TIMER_TIMB); #endif /* Configure Timer C deadtime */ #ifdef CONFIG_STM32_HRTIM_TIMC_DT hrtim_tim_deadtime_cfg(priv, HRTIM_TIMER_TIMC); #endif /* Configure Timer D deadtime */ #ifdef CONFIG_STM32_HRTIM_TIMD_DT hrtim_tim_deadtime_cfg(priv, HRTIM_TIMER_TIMD); #endif /* Configure Timer E deadtime */ #ifdef CONFIG_STM32_HRTIM_TIME_DT hrtim_tim_deadtime_cfg(priv, HRTIM_TIMER_TIME); #endif return OK; } #endif /* CONFIG_STM32_HRTIM_DEADTIME */ #ifdef CONFIG_STM32_HRTIM_CHOPPER /**************************************************************************** * Name: hrtim_chopper_enable * * Description: * Enable/disable HRTIM outputs (bulk operation) * * Input Parameters: * dev - HRTIM device structure * timer - An HRTIM Timer index * chan - Output channel * state - Enable/disable operation * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_chopper_enable(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t chan, bool state) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; uint32_t val = 0; int ret = OK; /* Get bit to change */ switch (chan) { case HRTIM_OUT_CH1: { val = HRTIM_TIMOUT_CHP1; break; } case HRTIM_OUT_CH2: { val = HRTIM_TIMOUT_CHP2; break; } default: { ret = -EINVAL; goto errout; } } /* Update register */ if (state == true) { /* Set enable bit */ hrtim_tim_modifyreg(priv, timer, STM32_HRTIM_TIM_OUTR_OFFSET, 0, val); } else { /* Clear enable bit */ hrtim_tim_modifyreg(priv, timer, STM32_HRTIM_TIM_OUTR_OFFSET, val, 0); } errout: return ret; } /**************************************************************************** * Name: hrtim_chopper_cfg ****************************************************************************/ static int hrtim_tim_chopper_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer) { FAR struct stm32_hrtim_slave_priv_s *slave; int ret = OK; uint32_t regval = 0; /* Sanity checking */ if (timer == HRTIM_TIMER_MASTER || timer == HRTIM_TIMER_COMMON) { ret = -EINVAL; goto errout; } /* Get Slave Timer data structure */ slave = hrtim_slave_get(priv, timer); if (slave == NULL) { ret = -EINVAL; goto errout; } /* Configure start pulsewidth */ regval |= slave->pwm.chp.start_pulse << HRTIM_TIMCHP_STRTPW_SHIFT; /* Configure chopper duty cycle */ regval |= slave->pwm.chp.duty << HRTIM_TIMCHP_CARDTY_SHIFT; /* Configure carrier frequency */ regval |= slave->pwm.chp.freq << HRTIM_TIMCHP_CARFRQ_SHIFT; /* Write register */ hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_CHPR_OFFSET, regval); errout: return OK; } /**************************************************************************** * Name: hrtim_chopper_config ****************************************************************************/ static int hrtim_chopper_config(FAR struct stm32_hrtim_s *priv) { /* Configure chopper for Timer A */ #ifdef CONFIG_STM32_HRTIM_TIMA_CHOP hrtim_tim_chopper_cfg(priv, HRTIM_TIMER_TIMA); #endif /* Configure chopper for Timer B */ #ifdef CONFIG_STM32_HRTIM_TIMB_CHOP hrtim_tim_chopper_cfg(priv, HRTIM_TIMER_TIMB); #endif /* Configure chopper for Timer C */ #ifdef CONFIG_STM32_HRTIM_TIMC_CHOP hrtim_tim_chopper_cfg(priv, HRTIM_TIMER_TIMC); #endif /* Configure chopper for Timer D */ #ifdef CONFIG_STM32_HRTIM_TIMD_CHOP hrtim_tim_chopper_cfg(priv, HRTIM_TIMER_TIMD); #endif /* Configure chopper for Timer E */ #ifdef CONFIG_STM32_HRTIM_TIME_CHOP hrtim_tim_chopper_cfg(priv, HRTIM_TIMER_TIME); #endif return OK; } #endif #ifdef CONFIG_STM32_HRTIM_BURST /**************************************************************************** * Name: hrtim_burst_enable ****************************************************************************/ static int hrtim_burst_enable(FAR struct hrtim_dev_s *dev, bool state) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; if (state) { /* Enable Burst mode */ hrtim_cmn_modifyreg(priv, STM32_HRTIM_CMN_BMCR_OFFSET, 0, HRTIM_BMCR_BME); /* Software start */ hrtim_cmn_modifyreg(priv, STM32_HRTIM_CMN_BMTRGR_OFFSET, 0, HRTIM_BMTRGR_SW); } else { /* Disable Burst mode */ hrtim_cmn_modifyreg(priv, STM32_HRTIM_CMN_BMCR_OFFSET, HRTIM_BMCR_BME, 0); } return OK; } /**************************************************************************** * Name: hrtim_burst_cmp_update ****************************************************************************/ static int hrtim_burst_cmp_update(FAR struct hrtim_dev_s *dev, uint16_t cmp) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_BMCMPR_OFFSET, cmp); return OK; } /**************************************************************************** * Name: hrtim_burst_per_update ****************************************************************************/ static int hrtim_burst_per_update(FAR struct hrtim_dev_s *dev, uint16_t per) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_BMPER_OFFSET, per); return OK; } /**************************************************************************** * Name: hrtim_burst_cmp_get ****************************************************************************/ static uint16_t hrtim_burst_cmp_get(FAR struct hrtim_dev_s *dev) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; return (uint16_t)hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BMCMPR_OFFSET); } /**************************************************************************** * Name: hrtim_burst_per_get ****************************************************************************/ static uint16_t hrtim_burst_per_get(FAR struct hrtim_dev_s *dev) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; return (uint16_t)hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_BMPER_OFFSET); } /**************************************************************************** * Name: hrtim_burst_pre_update ****************************************************************************/ static int hrtim_burst_pre_update(FAR struct hrtim_dev_s *dev, uint8_t pre) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; int ret = OK; uint32_t regval = 0; /* Sanity checking */ if (priv->burst->clk != HRTIM_BURST_CLOCK_HRTIM) { ret = -EPERM; goto errout; } if (pre > HRTIM_BURST_PRESCALER_32768) { ret = -EINVAL; goto errout; } /* Make sure that Burst mode is disabled */ hrtim_burst_enable(dev, false); /* Change prescaler */ priv->burst->presc = pre; regval = pre << HRTIM_BMCR_BMPRSC_SHIFT; hrtim_cmn_modifyreg(priv, STM32_HRTIM_CMN_BMCR_OFFSET, HRTIM_BMCR_BMPRSC_MASK, regval); errout: return ret; } /**************************************************************************** * Name: hrtim_burst_pre_get ****************************************************************************/ static int hrtim_burst_pre_get(FAR struct hrtim_dev_s *dev) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; int ret = OK; if (priv->burst->clk != HRTIM_BURST_CLOCK_HRTIM) { ret = -EPERM; goto errout; } ret = priv->burst->presc; errout: return ret; } /**************************************************************************** * Name: hrtim_burst_config ****************************************************************************/ static int hrtim_burst_config(FAR struct stm32_hrtim_s *priv) { FAR struct stm32_hrtim_burst_s *burst = priv->burst; uint32_t regval = 0; /* Configure triggers */ regval = burst->trg; /* Write triggers register */ hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_BMTRGR_OFFSET, regval); /* TODO: timers mode configuration */ regval = 0; /* Configure burst mode clock source */ regval |= (burst->clk << HRTIM_BMCR_BMCLK_SHIFT); /* Configure burst mode prescaler if f_HRTIM clock */ if (burst->clk == HRTIM_BURST_CLOCK_HRTIM) { regval |= (burst->presc << HRTIM_BMCR_BMPRSC_SHIFT); } /* Set continuous mode */ regval |= HRTIM_BMCR_BMOM; /* Write Burst Mode CR */ hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_BMCR_OFFSET, regval); return OK; } #endif #ifdef CONFIG_STM32_HRTIM_FAULTS /**************************************************************************** * Name: hrtim_tim_faults_cfg * * Description: * Configure HRTIM Slave Timer faults sources. * * Input Parameters: * priv - A reference to the HRTIM structure * timer - timer index * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_tim_faults_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer) { FAR struct stm32_hrtim_slave_priv_s *slave; uint32_t regval = 0; int ret = OK; slave = hrtim_slave_get(priv, timer); if (slave == NULL) { ret = -EINVAL; goto errout; } /* Get lock configuration */ regval = ((slave->flt & HRTIM_TIM_FAULT_LOCK) ? HRTIM_TIMFLT_FLTLCK : 0); /* Get sources configuration */ regval |= slave->flt & 0x1f; /* Write register */ hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_FLTR_OFFSET, regval); errout: return ret; } /**************************************************************************** * Name: hrtim_faults_config * * Description: * Configure single HRTIM Fault * * Input Parameters: * priv - A reference to the HRTIM structure * index - Fault index * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_flt_cfg(FAR struct stm32_hrtim_s *priv, uint8_t index) { FAR struct stm32_hrtim_fault_cfg_s *flt; int ret = OK; uint32_t regval = 0; /* Get fault configuration */ switch (index) { #ifdef CONFIG_STM32_HRTIM_FAULT1 case 1: { flt = &priv->flt->flt1; break; } #endif #ifdef CONFIG_STM32_HRTIM_FAULT2 case 2: { flt = &priv->flt->flt2; break; } #endif #ifdef CONFIG_STM32_HRTIM_FAULT3 case 3: { flt = &priv->flt->flt3; break; } #endif #ifdef CONFIG_STM32_HRTIM_FAULT4 case 4: { flt = &priv->flt->flt4; break; } #endif #ifdef CONFIG_STM32_HRTIM_FAULT5 case 5: { flt = &priv->flt->flt5; break; } #endif default: { ret = -EINVAL; goto errout; } } /* Configure fault */ switch (index) { /* Fault 1-4 Configuration is located in first common fault register */ case 1: case 2: case 3: case 4: { regval = hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_FLTINR1_OFFSET); /* Configure polarity */ regval |= (((flt->pol & HRTIM_FAULT_POL_HIGH) ? HRTIM_FLTINR1_FLT1P : 0) << (index - 1) * 8); /* Config source */ regval |= (((flt->src & HRTIM_FAULT_SRC_PIN) ? HRTIM_FLTINR1_FLT1SRC : 0) << (index - 1) * 8); /* Config filter */ regval |= ((flt->filter << HRTIM_FLTINR1_FLT1F_SHIFT) << (index - 1) * 8); /* Fault enable */ regval |= (HRTIM_FLTINR1_FLT1E << (index - 1) * 8); /* Write register */ hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_FLTINR1_OFFSET, regval); break; } /* Fault 5 configuration is located in second common fault * register */ case 5: { regval = hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_FLTINR2_OFFSET); /* Configure polarity */ regval |= ((flt->pol & HRTIM_FAULT_POL_HIGH) ? HRTIM_FLTINR2_FLT5P : 0); /* Config source */ regval |= ((flt->src & HRTIM_FAULT_SRC_PIN) ? HRTIM_FLTINR2_FLT5SRC : 0); /* Config filter */ regval |= ((flt->filter << HRTIM_FLTINR2_FLT5F_SHIFT)); /* Fault enable */ regval |= HRTIM_FLTINR2_FLT5E; /* Write register */ hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_FLTINR2_OFFSET, regval); break; } default: { ret = -EINVAL; goto errout; } } errout: return ret; } /**************************************************************************** * Name: hrtim_faults_config * * Description: * Configure HRTIM Faults * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_faults_config(FAR struct stm32_hrtim_s *priv) { uint32_t regval = 0; /* Configure faults */ #ifdef CONFIG_STM32_HRTIM_FAULT1 hrtim_flt_cfg(priv, 1); #endif #ifdef CONFIG_STM32_HRTIM_FAULT2 hrtim_flt_cfg(priv, 2); #endif #ifdef CONFIG_STM32_HRTIM_FAULT3 hrtim_flt_cfg(priv, 3); #endif #ifdef CONFIG_STM32_HRTIM_FAULT4 hrtim_flt_cfg(priv, 4); #endif #ifdef CONFIG_STM32_HRTIM_FAULT5 hrtim_flt_cfg(priv, 5); #endif /* Configure fault sources in Slave Timers */ #ifdef CONFIG_STM32_HRTIM_TIMA_FLT hrtim_tim_faults_cfg(priv, HRTIM_TIMER_TIMA); #endif #ifdef CONFIG_STM32_HRTIM_TIMB_FLT hrtim_tim_faults_cfg(priv, HRTIM_TIMER_TIMA); #endif #ifdef CONFIG_STM32_HRTIM_TIMC_FLT hrtim_tim_faults_cfg(priv, HRTIM_TIMER_TIMA); #endif #ifdef CONFIG_STM32_HRTIM_TIMD_FLT hrtim_tim_faults_cfg(priv, HRTIM_TIMER_TIMA); #endif #ifdef CONFIG_STM32_HRTIM_TIME_FLT hrtim_tim_faults_cfg(priv, HRTIM_TIMER_TIMA); #endif /* Configure fault sampling clock division */ regval = hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_FLTINR2_OFFSET); regval |= HRTIM_FAULT_SAMPLING << HRTIM_FLTINR1_FLT1F_SHIFT; hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_FLTINR2_OFFSET, regval); return OK; } #endif #ifdef CONFIG_STM32_HRTIM_EVENTS /**************************************************************************** * Name: hrtim_eev_cfg * * Description: * Configure single HRTIM External Event * * Input Parameters: * priv - A reference to the HRTIM structure * index - External Event index * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_eev_cfg(FAR struct stm32_hrtim_s *priv, uint8_t index) { struct stm32_hrtim_eev_cfg_s *eev; int ret = OK; uint32_t regval = 0; /* Get External Event configuration */ switch (index) { #ifdef CONFIG_STM32_HRTIM_EEV1 case 1: { eev = &priv->eev->eev1; break; } #endif #ifdef CONFIG_STM32_HRTIM_EEV2 case 2: { eev = &priv->eev->eev2; break; } #endif #ifdef CONFIG_STM32_HRTIM_EEV3 case 3: { eev = &priv->eev->eev3; break; } #endif #ifdef CONFIG_STM32_HRTIM_EEV4 case 4: { eev = &priv->eev->eev4; break; } #endif #ifdef CONFIG_STM32_HRTIM_EEV5 case 5: { eev = &priv->eev->eev5; break; } #endif #ifdef CONFIG_STM32_HRTIM_EEV6 case 6: { eev = &priv->eev->eev6; break; } #endif #ifdef CONFIG_STM32_HRTIM_EEV7 case 7: { eev = &priv->eev->eev7; break; } #endif #ifdef CONFIG_STM32_HRTIM_EEV8 case 8: { eev = &priv->eev->eev8; break; } #endif #ifdef CONFIG_STM32_HRTIM_EEV8 case 9: { eev = &priv->eev->eev9; break; } #endif #ifdef CONFIG_STM32_HRTIM_EEV10 case 10: { eev = &priv->eev->eev10; break; } #endif default: { ret = -EINVAL; goto errout; } } switch (index) { case 1: case 2: case 3: case 4: case 5: case 6: { regval = hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_EECR1_OFFSET); /* Configure source */ regval |= ((eev->src << HRTIM_EECR1_EE1SRC_SHIFT) << (index - 1) * 6); /* Configure polarity */ regval |= ((eev->pol & HRTIM_FAULT_POL_HIGH ? HRTIM_EECR1_EE1POL : 0) << (index - 1) * 6); /* Configure sensitivity */ regval |= (((eev->sen) << HRTIM_EECR1_EE1SNS_SHIFT) << (index - 1) * 6); /* Configure mode */ regval |= (((eev->mode & HRTIM_EEV_MODE_FAST) ? HRTIM_EECR1_EE1FAST : 0) << (index - 1) * 6); /* Write register */ hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_EECR1_OFFSET, regval); break; } case 7: case 8: case 9: case 10: { regval = hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_EECR2_OFFSET); /* Configure source */ regval |= ((eev->src << HRTIM_EECR2_EE6SRC_SHIFT) << (index - 6) * 6); /* Configure polarity */ regval |= ((eev->pol & HRTIM_FAULT_POL_HIGH ? HRTIM_EECR2_EE6POL : 0) << (index - 6) * 6); /* Configure sensitivity */ regval |= (((eev->sen) << HRTIM_EECR2_EE6SNS_SHIFT) << (index - 6) * 6); /* Configure External Event filter, only EEV6-10 */ regval |= (((eev->filter) << HRTIM_EECR2_EE6SNS_SHIFT) << (index - 6) * 6); /* Write register */ hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_EECR2_OFFSET, regval); break; } default: { ret = -EINVAL; goto errout; } } errout: return ret; } /**************************************************************************** * Name: hrtim_events_config * * Description: * Configure HRTIM External Events * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_events_config(FAR struct stm32_hrtim_s *priv) { uint32_t regval = 0; /* Configure Events sources */ #ifdef CONFIG_STM32_HRTIM_EEV1 hrtim_eev_cfg(priv, 1); #endif #ifdef CONFIG_STM32_HRTIM_EEV2 hrtim_eev_cfg(priv, 2); #endif #ifdef CONFIG_STM32_HRTIM_EEV3 hrtim_eev_cfg(priv, 3); #endif #ifdef CONFIG_STM32_HRTIM_EEV4 hrtim_eev_cfg(priv, 4); #endif #ifdef CONFIG_STM32_HRTIM_EEV5 hrtim_eev_cfg(priv, 5); #endif #ifdef CONFIG_STM32_HRTIM_EEV6 hrtim_eev_cfg(priv, 6); #endif #ifdef CONFIG_STM32_HRTIM_EEV7 hrtim_eev_cfg(priv, 7); #endif #ifdef CONFIG_STM32_HRTIM_EEV8 hrtim_eev_cfg(priv, 8); #endif #ifdef CONFIG_STM32_HRTIM_EEV9 hrtim_eev_cfg(priv, 9); #endif #ifdef CONFIG_STM32_HRTIM_EEV10 hrtim_eev_cfg(priv, 10); #endif /* External Event Sampling clock */ regval = hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_EECR3_OFFSET); regval |= (HRTIM_EEV_SAMPLING << HRTIM_EECR3_EEVSD_SHIFT); hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_EECR3_OFFSET, regval); return OK; } #endif /* CONFIG_STM32_HRTIM_FAULTS */ #ifdef CONFIG_STM32_HRTIM_INTERRUPTS /**************************************************************************** * Name: hrtim_irq_cfg ****************************************************************************/ static int hrtim_irq_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint16_t irq) { int ret = OK; if (timer == HRTIM_TIMER_COMMON) { hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_IER_OFFSET, irq); } else { hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_DIER_OFFSET, irq); } return ret; } /**************************************************************************** * Name: hrtim_irq_config * * Description: * Configure HRTIM interrupts * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_irq_config(FAR struct stm32_hrtim_s *priv) { #ifdef CONFIG_STM32_HRTIM_MASTER_IRQ hrtim_irq_cfg(priv, HRTIM_TIMER_MASTER, priv->master->tim.irq); #endif #ifdef CONFIG_STM32_HRTIM_TIMA_IRQ hrtim_irq_cfg(priv, HRTIM_TIMER_TIMA, priv->tima->tim.irq); #endif #ifdef CONFIG_STM32_HRTIM_TIMB_IRQ hrtim_irq_cfg(priv, HRTIM_TIMER_TIMB, priv->timb->tim.irq); #endif #ifdef CONFIG_STM32_HRTIM_TIMB_IRQ hrtim_irq_cfg(priv, HRTIM_TIMER_TIMB, priv->timc->tim.irq); #endif #ifdef CONFIG_STM32_HRTIM_TIMB_IRQ hrtim_irq_cfg(priv, HRTIM_TIMER_TIMB, priv->timd->tim.irq); #endif #ifdef CONFIG_STM32_HRTIM_TIMB_IRQ hrtim_irq_cfg(priv, HRTIM_TIMER_TIMB, priv->time->tim.irq); #endif #ifdef CONFIG_STM32_HRTIM_COMMON_IRQ hrtim_irq_cfg(priv, HRTIM_TIMER_COMMON, priv->irq); #endif return OK; } /**************************************************************************** * Name: hrtim_irq_ack ****************************************************************************/ static int hrtim_irq_ack(FAR struct hrtim_dev_s *dev, uint8_t timer, int source) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; if (timer == HRTIM_TIMER_COMMON) { /* Write to the HRTIM common clear interrupt register */ hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_ICR_OFFSET, source); } else { /* Each timer has its own ICR register */ hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_ICR_OFFSET, source); } return OK; } /**************************************************************************** * Name: hrtim_irq_get ****************************************************************************/ static uint16_t hrtim_irq_get(FAR struct hrtim_dev_s *dev, uint8_t timer) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; uint32_t regval = 0; if (timer == HRTIM_TIMER_COMMON) { /* Get HRTIM common status interrupt register */ regval = hrtim_cmn_getreg(priv, STM32_HRTIM_CMN_ISR_OFFSET); } else { /* Each timer has its own ISR register */ regval = hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_ISR_OFFSET); } return (uint16_t)regval; } #endif /* CONFIG_STM32_HRTIM_INTERRUPTS */ /**************************************************************************** * Name: hrtim_tim_mode_set * * Description: * Set HRTIM Timer mode * * Input Parameters: * priv - A reference to the HRTIM block * timer - HRTIM Timer index * mode - Timer mode configuration * * Returned Value: * None * ****************************************************************************/ static void hrtim_tim_mode_set(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint8_t mode) { uint32_t regval = 0; regval = hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET); /* Configure preload */ if (mode & HRTIM_MODE_PRELOAD) { regval |= HRTIM_CMNCR_PREEN; } /* Configure half mode */ if (mode & HRTIM_MODE_HALF) { regval |= HRTIM_CMNCR_HALF; } /* Configure re-triggerable mode */ if (mode & HRTIM_MODE_RETRIG) { regval |= HRTIM_CMNCR_RETRIG; } /* Configure continuous mode */ if (mode & HRTIM_MODE_CONT) { regval |= HRTIM_CMNCR_CONT; } /* Write register */ hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET, regval); } /**************************************************************************** * Name: hrtim_mode_config * * Description: * Configure HRTIM Timers mode * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * None * ****************************************************************************/ static void hrtim_mode_config(FAR struct stm32_hrtim_s *priv) { #ifdef CONFIG_STM32_HRTIM_MASTER hrtim_tim_mode_set(priv, HRTIM_TIMER_MASTER, priv->master->tim.mode); #endif #ifdef CONFIG_STM32_HRTIM_TIMA hrtim_tim_mode_set(priv, HRTIM_TIMER_TIMA, priv->tima->tim.mode); #endif #ifdef CONFIG_STM32_HRTIM_TIMB hrtim_tim_mode_set(priv, HRTIM_TIMER_TIMB, priv->timb->tim.mode); #endif #ifdef CONFIG_STM32_HRTIM_TIMC hrtim_tim_mode_set(priv, HRTIM_TIMER_TIMC, priv->timc->tim.mode); #endif #ifdef CONFIG_STM32_HRTIM_TIMD hrtim_tim_mode_set(priv, HRTIM_TIMER_TIMD, priv->timd->tim.mode); #endif #ifdef CONFIG_STM32_HRTIM_TIME hrtim_tim_mode_set(priv, HRTIM_TIMER_TIME, priv->time->tim.mode); #endif } /**************************************************************************** * Name: hrtim_cmpcap_mask_get * * Description: * This function returns not significant bits in counter/capture * registers for given HRTIM Timer index. * * Input Parameters: * priv - A reference to the HRTIM structure * timer - HRTIM Timer index * * Returned Value: * Not significant bits for counter/capture registers * ****************************************************************************/ static uint8_t hrtim_cmpcap_mask_get(FAR struct stm32_hrtim_s *priv, uint8_t timer) { FAR struct stm32_hrtim_tim_s *tim; uint8_t mask = 0; /* Get Timer data structure */ tim = hrtim_tim_get(priv, timer); if (tim == NULL) { mask = 0; goto errout; } /* Not significant bits depens on timer prescaler */ switch (tim->tim.prescaler) { case HRTIM_PRESCALER_1: { mask = 0b11111; break; } case HRTIM_PRESCALER_2: { mask = 0b1111; break; } case HRTIM_PRESCALER_4: { mask = 0b111; break; } case HRTIM_PRESCALER_8: { mask = 0b11; break; } case HRTIM_PRESCALER_16: { mask = 0b1; break; } default: { mask = 0; break; } } errout: return mask; } /**************************************************************************** * Name: hrtim_cmp_update * * Description: * Try update HRTIM Timer compare register. * * Input Parameters: * dev - HRTIM device structure * timer - HRTIM Timer index * index - Compare register timer * cmp - New compare register value * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_cmp_update(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t index, uint16_t cmp) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; int ret = OK; uint32_t offset = 0; uint8_t mask = 0; switch (index) { case HRTIM_CMP1: { offset = STM32_HRTIM_TIM_CMP1R_OFFSET; break; } case HRTIM_CMP2: { offset = STM32_HRTIM_TIM_CMP2R_OFFSET; break; } case HRTIM_CMP3: { offset = STM32_HRTIM_TIM_CMP3R_OFFSET; break; } case HRTIM_CMP4: { offset = STM32_HRTIM_TIM_CMP4R_OFFSET; break; } default: { ret = -EINVAL; goto errout; } } /* REVISIT: what should we do if cmp value is not significant ? * At this moment we set compare register to the nearest significant value. */ mask = hrtim_cmpcap_mask_get(priv, timer); if (cmp <= mask) { cmp = mask + 1; } hrtim_tim_putreg(priv, timer, offset, cmp); errout: return ret; } /**************************************************************************** * Name: hrtim_per_update * * Description: * Try update HRTIM Timer period register. * * Input Parameters: * dev - HRTIM device structure * timer - HRTIM Timer index * per - New period register value * * Returned Value: * 0 on success; a negated errno value on failure * ****************************************************************************/ static int hrtim_per_update(FAR struct hrtim_dev_s *dev, uint8_t timer, uint16_t per) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_PER_OFFSET, per); return OK; } /**************************************************************************** * Name: hrtim_per_get * * Description: * Get HRTIM Timer period value * * Input Parameters: * dev - HRTIM device structure * timer - HRTIM Timer index * * Returned Value: * Timer period value * ****************************************************************************/ static uint16_t hrtim_per_get(FAR struct hrtim_dev_s *dev, uint8_t timer) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; return (uint16_t)hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_PER_OFFSET); } /**************************************************************************** * Name: hrtim_rep_update * * Description: * Try update HRTIM Timer repetition register. * * Input Parameters: * dev - HRTIM device structure * timer - HRTIM Timer index * rep - New repetition register value * * Returned Value: * 0 on success; a negated errno value on failure * ****************************************************************************/ static int hrtim_rep_update(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t rep) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_REPR_OFFSET, rep); return OK; } /**************************************************************************** * Name: hrtim_cmp_update * * Description: * Get HRTIM Timer compare register * * Input Parameters: * priv - A reference to the HRTIM block * timer - HRTIM Timer index * index - Compare register timer * * Returned Value: * Timer compare value * ****************************************************************************/ static uint16_t hrtim_cmp_get(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t index) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; uint16_t cmpx = 0; uint32_t offset = 0; switch (index) { case HRTIM_CMP1: { offset = STM32_HRTIM_TIM_CMP1R_OFFSET; break; } case HRTIM_CMP2: { offset = STM32_HRTIM_TIM_CMP2R_OFFSET; break; } case HRTIM_CMP3: { offset = STM32_HRTIM_TIM_CMP3R_OFFSET; break; } case HRTIM_CMP4: { offset = STM32_HRTIM_TIM_CMP4R_OFFSET; break; } default: { cmpx = 0; goto errout; } } cmpx = (uint16_t)hrtim_tim_getreg(priv, timer, offset); errout: return cmpx; } /**************************************************************************** * Name: hrtim_fclk_get * * Description: * Get HRTIM Timer clock value * * Input Parameters: * dev - HRTIM device structure * timer - HRTIM Timer index * * Returned Value: * Timer clock value * ****************************************************************************/ static uint64_t hrtim_fclk_get(FAR struct hrtim_dev_s *dev, uint8_t timer) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; FAR struct stm32_hrtim_tim_s *tim; uint64_t fclk = 0; /* Get Timer data structure */ tim = hrtim_tim_get(priv, timer); if (tim == NULL) { fclk = 0; goto errout; } fclk = tim->tim.fclk; errout: return fclk; } /**************************************************************************** * Name: hrtim_soft_update * * Description: * HRTIM Timer software update. * This is bulk operation, so we can update many registers at the same * time. * * Input Parameters: * dev - HRTIM device structure * timer - HRTIM Timer indexes * * Returned Value: * 0 on success; a negated errno value on failure * ****************************************************************************/ static int hrtim_soft_update(FAR struct hrtim_dev_s *dev, uint8_t timer) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; uint32_t regval = 0; regval |= (timer & HRTIM_TIMER_MASTER ? HRTIM_CR2_MSWU : 0); #ifdef CONFIG_STM32_HRTIM_TIMA regval |= (timer & HRTIM_TIMER_TIMA ? HRTIM_CR2_TASWU : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIMB regval |= (timer & HRTIM_TIMER_TIMB ? HRTIM_CR2_TBSWU : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIMC regval |= (timer & HRTIM_TIMER_TIMC ? HRTIM_CR2_TCSWU : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIMD regval |= (timer & HRTIM_TIMER_TIMD ? HRTIM_CR2_TDSWU : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIME regval |= (timer & HRTIM_TIMER_TIME ? HRTIM_CR2_TESWU : 0); #endif /* Bits in HRTIM CR2 common register are automatically reset, * so we can just write to it. */ hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_CR2_OFFSET, regval); return OK; } /**************************************************************************** * Name: hrtim_soft_reset * * Description: * HRTIM Timer software reset. * This is bulk operation, so we can update many registers at the same * time. * * Input Parameters: * dev - HRTIM device structure * timer - HRTIM Timer indexes * * Returned Value: * 0 on success; a negated errno value on failure * ****************************************************************************/ static int hrtim_soft_reset(FAR struct hrtim_dev_s *dev, uint8_t timer) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; uint32_t regval = 0; regval |= (timer & HRTIM_TIMER_MASTER ? HRTIM_CR2_MRST : 0); #ifdef CONFIG_STM32_HRTIM_TIMA regval |= (timer & HRTIM_TIMER_TIMA ? HRTIM_CR2_TARST : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIMB regval |= (timer & HRTIM_TIMER_TIMB ? HRTIM_CR2_TBRST : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIMC regval |= (timer & HRTIM_TIMER_TIMC ? HRTIM_CR2_TCRST : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIMD regval |= (timer & HRTIM_TIMER_TIMD ? HRTIM_CR2_TDRST : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIME regval |= (timer & HRTIM_TIMER_TIME ? HRTIM_CR2_TERST : 0); #endif /* Bits in HRTIM CR2 common register are automatically reset, * so we can just write to it. */ hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_CR2_OFFSET, regval); return OK; } /**************************************************************************** * Name: hrtim_tim_freq_set * * Description: * Set HRTIM Timer frequency * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_tim_freq_set(FAR struct hrtim_dev_s *dev, uint8_t timer, uint64_t freq) { uint64_t per = 0; uint64_t fclk = 0; int ret = OK; /* Get Timer period value for given frequency */ fclk = HRTIM_FCLK_GET(dev, timer); per = fclk / freq; if (per > HRTIM_PER_MAX) { tmrerr("ERROR: can not achieve timer pwm " "freq=%" PRIu64 " if fclk=%" PRIu64 "\n", freq, fclk); ret = -EINVAL; goto errout; } /* Set Timer period value */ HRTIM_PER_SET(dev, timer, (uint16_t)per); errout: return ret; } /**************************************************************************** * Name: hrtim_tim_enable * * Description: * Enable/disable HRTIM timer counter (bulk operation) * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_tim_enable(FAR struct hrtim_dev_s *dev, uint8_t timers, bool state) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; uint32_t regval = 0; regval |= (timers & HRTIM_TIMERS_MASK) << HRTIM_MCR_TCEN_SHIFT; if (state == true) { /* Set bits */ hrtim_tim_modifyreg(priv, HRTIM_TIMER_MASTER, STM32_HRTIM_TIM_CR_OFFSET, 0, regval); } else { /* Clear bits */ hrtim_tim_modifyreg(priv, HRTIM_TIMER_MASTER, STM32_HRTIM_TIM_CR_OFFSET, regval, 0); } return OK; } /**************************************************************************** * Name: hrtim_tim_reset_set * * Description: * Set HRTIM Timer Reset events * * Input Parameters: * priv - A reference to the HRTIM block * timer - HRTIM Timer index * reset - Reset configuration * * Returned Value: * Zero on success; a negated errno value on failure * ****************************************************************************/ static int hrtim_tim_reset_set(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint64_t reset) { int ret = OK; uint32_t regval = 0; /* Sanity checking */ if (timer == HRTIM_TIMER_MASTER || timer == HRTIM_TIMER_COMMON) { ret = -EINVAL; goto errout; } /* First 18 bits can be written directly */ regval |= (reset & 0x3ffff); /* TimerX reset events differ for individual timers */ switch (timer) { #ifdef CONFIG_STM32_HRTIM_TIMA case HRTIM_TIMER_TIMA: { regval |= ((reset & HRTIM_RST_TBCMP1) ? HRTIM_TIMARST_TIMBCMP1 : 0); regval |= ((reset & HRTIM_RST_TBCMP2) ? HRTIM_TIMARST_TIMBCMP2 : 0); regval |= ((reset & HRTIM_RST_TBCMP4) ? HRTIM_TIMARST_TIMBCMP4 : 0); regval |= ((reset & HRTIM_RST_TCCMP1) ? HRTIM_TIMARST_TIMCCMP1 : 0); regval |= ((reset & HRTIM_RST_TCCMP2) ? HRTIM_TIMARST_TIMCCMP2 : 0); regval |= ((reset & HRTIM_RST_TCCMP4) ? HRTIM_TIMARST_TIMCCMP4 : 0); regval |= ((reset & HRTIM_RST_TDCMP1) ? HRTIM_TIMARST_TIMDCMP1 : 0); regval |= ((reset & HRTIM_RST_TDCMP2) ? HRTIM_TIMARST_TIMDCMP2 : 0); regval |= ((reset & HRTIM_RST_TDCMP4) ? HRTIM_TIMARST_TIMDCMP4 : 0); regval |= ((reset & HRTIM_RST_TECMP1) ? HRTIM_TIMARST_TIMECMP1 : 0); regval |= ((reset & HRTIM_RST_TECMP2) ? HRTIM_TIMARST_TIMECMP2 : 0); regval |= ((reset & HRTIM_RST_TECMP4) ? HRTIM_TIMARST_TIMECMP4 : 0); break; } #endif #ifdef CONFIG_STM32_HRTIM_TIMB case HRTIM_TIMER_TIMB: { regval |= ((reset & HRTIM_RST_TACMP1) ? HRTIM_TIMBRST_TIMACMP1 : 0); regval |= ((reset & HRTIM_RST_TACMP2) ? HRTIM_TIMBRST_TIMACMP2 : 0); regval |= ((reset & HRTIM_RST_TACMP4) ? HRTIM_TIMBRST_TIMACMP4 : 0); regval |= ((reset & HRTIM_RST_TCCMP1) ? HRTIM_TIMBRST_TIMCCMP1 : 0); regval |= ((reset & HRTIM_RST_TCCMP2) ? HRTIM_TIMBRST_TIMCCMP2 : 0); regval |= ((reset & HRTIM_RST_TCCMP4) ? HRTIM_TIMBRST_TIMCCMP4 : 0); regval |= ((reset & HRTIM_RST_TDCMP1) ? HRTIM_TIMBRST_TIMDCMP1 : 0); regval |= ((reset & HRTIM_RST_TDCMP2) ? HRTIM_TIMBRST_TIMDCMP2 : 0); regval |= ((reset & HRTIM_RST_TDCMP4) ? HRTIM_TIMBRST_TIMDCMP4 : 0); regval |= ((reset & HRTIM_RST_TECMP1) ? HRTIM_TIMBRST_TIMECMP1 : 0); regval |= ((reset & HRTIM_RST_TECMP2) ? HRTIM_TIMBRST_TIMECMP2 : 0); regval |= ((reset & HRTIM_RST_TECMP4) ? HRTIM_TIMBRST_TIMECMP4 : 0); break; } #endif #ifdef CONFIG_STM32_HRTIM_TIMC case HRTIM_TIMER_TIMC: { regval |= ((reset & HRTIM_RST_TACMP1) ? HRTIM_TIMCRST_TIMACMP1 : 0); regval |= ((reset & HRTIM_RST_TACMP2) ? HRTIM_TIMCRST_TIMACMP2 : 0); regval |= ((reset & HRTIM_RST_TACMP4) ? HRTIM_TIMCRST_TIMACMP4 : 0); regval |= ((reset & HRTIM_RST_TBCMP1) ? HRTIM_TIMCRST_TIMBCMP1 : 0); regval |= ((reset & HRTIM_RST_TBCMP2) ? HRTIM_TIMCRST_TIMBCMP2 : 0); regval |= ((reset & HRTIM_RST_TBCMP4) ? HRTIM_TIMCRST_TIMBCMP4 : 0); regval |= ((reset & HRTIM_RST_TDCMP1) ? HRTIM_TIMCRST_TIMDCMP1 : 0); regval |= ((reset & HRTIM_RST_TDCMP2) ? HRTIM_TIMCRST_TIMDCMP2 : 0); regval |= ((reset & HRTIM_RST_TDCMP4) ? HRTIM_TIMCRST_TIMDCMP4 : 0); regval |= ((reset & HRTIM_RST_TECMP1) ? HRTIM_TIMCRST_TIMECMP1 : 0); regval |= ((reset & HRTIM_RST_TECMP2) ? HRTIM_TIMCRST_TIMECMP2 : 0); regval |= ((reset & HRTIM_RST_TECMP4) ? HRTIM_TIMCRST_TIMECMP4 : 0); break; } #endif #ifdef CONFIG_STM32_HRTIM_TIMD case HRTIM_TIMER_TIMD: { regval |= ((reset & HRTIM_RST_TACMP1) ? HRTIM_TIMDRST_TIMACMP1 : 0); regval |= ((reset & HRTIM_RST_TACMP2) ? HRTIM_TIMDRST_TIMACMP2 : 0); regval |= ((reset & HRTIM_RST_TACMP4) ? HRTIM_TIMDRST_TIMACMP4 : 0); regval |= ((reset & HRTIM_RST_TBCMP1) ? HRTIM_TIMDRST_TIMBCMP1 : 0); regval |= ((reset & HRTIM_RST_TBCMP2) ? HRTIM_TIMDRST_TIMBCMP2 : 0); regval |= ((reset & HRTIM_RST_TBCMP4) ? HRTIM_TIMDRST_TIMBCMP4 : 0); regval |= ((reset & HRTIM_RST_TCCMP1) ? HRTIM_TIMDRST_TIMCCMP1 : 0); regval |= ((reset & HRTIM_RST_TCCMP2) ? HRTIM_TIMDRST_TIMCCMP2 : 0); regval |= ((reset & HRTIM_RST_TCCMP4) ? HRTIM_TIMDRST_TIMCCMP4 : 0); regval |= ((reset & HRTIM_RST_TECMP1) ? HRTIM_TIMDRST_TIMECMP1 : 0); regval |= ((reset & HRTIM_RST_TECMP2) ? HRTIM_TIMDRST_TIMECMP2 : 0); regval |= ((reset & HRTIM_RST_TECMP4) ? HRTIM_TIMDRST_TIMECMP4 : 0); break; } #endif #ifdef CONFIG_STM32_HRTIM_TIME case HRTIM_TIMER_TIME: { regval |= ((reset & HRTIM_RST_TACMP1) ? HRTIM_TIMERST_TIMACMP1 : 0); regval |= ((reset & HRTIM_RST_TACMP2) ? HRTIM_TIMERST_TIMACMP2 : 0); regval |= ((reset & HRTIM_RST_TACMP4) ? HRTIM_TIMERST_TIMACMP4 : 0); regval |= ((reset & HRTIM_RST_TBCMP1) ? HRTIM_TIMERST_TIMBCMP1 : 0); regval |= ((reset & HRTIM_RST_TBCMP2) ? HRTIM_TIMERST_TIMBCMP2 : 0); regval |= ((reset & HRTIM_RST_TBCMP4) ? HRTIM_TIMERST_TIMBCMP4 : 0); regval |= ((reset & HRTIM_RST_TCCMP1) ? HRTIM_TIMERST_TIMCCMP1 : 0); regval |= ((reset & HRTIM_RST_TCCMP2) ? HRTIM_TIMERST_TIMCCMP2 : 0); regval |= ((reset & HRTIM_RST_TCCMP4) ? HRTIM_TIMERST_TIMCCMP4 : 0); regval |= ((reset & HRTIM_RST_TDCMP1) ? HRTIM_TIMERST_TIMDCMP1 : 0); regval |= ((reset & HRTIM_RST_TDCMP2) ? HRTIM_TIMERST_TIMDCMP2 : 0); regval |= ((reset & HRTIM_RST_TDCMP4) ? HRTIM_TIMERST_TIMDCMP4 : 0); break; } #endif default: { ret = -EINVAL; goto errout; } } hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_RSTR_OFFSET, regval); errout: return ret; } static int hrtim_reset_config(FAR struct stm32_hrtim_s *priv) { FAR struct stm32_hrtim_slave_priv_s *slave; #ifdef CONFIG_STM32_HRTIM_TIMA slave = (struct stm32_hrtim_slave_priv_s *)priv->tima->priv; hrtim_tim_reset_set(priv, HRTIM_TIMER_TIMA, slave->reset); #endif #ifdef CONFIG_STM32_HRTIM_TIMB slave = (struct stm32_hrtim_slave_priv_s *)priv->timb->priv; hrtim_tim_reset_set(priv, HRTIM_TIMER_TIMB, slave->reset); #endif #ifdef CONFIG_STM32_HRTIM_TIMC slave = (struct stm32_hrtim_slave_priv_s *)priv->timc->priv; hrtim_tim_reset_set(priv, HRTIM_TIMER_TIMC, slave->reset); #endif #ifdef CONFIG_STM32_HRTIM_TIMD slave = (struct stm32_hrtim_slave_priv_s *)priv->timd->priv; hrtim_tim_reset_set(priv, HRTIM_TIMER_TIMD, slave->reset); #endif #ifdef CONFIG_STM32_HRTIM_TIME slave = (struct stm32_hrtim_slave_priv_s *)priv->time->priv; hrtim_tim_reset_set(priv, HRTIM_TIMER_TIME, slave->reset); #endif return OK; } static int hrtim_tim_update_set(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint16_t update) { uint32_t regval = 0; regval = hrtim_tim_getreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET); /* Configure update events */ regval |= (update & HRTIM_UPDATE_MSTU ? HRTIM_TIMCR_MSTU : 0); regval |= (update & HRTIM_UPDATE_RSTU ? HRTIM_TIMCR_RSTU : 0); regval |= (update & HRTIM_UPDATE_REPU ? HRTIM_TIMCR_REPU : 0); #ifdef CONFIG_STM32_HRTIM_TIMA regval |= (update & HRTIM_UPDATE_TAU ? HRTIM_TIMCR_TAU : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIMB regval |= (update & HRTIM_UPDATE_TBU ? HRTIM_TIMCR_TBU : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIMC regval |= (update & HRTIM_UPDATE_TCU ? HRTIM_TIMCR_TCU : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIMD regval |= (update & HRTIM_UPDATE_TDU ? HRTIM_TIMCR_TDU : 0); #endif #ifdef CONFIG_STM32_HRTIM_TIME regval |= (update & HRTIM_UPDATE_TEU ? HRTIM_TIMCR_TEU : 0); #endif /* TODO: Configure update gating */ /* Write register */ hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_CR_OFFSET, regval); return OK; } static int hrtim_update_config(FAR struct stm32_hrtim_s *priv) { FAR struct stm32_hrtim_slave_priv_s *slave; #ifdef CONFIG_STM32_HRTIM_TIMA slave = (struct stm32_hrtim_slave_priv_s *)priv->tima->priv; hrtim_tim_update_set(priv, HRTIM_TIMER_TIMA, slave->update); #endif #ifdef CONFIG_STM32_HRTIM_TIMB slave = (struct stm32_hrtim_slave_priv_s *)priv->timb->priv; hrtim_tim_update_set(priv, HRTIM_TIMER_TIMB, slave->update); #endif #ifdef CONFIG_STM32_HRTIM_TIMC slave = (struct stm32_hrtim_slave_priv_s *)priv->timc->priv; hrtim_tim_update_set(priv, HRTIM_TIMER_TIMC, slave->update); #endif #ifdef CONFIG_STM32_HRTIM_TIMD slave = (struct stm32_hrtim_slave_priv_s *)priv->timd->priv; hrtim_tim_update_set(priv, HRTIM_TIMER_TIMD, slave->update); #endif #ifdef CONFIG_STM32_HRTIM_TIME slave = (struct stm32_hrtim_slave_priv_s *)priv->time->priv; hrtim_tim_update_set(priv, HRTIM_TIMER_TIME, slave->update); #endif return OK; } /**************************************************************************** * Name: stm32_hrtimconfig * * Description: * Configure HRTIM * * Input Parameters: * priv - A reference to the HRTIM structure * * Returned Value: * 0 on success, a negated errno value on failure * ****************************************************************************/ static int stm32_hrtimconfig(FAR struct stm32_hrtim_s *priv) { int ret; uint32_t regval = 0; /* HRTIM DLL calibration */ ret = hrtim_dll_cal(priv); if (ret != OK) { tmrerr("ERROR: HRTIM DLL calibration failed!\n"); goto errout; } /* Configure Timers Clocks */ ret = hrtim_tim_clocks_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM timers clock configuration failed!\n"); goto errout; } /* Configure Timers reset events */ hrtim_reset_config(priv); /* Configure Timers update events */ hrtim_update_config(priv); /* Configure Timers mode */ hrtim_mode_config(priv); /* Configure auto-delayed mode */ #ifdef CONFIG_STM32_HRTIM_AUTODELAYED hrtim_autodelayed_config(priv); #endif /* Configure HRTIM GPIOs */ #if defined(CONFIG_STM32_HRTIM_PWM) || defined(CONFIG_STM32_HRTIM_SYNC) ret = hrtim_gpios_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM GPIOs configuration failed!\n"); goto errout; } #endif /* Configure HRTIM capture */ #if defined(CONFIG_STM32_HRTIM_CAPTURE) ret = hrtim_capture_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM capture configuration failed!\n"); goto errout; } #endif /* Configure Synchronisation IOs */ #if defined(CONFIG_STM32_HRTIM_SYNC) ret = hrtim_synch_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM synchronisation configuration failed!\n"); goto errout; } #endif /* Configure HRTIM outputs deadtime */ #if defined(CONFIG_STM32_HRTIM_DEADTIME) ret = hrtim_deadtime_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM deadtime configuration failed!\n"); goto errout; } #endif /* Configure HRTIM outputs GPIOs */ #if defined(CONFIG_STM32_HRTIM_PWM) ret = hrtim_outputs_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM outputs configuration failed!\n"); goto errout; } #endif /* Configure ADC triggers */ #ifdef HRTIM_HAVE_ADC ret = hrtim_adc_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM ADC configuration failed!\n"); goto errout; } #endif /* Configure DAC synchronization */ #ifdef CONFIG_STM32_HRTIM_DAC ret = hrtim_dac_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM ADC configuration failed!\n"); goto errout; } #endif /* Configure Faults */ #ifdef CONFIG_STM32_HRTIM_FAULTS ret = hrtim_faults_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM faults configuration failed!\n"); goto errout; } #endif /* Configure External Events */ #ifdef CONFIG_STM32_HRTIM_EVENTS ret = hrtim_events_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM EEV configuration failed!\n"); goto errout; } #endif /* Configure interrupts */ #ifdef CONFIG_STM32_HRTIM_INTERRUPTS ret = hrtim_irq_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM IRQ configuration failed!\n"); goto errout; } #endif /* Configure DMA */ #ifdef CONFIG_STM32_HRTIM_DMA ret = hrtim_dma_cfg(priv); if (ret != OK) { tmrerr("ERROR: HRTIM DMA configuration failed!\n"); goto errout; } #endif /* Configure burst mode */ #ifdef CONFIG_STM32_HRTIM_BURST ret = hrtim_burst_config(priv); if (ret != OK) { tmrerr("ERROR: HRTIM burst mode configuration failed!\n"); goto errout; } #endif #ifndef CONFIG_STM32_HRTIM_NO_ENABLE_TIMERS /* Enable Master Timer */ # ifdef CONFIG_STM32_HRTIM_MASTER regval |= HRTIM_MCR_MCEN; # endif /* Enable Slave Timers */ # ifdef CONFIG_STM32_HRTIM_TIMA regval |= HRTIM_MCR_TACEN; # endif # ifdef CONFIG_STM32_HRTIM_TIMB regval |= HRTIM_MCR_TBCEN; # endif # ifdef CONFIG_STM32_HRTIM_TIMC regval |= HRTIM_MCR_TCCEN; # endif # ifdef CONFIG_STM32_HRTIM_TIMD regval |= HRTIM_MCR_TDCEN; # endif # ifdef CONFIG_STM32_HRTIM_TIME regval |= HRTIM_MCR_TECEN; # endif #endif /* CONFIG_STM32_HRTIM_NO_ENABLE_TIMERS */ /* Write enable bits at once */ hrtim_tim_modifyreg(priv, HRTIM_TIMER_MASTER, STM32_HRTIM_TIM_CR_OFFSET, 0, regval); /* Dump registers for Master */ hrtim_dumpregs(priv, HRTIM_TIMER_MASTER, "Master after configuration"); /* Dump registers for Timer A */ #ifdef CONFIG_STM32_HRTIM_TIMA hrtim_dumpregs(priv, HRTIM_TIMER_TIMA, "Timer A after configuration"); #endif /* Dump registers for Timer B */ #ifdef CONFIG_STM32_HRTIM_TIMB hrtim_dumpregs(priv, HRTIM_TIMER_TIMB, "Timer B after configuration"); #endif /* Dump registers for Timer C */ #ifdef CONFIG_STM32_HRTIM_TIMC hrtim_dumpregs(priv, HRTIM_TIMER_TIMC, "Timer C after configuration"); #endif /* Dump registers for Timer D */ #ifdef CONFIG_STM32_HRTIM_TIMD hrtim_dumpregs(priv, HRTIM_TIMER_TIMD, "Timer D after configuration"); #endif /* Dump registers for Timer E */ #ifdef CONFIG_STM32_HRTIM_TIME hrtim_dumpregs(priv, HRTIM_TIMER_TIME, "Timer E after configuration"); #endif /* Dump common registers */ hrtim_dumpregs(priv, HRTIM_TIMER_COMMON, "Common after configuration"); errout: return ret; } /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: stm32_hrtiminitialize * * Description: * Initialize the HRTIM. * * Returned Value: * Valid HRTIM device structure reference on success; a NULL on failure. * * Assumptions: * 1. Clock to the HRTIM block has enabled, * 2. Board-specific logic has already configured * ****************************************************************************/ FAR struct hrtim_dev_s *stm32_hrtiminitialize(void) { FAR struct hrtim_dev_s *dev; FAR struct stm32_hrtim_s *hrtim; int ret; dev = &g_hrtim1dev; hrtim = dev->hd_priv; /* configure HRTIM only once */ if (!dev->initialized) { ret = stm32_hrtimconfig(hrtim); if (ret < 0) { tmrerr("ERROR: Failed to initialize HRTIM1: %d\n", ret); return NULL; } dev->initialized = true; } return dev; } /**************************************************************************** * Name: hrtim_register ****************************************************************************/ #ifndef CONFIG_STM32_HRTIM_DISABLE_CHARDRV int hrtim_register(FAR const char *path, FAR struct hrtim_dev_s *dev) { int ret ; /* Initialize the HRTIM device structure */ dev->hd_ocount = 0; /* Initialize semaphores */ nxsem_init(&dev->hd_closesem, 0, 1); /* Register the HRTIM character driver */ ret = register_driver(path, &hrtim_fops, 0444, dev); if (ret < 0) { nxsem_destroy(&dev->hd_closesem); } return ret; } #endif /* CONFIG_STM32_HRTIM_DISABLE_CHARDRV */ #endif /* CONFIG_STM32_STM32F33XX */ #endif /* CONFIG_STM32_HRTIM1 */