From 35e0e1fadc8dea1d85f993a210e0837492f0d20a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20=C5=BDaitl=C3=ADk?= Date: Mon, 19 Jul 2021 11:55:05 +0200 Subject: [PATCH 1/2] Created timer for measurement and base for UART. Polished main a bit. --- fw/.mxproject | 18 +- fw/Core/Inc/main.h | 12 +- fw/Core/Inc/sps30.h | 2 +- fw/Core/Inc/stm32l0xx_it.h | 5 +- fw/Core/Src/main.c | 226 +- fw/Core/Src/sps30.c | 2 +- fw/Core/Src/stm32l0xx_it.c | 59 +- .../Inc/stm32l0xx_ll_tim.h | 3289 +++++++++++++++++ .../Inc/stm32l0xx_ll_utils.h | 1 - .../Src/stm32l0xx_ll_tim.c | 847 +++++ fw/iaq_wired_sensor.ioc | 101 +- 11 files changed, 4431 insertions(+), 131 deletions(-) create mode 100644 fw/Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h create mode 100644 fw/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c diff --git a/fw/.mxproject b/fw/.mxproject index ad2456a..4d4db74 100644 --- a/fw/.mxproject +++ b/fw/.mxproject @@ -1,24 +1,24 @@ [PreviousLibFiles] -LibFiles=Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_lpuart.h;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_lpuart.c;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_lpuart.h;Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l011xx.h;Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h;Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h;Drivers/CMSIS/Device/ST/STM32L0xx/Source/Templates/system_stm32l0xx.c;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_armv8mbl.h; +LibFiles=Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_lpuart.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_lpuart.c;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_lpuart.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h;Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l011xx.h;Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h;Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h;Drivers/CMSIS/Device/ST/STM32L0xx/Source/Templates/system_stm32l0xx.c;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_cm3.h; [PreviousUsedCubeIDEFiles] -SourceFiles=Core/Src/main.c;Core/Src/stm32l0xx_it.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_lpuart.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c;Core/Src/system_stm32l0xx.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_lpuart.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c;Core/Src/system_stm32l0xx.c;Drivers/CMSIS/Device/ST/STM32L0xx/Source/Templates/system_stm32l0xx.c;; +SourceFiles=Core/Src/main.c;Core/Src/stm32l0xx_it.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_lpuart.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c;Core/Src/system_stm32l0xx.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_lpuart.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c;Core/Src/system_stm32l0xx.c;Drivers/CMSIS/Device/ST/STM32L0xx/Source/Templates/system_stm32l0xx.c;; HeaderPath=Drivers/STM32L0xx_HAL_Driver/Inc;Drivers/CMSIS/Device/ST/STM32L0xx/Include;Drivers/CMSIS/Include;Core/Inc; CDefines=USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;MSI_VALUE:2097000;HSI_VALUE:16000000;LSI_VALUE:37000;VDD_VALUE:3300;PREFETCH_ENABLE:0;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;STM32L011xx;USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;MSI_VALUE:2097000;HSI_VALUE:16000000;LSI_VALUE:37000;VDD_VALUE:3300;PREFETCH_ENABLE:0;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1; [PreviousGenFiles] AdvancedFolderStructure=true HeaderFileListSize=3 -HeaderFiles#0=/home/david/Personal/Projects/HDIoT/Smart_Household/Wired_Sensors/iaq_wired_sensor/fw/Core/Inc/stm32l0xx_it.h -HeaderFiles#1=/home/david/Personal/Projects/HDIoT/Smart_Household/Wired_Sensors/iaq_wired_sensor/fw/Core/Inc/stm32_assert.h -HeaderFiles#2=/home/david/Personal/Projects/HDIoT/Smart_Household/Wired_Sensors/iaq_wired_sensor/fw/Core/Inc/main.h +HeaderFiles#0=/home/mrs/Personal/HDIoT/Smart_Household/iaq_wired_sensor/fw/Core/Inc/stm32l0xx_it.h +HeaderFiles#1=/home/mrs/Personal/HDIoT/Smart_Household/iaq_wired_sensor/fw/Core/Inc/stm32_assert.h +HeaderFiles#2=/home/mrs/Personal/HDIoT/Smart_Household/iaq_wired_sensor/fw/Core/Inc/main.h HeaderFolderListSize=1 -HeaderPath#0=/home/david/Personal/Projects/HDIoT/Smart_Household/Wired_Sensors/iaq_wired_sensor/fw/Core/Inc +HeaderPath#0=/home/mrs/Personal/HDIoT/Smart_Household/iaq_wired_sensor/fw/Core/Inc HeaderFiles=; SourceFileListSize=2 -SourceFiles#0=/home/david/Personal/Projects/HDIoT/Smart_Household/Wired_Sensors/iaq_wired_sensor/fw/Core/Src/stm32l0xx_it.c -SourceFiles#1=/home/david/Personal/Projects/HDIoT/Smart_Household/Wired_Sensors/iaq_wired_sensor/fw/Core/Src/main.c +SourceFiles#0=/home/mrs/Personal/HDIoT/Smart_Household/iaq_wired_sensor/fw/Core/Src/stm32l0xx_it.c +SourceFiles#1=/home/mrs/Personal/HDIoT/Smart_Household/iaq_wired_sensor/fw/Core/Src/main.c SourceFolderListSize=1 -SourcePath#0=/home/david/Personal/Projects/HDIoT/Smart_Household/Wired_Sensors/iaq_wired_sensor/fw/Core/Src +SourcePath#0=/home/mrs/Personal/HDIoT/Smart_Household/iaq_wired_sensor/fw/Core/Src SourceFiles=; diff --git a/fw/Core/Inc/main.h b/fw/Core/Inc/main.h index f42443b..9172851 100644 --- a/fw/Core/Inc/main.h +++ b/fw/Core/Inc/main.h @@ -28,8 +28,6 @@ extern "C" { #endif /* Includes ------------------------------------------------------------------*/ -#include "stm32l0xx_ll_dma.h" -#include "stm32l0xx.h" #include "stm32l0xx_ll_i2c.h" #include "stm32l0xx_ll_lpuart.h" #include "stm32l0xx_ll_rcc.h" @@ -40,6 +38,8 @@ extern "C" { #include "stm32l0xx_ll_cortex.h" #include "stm32l0xx_ll_utils.h" #include "stm32l0xx_ll_pwr.h" +#include "stm32l0xx_ll_dma.h" +#include "stm32l0xx_ll_tim.h" #include "stm32l0xx_ll_gpio.h" #if defined(USE_FULL_ASSERT) @@ -51,6 +51,7 @@ extern "C" { #include "i2c.h" #include "scd4x.h" #include "sht4x.h" +#include "sps30.h" /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ @@ -95,7 +96,14 @@ void Error_Handler(void); 0 bit for subpriority */ #endif /* USER CODE BEGIN Private defines */ +#define MEASUREMENT_PERIOD_MS 600000 +extern uint8_t lpuart1_rx_message[255]; +extern uint8_t lpuart1_rx_message_index; +extern uint8_t lpuart1_rx_message_len; +extern uint8_t lpuart1_rx_done; + +extern uint8_t tim21_elapsed_period; /* USER CODE END Private defines */ #ifdef __cplusplus diff --git a/fw/Core/Inc/sps30.h b/fw/Core/Inc/sps30.h index 140b228..9ca3c45 100644 --- a/fw/Core/Inc/sps30.h +++ b/fw/Core/Inc/sps30.h @@ -73,6 +73,6 @@ int8_t sps30_read_status_register ( void ); int8_t sps30_read_firmware_version ( uint8_t * fw_ver_hi, uint8_t * fw_ver_lo ); -static uint8_t calculate_crc(uint8_t data[2]); +uint8_t calculate_crc(uint8_t data[2]); #endif /* INC_SPS30_H_ */ diff --git a/fw/Core/Inc/stm32l0xx_it.h b/fw/Core/Inc/stm32l0xx_it.h index 5212081..e4fecd6 100644 --- a/fw/Core/Inc/stm32l0xx_it.h +++ b/fw/Core/Inc/stm32l0xx_it.h @@ -38,7 +38,6 @@ /* Exported constants --------------------------------------------------------*/ /* USER CODE BEGIN EC */ - /* USER CODE END EC */ /* Exported macro ------------------------------------------------------------*/ @@ -52,9 +51,9 @@ void HardFault_Handler(void); void SVC_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); -void DMA1_Channel2_3_IRQHandler(void); +void TIM21_IRQHandler(void); +void LPUART1_IRQHandler(void); /* USER CODE BEGIN EFP */ - /* USER CODE END EFP */ #ifdef __cplusplus diff --git a/fw/Core/Src/main.c b/fw/Core/Src/main.c index bfcf26d..262d0d4 100644 --- a/fw/Core/Src/main.c +++ b/fw/Core/Src/main.c @@ -42,15 +42,22 @@ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ - +/* + * BASE CLOCK 12MHz + * Desired interrupt period 60s + */ +const uint16_t tim21_prescaler = 60000-1; // 100Hz +const uint16_t tim21_period = 12000-1; // 60s +//const uint16_t tim21_period = 1200-1; // 6s +//const uint16_t tim21_period = 200-1; // 1s /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); -static void MX_DMA_Init(void); static void MX_I2C1_Init(void); static void MX_LPUART1_UART_Init(void); +static void MX_TIM21_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -92,12 +99,21 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); - MX_DMA_Init(); MX_I2C1_Init(); MX_LPUART1_UART_Init(); + MX_TIM21_Init(); /* USER CODE BEGIN 2 */ + /* Enable I2C for sensors */ LL_I2C_Enable(I2C1); + + /* Enable UART for RS485 */ LL_LPUART_Enable(LPUART1); + + /* Start the timer for measurement triggering */ + LL_TIM_EnableCounter(TIM21); + LL_TIM_EnableIT_UPDATE(TIM21); + /*LL_TIM_GenerateEvent_UPDATE(TIM2);*/ + /* I2C context init (for SHT4x and SCD4x) */ i2c_context_t i2c_context; i2c_context.i2c = I2C1; @@ -107,47 +123,100 @@ int main(void) /* Infinite loop */ /* USER CODE BEGIN WHILE */ - uint8_t uart_data_dummy = 0; - //scd4x_perform_factory_reset(); - //LL_mDelay(2000); - scd4x_start_periodic_measurement(); - - uint8_t sps30_fw_v_hi, sps30_fw_v_lo; - - sps30_read_firmware_version(&sps30_fw_v_hi, &sps30_fw_v_lo); + uint8_t scd4x_is_connected = 0; + if (scd4x_start_periodic_measurement() == SCD4X_OK) + { + scd4x_is_connected = 1; + } + /* Attempt to start SPS30 measurement and check if it's connected */ sps30_reset(); - sps30_start_measurement(); - LL_mDelay(2000); + uint8_t sps30_is_connected = 0; + if (sps30_start_measurement() == SPS30_OK) + { + sps30_is_connected = 1; + } + + /* Variables to store the measured data */ int CO2, T_SCD4x, RH_SCD4x; int T_SHT4x, RH_SHT4x; uint16_t sps30_measured_data[10]; - /* - sps30_start_fan_cleaning(); - LL_mDelay(15000); - */ + /* Wait 1000ms for sensors initialization */ + /* SHT4x Init Time: max 1 ms (datasheet pg. 8) */ + /* SCD4x Init Time: max 1000 ms (datasheet pg. 6) */ + /* SPS30 Init Time: max 30000 ms (datasheet pg. 2) */ + LL_mDelay(1000); + + /* Turn on LED to signal ready state */ + LL_GPIO_ResetOutputPin(LED_B_GPIO_Port, LED_B_Pin); + + /* Enter the main loop */ while (1) { + /* UART RX is done */ + if (lpuart1_rx_done == 1) + { + /* Process the message */ + /* process_modbus_message(lpuart1_rx_message, lpuart1_rx_message_len); */ + + /* Reset the RX DONE flag */ + lpuart1_rx_done = 0; + } + + /* It is time for measurement */ + if (tim21_elapsed_period == 1) + { + /* TODO: Check the data */ + /* Read SHT4x data (always connected) */ + sht4x_measure(&T_SHT4x, &RH_SHT4x); + + /* Read SCD4x data (if connected) */ + if (scd4x_is_connected == 1) + { + scd4x_read_measurement(&CO2, &T_SCD4x, &RH_SCD4x); + } + + /* Read SPS30 data (if connected) */ + if (sps30_is_connected == 1) + { + sps30_read_measured_values(sps30_measured_data, 10); + } + + /* Toggle LED for now */ + /* TODO: Remove LED Toggle */ + LL_GPIO_TogglePin(LED_B_GPIO_Port, LED_B_Pin); + + /* TODO: Process data and light a desired color of LED */ + + /* Reset the TIM21 Elapsed Period Flag */ + tim21_elapsed_period = 0; + } + /* TEST START */ + /* TODO: DELETE TEST */ + /* RS485 test */ /*LL_LPUART_SetDESignalPolarity(LPUART1, 1); LL_LPUART_TransmitData8(LPUART1, uart_data_dummy); uart_data_dummy++;*/ /* SHT41 measurement */ - sht4x_measure(&T_SHT4x, &RH_SHT4x); - LL_mDelay(10); + /*sht4x_measure(&T_SHT4x, &RH_SHT4x); + LL_mDelay(10);*/ /* SCD4x measurement */ - scd4x_read_measurement(&CO2, &T_SCD4x, &RH_SCD4x); - LL_mDelay(10); + /*scd4x_read_measurement(&CO2, &T_SCD4x, &RH_SCD4x); + LL_mDelay(10);*/ /* SPS30 measurement*/ - sps30_read_measured_values(sps30_measured_data, 10); + /*sps30_read_measured_values(sps30_measured_data, 10);*/ /* SLEEP */ - LL_mDelay(1000); + /*LL_mDelay(1000);*/ + + /* TEST END */ /* USER CODE END WHILE */ + /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ @@ -164,29 +233,36 @@ void SystemClock_Config(void) { } LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); - LL_RCC_MSI_Enable(); + LL_RCC_HSI_Enable(); - /* Wait till MSI is ready */ - while(LL_RCC_MSI_IsReady() != 1) + /* Wait till HSI is ready */ + while(LL_RCC_HSI_IsReady() != 1) + { + + } + LL_RCC_HSI_SetCalibTrimming(16); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLL_MUL_3, LL_RCC_PLL_DIV_4); + LL_RCC_PLL_Enable(); + + /* Wait till PLL is ready */ + while(LL_RCC_PLL_IsReady() != 1) { } - LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_5); - LL_RCC_MSI_SetCalibTrimming(0); LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); - LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI); + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); /* Wait till System clock is ready */ - while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) + while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { } - LL_Init1msTick(2097000); + LL_Init1msTick(12000000); - LL_SetSystemCoreClock(2097000); + LL_SetSystemCoreClock(12000000); LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1); LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); } @@ -241,7 +317,7 @@ static void MX_I2C1_Init(void) LL_I2C_DisableGeneralCall(I2C1); LL_I2C_EnableClockStretching(I2C1); I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; - I2C_InitStruct.Timing = 0x00000708; + I2C_InitStruct.Timing = 0x40000A0B; I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; I2C_InitStruct.DigitalFilter = 0; I2C_InitStruct.OwnAddress1 = 0; @@ -274,9 +350,11 @@ static void MX_LPUART1_UART_Init(void) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPUART1); LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); + LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB); /**LPUART1 GPIO Configuration PA0-CK_IN ------> LPUART1_RX PA1 ------> LPUART1_TX + PB1 ------> LPUART1_DE */ GPIO_InitStruct.Pin = LL_GPIO_PIN_0; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; @@ -294,55 +372,80 @@ static void MX_LPUART1_UART_Init(void) GPIO_InitStruct.Alternate = LL_GPIO_AF_6; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); - /* LPUART1 DMA Init */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_1; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_4; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); - /* LPUART1_RX Init */ - LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_3, LL_DMA_REQUEST_5); - - LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); - - LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PRIORITY_MEDIUM); - - LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_CIRCULAR); - - LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PERIPH_NOINCREMENT); - - LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MEMORY_INCREMENT); - - LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PDATAALIGN_BYTE); - - LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MDATAALIGN_BYTE); + /* LPUART1 interrupt Init */ + NVIC_SetPriority(LPUART1_IRQn, 0); + NVIC_EnableIRQ(LPUART1_IRQn); /* USER CODE BEGIN LPUART1_Init 1 */ /* USER CODE END LPUART1_Init 1 */ LPUART_InitStruct.BaudRate = 115200; - LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B; + LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_9B; LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1; - LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE; + LPUART_InitStruct.Parity = LL_LPUART_PARITY_EVEN; LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX; LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; LL_LPUART_Init(LPUART1, &LPUART_InitStruct); + LL_LPUART_EnableDEMode(LPUART1); + LL_LPUART_SetDESignalPolarity(LPUART1, LL_LPUART_DE_POLARITY_HIGH); + LL_LPUART_SetDEAssertionTime(LPUART1, 0); + LL_LPUART_SetDEDeassertionTime(LPUART1, 0); /* USER CODE BEGIN LPUART1_Init 2 */ + /* Enable IDLE Interrupt */ + LL_LPUART_EnableIT_IDLE(LPUART1); + + /* Enable RX Not Empty Interrupt */ + LL_LPUART_EnableIT_RXNE(LPUART1); + /* USER CODE END LPUART1_Init 2 */ } /** - * Enable DMA controller clock + * @brief TIM21 Initialization Function + * @param None + * @retval None */ -static void MX_DMA_Init(void) +static void MX_TIM21_Init(void) { - /* Init with LL driver */ - /* DMA controller clock enable */ - LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); + /* USER CODE BEGIN TIM21_Init 0 */ - /* DMA interrupt init */ - /* DMA1_Channel2_3_IRQn interrupt configuration */ - NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0); - NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); + /* USER CODE END TIM21_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM21); + + /* TIM21 interrupt Init */ + NVIC_SetPriority(TIM21_IRQn, 0); + NVIC_EnableIRQ(TIM21_IRQn); + + /* USER CODE BEGIN TIM21_Init 1 */ + + /* USER CODE END TIM21_Init 1 */ + TIM_InitStruct.Prescaler = tim21_prescaler; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = tim21_period; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM21, &TIM_InitStruct); + LL_TIM_EnableARRPreload(TIM21); + LL_TIM_SetClockSource(TIM21, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_SetTriggerOutput(TIM21, LL_TIM_TRGO_RESET); + LL_TIM_DisableMasterSlaveMode(TIM21); + /* USER CODE BEGIN TIM21_Init 2 */ + + /* USER CODE END TIM21_Init 2 */ } @@ -357,6 +460,7 @@ static void MX_GPIO_Init(void) /* GPIO Ports Clock Enable */ LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); + LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB); /**/ LL_GPIO_SetOutputPin(LED_B_GPIO_Port, LED_B_Pin); diff --git a/fw/Core/Src/sps30.c b/fw/Core/Src/sps30.c index b189a4c..c05a273 100644 --- a/fw/Core/Src/sps30.c +++ b/fw/Core/Src/sps30.c @@ -176,7 +176,7 @@ int8_t sps30_read_firmware_version ( uint8_t * fw_ver_hi, uint8_t * fw_ver_lo ) } -static uint8_t calculate_crc(uint8_t data[2]) +uint8_t calculate_crc(uint8_t data[2]) { uint8_t crc = 0xFF; for(uint8_t i = 0; i < 2; i++) { diff --git a/fw/Core/Src/stm32l0xx_it.c b/fw/Core/Src/stm32l0xx_it.c index b44f078..8e22949 100644 --- a/fw/Core/Src/stm32l0xx_it.c +++ b/fw/Core/Src/stm32l0xx_it.c @@ -42,12 +42,17 @@ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ +uint8_t lpuart1_rx_message[255]; +uint8_t lpuart1_rx_message_index = 0; +uint8_t lpuart1_rx_message_len = 0; +uint8_t lpuart1_rx_done = 0; +uint8_t tim21_elapsed_period = 0; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ - +void LPUART1_CharReception_Callback( void ); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ @@ -141,20 +146,58 @@ void SysTick_Handler(void) /******************************************************************************/ /** - * @brief This function handles DMA1 channel 2 and channel 3 interrupts. + * @brief This function handles TIM21 global interrupt. */ -void DMA1_Channel2_3_IRQHandler(void) +void TIM21_IRQHandler(void) { - /* USER CODE BEGIN DMA1_Channel2_3_IRQn 0 */ + /* USER CODE BEGIN TIM21_IRQn 0 */ + LL_TIM_ClearFlag_UPDATE(TIM21); + tim21_elapsed_period = 1; - /* USER CODE END DMA1_Channel2_3_IRQn 0 */ + /* USER CODE END TIM21_IRQn 0 */ + /* USER CODE BEGIN TIM21_IRQn 1 */ - /* USER CODE BEGIN DMA1_Channel2_3_IRQn 1 */ + /* USER CODE END TIM21_IRQn 1 */ +} - /* USER CODE END DMA1_Channel2_3_IRQn 1 */ +/** + * @brief This function handles LPUART1 global interrupt / LPUART1 wake-up interrupt through EXTI line 28. + */ +void LPUART1_IRQHandler(void) +{ + /* USER CODE BEGIN LPUART1_IRQn 0 */ + + + /* Check RXNE flag value in SR register */ + if(LL_LPUART_IsActiveFlag_RXNE(LPUART1) && LL_LPUART_IsEnabledIT_RXNE(LPUART1)) + { + /* RXNE flag will be cleared by reading of DR register (done in call) */ + /* Call function in charge of handling Character reception */ + LPUART1_CharReception_Callback(); + } + + /* USER CODE END LPUART1_IRQn 0 */ + /* USER CODE BEGIN LPUART1_IRQn 1 */ + /* If the IDLE flag is active */ + if (LL_LPUART_IsActiveFlag_IDLE(LPUART1) == 1) + { + /* Clear the IDLE flag */ + LL_LPUART_ClearFlag_IDLE(LPUART1); + + /* Reset the buffer index */ + lpuart1_rx_message_len = lpuart1_rx_message_index + 1; + lpuart1_rx_message_index = 0; + lpuart1_rx_done = 1; + } + /* USER CODE END LPUART1_IRQn 1 */ } /* USER CODE BEGIN 1 */ - +void LPUART1_CharReception_Callback( void ) +{ + uint16_t lpuart1_rx_bit = LL_LPUART_ReceiveData9(LPUART1); + lpuart1_rx_message[lpuart1_rx_message_index] = (uint8_t)lpuart1_rx_bit; + lpuart1_rx_message_index++; +} /* USER CODE END 1 */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/fw/Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h b/fw/Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h new file mode 100644 index 0000000..74d4271 --- /dev/null +++ b/fw/Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h @@ -0,0 +1,3289 @@ +/** + ****************************************************************************** + * @file stm32l0xx_ll_tim.h + * @author MCD Application Team + * @brief Header file of TIM LL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L0xx_LL_TIM_H +#define __STM32L0xx_LL_TIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l0xx.h" + +/** @addtogroup STM32L0xx_LL_Driver + * @{ + */ + +#if defined (TIM2) || defined (TIM3) || defined (TIM21) || defined (TIM22) || defined (TIM6) || defined (TIM7) + +/** @defgroup TIM_LL TIM + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Variables TIM Private Variables + * @{ + */ +static const uint8_t OFFSET_TAB_CCMRx[] = +{ + 0x00U, /* 0: TIMx_CH1 */ + 0x00U, /* 1: NA */ + 0x00U, /* 2: TIMx_CH2 */ + 0x00U, /* 3: NA */ + 0x04U, /* 4: TIMx_CH3 */ + 0x00U, /* 5: NA */ + 0x04U /* 6: TIMx_CH4 */ +}; + +static const uint8_t SHIFT_TAB_OCxx[] = +{ + 0U, /* 0: OC1M, OC1FE, OC1PE */ + 0U, /* 1: - NA */ + 8U, /* 2: OC2M, OC2FE, OC2PE */ + 0U, /* 3: - NA */ + 0U, /* 4: OC3M, OC3FE, OC3PE */ + 0U, /* 5: - NA */ + 8U /* 6: OC4M, OC4FE, OC4PE */ +}; + +static const uint8_t SHIFT_TAB_ICxx[] = +{ + 0U, /* 0: CC1S, IC1PSC, IC1F */ + 0U, /* 1: - NA */ + 8U, /* 2: CC2S, IC2PSC, IC2F */ + 0U, /* 3: - NA */ + 0U, /* 4: CC3S, IC3PSC, IC3F */ + 0U, /* 5: - NA */ + 8U /* 6: CC4S, IC4PSC, IC4F */ +}; + +static const uint8_t SHIFT_TAB_CCxP[] = +{ + 0U, /* 0: CC1P */ + 0U, /* 1: NA */ + 4U, /* 2: CC2P */ + 0U, /* 3: NA */ + 8U, /* 4: CC3P */ + 0U, /* 5: NA */ + 12U /* 6: CC4P */ +}; + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Constants TIM Private Constants + * @{ + */ + + +/* Remap mask definitions */ +#define TIMx_OR_RMP_SHIFT 16U +#define TIMx_OR_RMP_MASK 0x0000FFFFU +#define TIM2_OR_RMP_MASK ((TIM2_OR_ETR_RMP | TIM2_OR_TI4_RMP ) << TIMx_OR_RMP_SHIFT) +#define TIM21_OR_RMP_MASK ((TIM21_OR_ETR_RMP | TIM21_OR_TI1_RMP | TIM21_OR_TI2_RMP) << TIMx_OR_RMP_SHIFT) +#define TIM22_OR_RMP_MASK ((TIM22_OR_ETR_RMP | TIM22_OR_TI1_RMP) << TIMx_OR_RMP_SHIFT) +#if defined(TIM3) +#define TIM3_OR_RMP_MASK ((TIM3_OR_ETR_RMP | TIM3_OR_TI1_RMP | TIM3_OR_TI2_RMP | \ + TIM3_OR_TI4_RMP) << TIMx_OR_RMP_SHIFT) +#endif /* TIM3 */ + + + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Macros TIM Private Macros + * @{ + */ +/** @brief Convert channel id into channel index. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval none + */ +#define TIM_GET_CHANNEL_INDEX( __CHANNEL__) \ + (((__CHANNEL__) == LL_TIM_CHANNEL_CH1) ? 0U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH2) ? 2U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH3) ? 4U : 6U) + +/** + * @} + */ + + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_ES_INIT TIM Exported Init structure + * @{ + */ + +/** + * @brief TIM Time Base configuration structure definition. + */ +typedef struct +{ + uint16_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + + This feature can be modified afterwards using unitary function @ref LL_TIM_SetPrescaler().*/ + + uint32_t CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_LL_EC_COUNTERMODE. + + This feature can be modified afterwards using unitary function @ref LL_TIM_SetCounterMode().*/ + + uint32_t Autoreload; /*!< Specifies the auto reload value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + Some timer instances may support 32 bits counters. In that case this parameter must be a number between 0x0000 and 0xFFFFFFFF. + + This feature can be modified afterwards using unitary function @ref LL_TIM_SetAutoReload().*/ + + uint32_t ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_LL_EC_CLOCKDIVISION. + + This feature can be modified afterwards using unitary function @ref LL_TIM_SetClockDivision().*/ +} LL_TIM_InitTypeDef; + +/** + * @brief TIM Output Compare configuration structure definition. + */ +typedef struct +{ + uint32_t OCMode; /*!< Specifies the output mode. + This parameter can be a value of @ref TIM_LL_EC_OCMODE. + + This feature can be modified afterwards using unitary function @ref LL_TIM_OC_SetMode().*/ + + uint32_t OCState; /*!< Specifies the TIM Output Compare state. + This parameter can be a value of @ref TIM_LL_EC_OCSTATE. + + This feature can be modified afterwards using unitary functions @ref LL_TIM_CC_EnableChannel() or @ref LL_TIM_CC_DisableChannel().*/ + + uint32_t CompareValue; /*!< Specifies the Compare value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + + This feature can be modified afterwards using unitary function LL_TIM_OC_SetCompareCHx (x=1..6).*/ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_LL_EC_OCPOLARITY. + + This feature can be modified afterwards using unitary function @ref LL_TIM_OC_SetPolarity().*/ + + +} LL_TIM_OC_InitTypeDef; + +/** + * @brief TIM Input Capture configuration structure definition. + */ + +typedef struct +{ + + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t ICActiveInput; /*!< Specifies the input. + This parameter can be a value of @ref TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetFilter().*/ +} LL_TIM_IC_InitTypeDef; + + +/** + * @brief TIM Encoder interface configuration structure definition. + */ +typedef struct +{ + uint32_t EncoderMode; /*!< Specifies the encoder resolution (x2 or x4). + This parameter can be a value of @ref TIM_LL_EC_ENCODERMODE. + + This feature can be modified afterwards using unitary function @ref LL_TIM_SetEncoderMode().*/ + + uint32_t IC1Polarity; /*!< Specifies the active edge of TI1 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC1ActiveInput; /*!< Specifies the TI1 input source + This parameter can be a value of @ref TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t IC1Prescaler; /*!< Specifies the TI1 input prescaler value. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t IC1Filter; /*!< Specifies the TI1 input filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetFilter().*/ + + uint32_t IC2Polarity; /*!< Specifies the active edge of TI2 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC2ActiveInput; /*!< Specifies the TI2 input source + This parameter can be a value of @ref TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t IC2Prescaler; /*!< Specifies the TI2 input prescaler value. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t IC2Filter; /*!< Specifies the TI2 input filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function @ref LL_TIM_IC_SetFilter().*/ + +} LL_TIM_ENCODER_InitTypeDef; + + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIM_LL_Exported_Constants TIM Exported Constants + * @{ + */ + +/** @defgroup TIM_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_TIM_ReadReg function. + * @{ + */ +#define LL_TIM_SR_UIF TIM_SR_UIF /*!< Update interrupt flag */ +#define LL_TIM_SR_CC1IF TIM_SR_CC1IF /*!< Capture/compare 1 interrupt flag */ +#define LL_TIM_SR_CC2IF TIM_SR_CC2IF /*!< Capture/compare 2 interrupt flag */ +#define LL_TIM_SR_CC3IF TIM_SR_CC3IF /*!< Capture/compare 3 interrupt flag */ +#define LL_TIM_SR_CC4IF TIM_SR_CC4IF /*!< Capture/compare 4 interrupt flag */ +#define LL_TIM_SR_TIF TIM_SR_TIF /*!< Trigger interrupt flag */ +#define LL_TIM_SR_CC1OF TIM_SR_CC1OF /*!< Capture/Compare 1 overcapture flag */ +#define LL_TIM_SR_CC2OF TIM_SR_CC2OF /*!< Capture/Compare 2 overcapture flag */ +#define LL_TIM_SR_CC3OF TIM_SR_CC3OF /*!< Capture/Compare 3 overcapture flag */ +#define LL_TIM_SR_CC4OF TIM_SR_CC4OF /*!< Capture/Compare 4 overcapture flag */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_TIM_ReadReg and LL_TIM_WriteReg functions. + * @{ + */ +#define LL_TIM_DIER_UIE TIM_DIER_UIE /*!< Update interrupt enable */ +#define LL_TIM_DIER_CC1IE TIM_DIER_CC1IE /*!< Capture/compare 1 interrupt enable */ +#define LL_TIM_DIER_CC2IE TIM_DIER_CC2IE /*!< Capture/compare 2 interrupt enable */ +#define LL_TIM_DIER_CC3IE TIM_DIER_CC3IE /*!< Capture/compare 3 interrupt enable */ +#define LL_TIM_DIER_CC4IE TIM_DIER_CC4IE /*!< Capture/compare 4 interrupt enable */ +#define LL_TIM_DIER_TIE TIM_DIER_TIE /*!< Trigger interrupt enable */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_UPDATESOURCE Update Source + * @{ + */ +#define LL_TIM_UPDATESOURCE_REGULAR 0x00000000U /*!< Counter overflow/underflow, Setting the UG bit or Update generation through the slave mode controller generates an update request */ +#define LL_TIM_UPDATESOURCE_COUNTER TIM_CR1_URS /*!< Only counter overflow/underflow generates an update request */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_ONEPULSEMODE One Pulse Mode + * @{ + */ +#define LL_TIM_ONEPULSEMODE_SINGLE TIM_CR1_OPM /*!< Counter is not stopped at update event */ +#define LL_TIM_ONEPULSEMODE_REPETITIVE 0x00000000U /*!< Counter stops counting at the next update event */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_COUNTERMODE Counter Mode + * @{ + */ +#define LL_TIM_COUNTERMODE_UP 0x00000000U /*!TIMx_CCRy else active.*/ +#define LL_TIM_OCMODE_PWM2 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!TIMx_CCRy else inactive*/ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_OCPOLARITY Output Configuration Polarity + * @{ + */ +#define LL_TIM_OCPOLARITY_HIGH 0x00000000U /*!< OCxactive high*/ +#define LL_TIM_OCPOLARITY_LOW TIM_CCER_CC1P /*!< OCxactive low*/ +/** + * @} + */ + + + +/** @defgroup TIM_LL_EC_ACTIVEINPUT Active Input Selection + * @{ + */ +#define LL_TIM_ACTIVEINPUT_DIRECTTI (TIM_CCMR1_CC1S_0 << 16U) /*!< ICx is mapped on TIx */ +#define LL_TIM_ACTIVEINPUT_INDIRECTTI (TIM_CCMR1_CC1S_1 << 16U) /*!< ICx is mapped on TIy */ +#define LL_TIM_ACTIVEINPUT_TRC (TIM_CCMR1_CC1S << 16U) /*!< ICx is mapped on TRC */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_ICPSC Input Configuration Prescaler + * @{ + */ +#define LL_TIM_ICPSC_DIV1 0x00000000U /*!< No prescaler, capture is done each time an edge is detected on the capture input */ +#define LL_TIM_ICPSC_DIV2 (TIM_CCMR1_IC1PSC_0 << 16U) /*!< Capture is done once every 2 events */ +#define LL_TIM_ICPSC_DIV4 (TIM_CCMR1_IC1PSC_1 << 16U) /*!< Capture is done once every 4 events */ +#define LL_TIM_ICPSC_DIV8 (TIM_CCMR1_IC1PSC << 16U) /*!< Capture is done once every 8 events */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_IC_FILTER Input Configuration Filter + * @{ + */ +#define LL_TIM_IC_FILTER_FDIV1 0x00000000U /*!< No filter, sampling is done at fDTS */ +#define LL_TIM_IC_FILTER_FDIV1_N2 (TIM_CCMR1_IC1F_0 << 16U) /*!< fSAMPLING=fCK_INT, N=2 */ +#define LL_TIM_IC_FILTER_FDIV1_N4 (TIM_CCMR1_IC1F_1 << 16U) /*!< fSAMPLING=fCK_INT, N=4 */ +#define LL_TIM_IC_FILTER_FDIV1_N8 ((TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fCK_INT, N=8 */ +#define LL_TIM_IC_FILTER_FDIV2_N6 (TIM_CCMR1_IC1F_2 << 16U) /*!< fSAMPLING=fDTS/2, N=6 */ +#define LL_TIM_IC_FILTER_FDIV2_N8 ((TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/2, N=8 */ +#define LL_TIM_IC_FILTER_FDIV4_N6 ((TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_1) << 16U) /*!< fSAMPLING=fDTS/4, N=6 */ +#define LL_TIM_IC_FILTER_FDIV4_N8 ((TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/4, N=8 */ +#define LL_TIM_IC_FILTER_FDIV8_N6 (TIM_CCMR1_IC1F_3 << 16U) /*!< fSAMPLING=fDTS/8, N=6 */ +#define LL_TIM_IC_FILTER_FDIV8_N8 ((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/8, N=8 */ +#define LL_TIM_IC_FILTER_FDIV16_N5 ((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_1) << 16U) /*!< fSAMPLING=fDTS/16, N=5 */ +#define LL_TIM_IC_FILTER_FDIV16_N6 ((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/16, N=6 */ +#define LL_TIM_IC_FILTER_FDIV16_N8 ((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_2) << 16U) /*!< fSAMPLING=fDTS/16, N=8 */ +#define LL_TIM_IC_FILTER_FDIV32_N5 ((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/32, N=5 */ +#define LL_TIM_IC_FILTER_FDIV32_N6 ((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_1) << 16U) /*!< fSAMPLING=fDTS/32, N=6 */ +#define LL_TIM_IC_FILTER_FDIV32_N8 (TIM_CCMR1_IC1F << 16U) /*!< fSAMPLING=fDTS/32, N=8 */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_IC_POLARITY Input Configuration Polarity + * @{ + */ +#define LL_TIM_IC_POLARITY_RISING 0x00000000U /*!< The circuit is sensitive to TIxFP1 rising edge, TIxFP1 is not inverted */ +#define LL_TIM_IC_POLARITY_FALLING TIM_CCER_CC1P /*!< The circuit is sensitive to TIxFP1 falling edge, TIxFP1 is inverted */ +#define LL_TIM_IC_POLARITY_BOTHEDGE (TIM_CCER_CC1P | TIM_CCER_CC1NP) /*!< The circuit is sensitive to both TIxFP1 rising and falling edges, TIxFP1 is not inverted */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_CLOCKSOURCE Clock Source + * @{ + */ +#define LL_TIM_CLOCKSOURCE_INTERNAL 0x00000000U /*!< The timer is clocked by the internal clock provided from the RCC */ +#define LL_TIM_CLOCKSOURCE_EXT_MODE1 (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< Counter counts at each rising or falling edge on a selected input*/ +#define LL_TIM_CLOCKSOURCE_EXT_MODE2 TIM_SMCR_ECE /*!< Counter counts at each rising or falling edge on the external trigger input ETR */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_ENCODERMODE Encoder Mode + * @{ + */ +#define LL_TIM_ENCODERMODE_X2_TI1 TIM_SMCR_SMS_0 /*!< Quadrature encoder mode 1, x2 mode - Counter counts up/down on TI1FP1 edge depending on TI2FP2 level */ +#define LL_TIM_ENCODERMODE_X2_TI2 TIM_SMCR_SMS_1 /*!< Quadrature encoder mode 2, x2 mode - Counter counts up/down on TI2FP2 edge depending on TI1FP1 level */ +#define LL_TIM_ENCODERMODE_X4_TI12 (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< Quadrature encoder mode 3, x4 mode - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_TRGO Trigger Output + * @{ + */ +#define LL_TIM_TRGO_RESET 0x00000000U /*!< UG bit from the TIMx_EGR register is used as trigger output */ +#define LL_TIM_TRGO_ENABLE TIM_CR2_MMS_0 /*!< Counter Enable signal (CNT_EN) is used as trigger output */ +#define LL_TIM_TRGO_UPDATE TIM_CR2_MMS_1 /*!< Update event is used as trigger output */ +#define LL_TIM_TRGO_CC1IF (TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< CC1 capture or a compare match is used as trigger output */ +#define LL_TIM_TRGO_OC1REF TIM_CR2_MMS_2 /*!< OC1REF signal is used as trigger output */ +#define LL_TIM_TRGO_OC2REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_0) /*!< OC2REF signal is used as trigger output */ +#define LL_TIM_TRGO_OC3REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1) /*!< OC3REF signal is used as trigger output */ +#define LL_TIM_TRGO_OC4REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< OC4REF signal is used as trigger output */ +/** + * @} + */ + + +/** @defgroup TIM_LL_EC_SLAVEMODE Slave Mode + * @{ + */ +#define LL_TIM_SLAVEMODE_DISABLED 0x00000000U /*!< Slave mode disabled */ +#define LL_TIM_SLAVEMODE_RESET TIM_SMCR_SMS_2 /*!< Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter */ +#define LL_TIM_SLAVEMODE_GATED (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0) /*!< Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high */ +#define LL_TIM_SLAVEMODE_TRIGGER (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1) /*!< Trigger Mode - The counter starts at a rising edge of the trigger TRGI */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_TS Trigger Selection + * @{ + */ +#define LL_TIM_TS_ITR0 0x00000000U /*!< Internal Trigger 0 (ITR0) is used as trigger input */ +#define LL_TIM_TS_ITR1 TIM_SMCR_TS_0 /*!< Internal Trigger 1 (ITR1) is used as trigger input */ +#define LL_TIM_TS_ITR2 TIM_SMCR_TS_1 /*!< Internal Trigger 2 (ITR2) is used as trigger input */ +#define LL_TIM_TS_ITR3 (TIM_SMCR_TS_0 | TIM_SMCR_TS_1) /*!< Internal Trigger 3 (ITR3) is used as trigger input */ +#define LL_TIM_TS_TI1F_ED TIM_SMCR_TS_2 /*!< TI1 Edge Detector (TI1F_ED) is used as trigger input */ +#define LL_TIM_TS_TI1FP1 (TIM_SMCR_TS_2 | TIM_SMCR_TS_0) /*!< Filtered Timer Input 1 (TI1FP1) is used as trigger input */ +#define LL_TIM_TS_TI2FP2 (TIM_SMCR_TS_2 | TIM_SMCR_TS_1) /*!< Filtered Timer Input 2 (TI12P2) is used as trigger input */ +#define LL_TIM_TS_ETRF (TIM_SMCR_TS_2 | TIM_SMCR_TS_1 | TIM_SMCR_TS_0) /*!< Filtered external Trigger (ETRF) is used as trigger input */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_ETR_POLARITY External Trigger Polarity + * @{ + */ +#define LL_TIM_ETR_POLARITY_NONINVERTED 0x00000000U /*!< ETR is non-inverted, active at high level or rising edge */ +#define LL_TIM_ETR_POLARITY_INVERTED TIM_SMCR_ETP /*!< ETR is inverted, active at low level or falling edge */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_ETR_PRESCALER External Trigger Prescaler + * @{ + */ +#define LL_TIM_ETR_PRESCALER_DIV1 0x00000000U /*!< ETR prescaler OFF */ +#define LL_TIM_ETR_PRESCALER_DIV2 TIM_SMCR_ETPS_0 /*!< ETR frequency is divided by 2 */ +#define LL_TIM_ETR_PRESCALER_DIV4 TIM_SMCR_ETPS_1 /*!< ETR frequency is divided by 4 */ +#define LL_TIM_ETR_PRESCALER_DIV8 TIM_SMCR_ETPS /*!< ETR frequency is divided by 8 */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_ETR_FILTER External Trigger Filter + * @{ + */ +#define LL_TIM_ETR_FILTER_FDIV1 0x00000000U /*!< No filter, sampling is done at fDTS */ +#define LL_TIM_ETR_FILTER_FDIV1_N2 TIM_SMCR_ETF_0 /*!< fSAMPLING=fCK_INT, N=2 */ +#define LL_TIM_ETR_FILTER_FDIV1_N4 TIM_SMCR_ETF_1 /*!< fSAMPLING=fCK_INT, N=4 */ +#define LL_TIM_ETR_FILTER_FDIV1_N8 (TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fCK_INT, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV2_N6 TIM_SMCR_ETF_2 /*!< fSAMPLING=fDTS/2, N=6 */ +#define LL_TIM_ETR_FILTER_FDIV2_N8 (TIM_SMCR_ETF_2 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/2, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV4_N6 (TIM_SMCR_ETF_2 | TIM_SMCR_ETF_1) /*!< fSAMPLING=fDTS/4, N=6 */ +#define LL_TIM_ETR_FILTER_FDIV4_N8 (TIM_SMCR_ETF_2 | TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/4, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV8_N6 TIM_SMCR_ETF_3 /*!< fSAMPLING=fDTS/8, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV8_N8 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/16, N=5 */ +#define LL_TIM_ETR_FILTER_FDIV16_N5 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_1) /*!< fSAMPLING=fDTS/16, N=6 */ +#define LL_TIM_ETR_FILTER_FDIV16_N6 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/16, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV16_N8 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_2) /*!< fSAMPLING=fDTS/16, N=5 */ +#define LL_TIM_ETR_FILTER_FDIV32_N5 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_2 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/32, N=5 */ +#define LL_TIM_ETR_FILTER_FDIV32_N6 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_2 | TIM_SMCR_ETF_1) /*!< fSAMPLING=fDTS/32, N=6 */ +#define LL_TIM_ETR_FILTER_FDIV32_N8 TIM_SMCR_ETF /*!< fSAMPLING=fDTS/32, N=8 */ +/** + * @} + */ + + + + + + + +/** @defgroup TIM_LL_EC_DMABURST_BASEADDR DMA Burst Base Address + * @{ + */ +#define LL_TIM_DMABURST_BASEADDR_CR1 0x00000000U /*!< TIMx_CR1 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CR2 TIM_DCR_DBA_0 /*!< TIMx_CR2 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_SMCR TIM_DCR_DBA_1 /*!< TIMx_SMCR register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_DIER (TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_DIER register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_SR TIM_DCR_DBA_2 /*!< TIMx_SR register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_EGR (TIM_DCR_DBA_2 | TIM_DCR_DBA_0) /*!< TIMx_EGR register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCMR1 (TIM_DCR_DBA_2 | TIM_DCR_DBA_1) /*!< TIMx_CCMR1 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCMR2 (TIM_DCR_DBA_2 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_CCMR2 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCER TIM_DCR_DBA_3 /*!< TIMx_CCER register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CNT (TIM_DCR_DBA_3 | TIM_DCR_DBA_0) /*!< TIMx_CNT register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_PSC (TIM_DCR_DBA_3 | TIM_DCR_DBA_1) /*!< TIMx_PSC register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_ARR (TIM_DCR_DBA_3 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_ARR register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCR1 (TIM_DCR_DBA_3 | TIM_DCR_DBA_2 | TIM_DCR_DBA_0) /*!< TIMx_CCR1 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCR2 (TIM_DCR_DBA_3 | TIM_DCR_DBA_2 | TIM_DCR_DBA_1) /*!< TIMx_CCR2 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCR3 (TIM_DCR_DBA_3 | TIM_DCR_DBA_2 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_CCR3 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCR4 TIM_DCR_DBA_4 /*!< TIMx_CCR4 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_OR (TIM_DCR_DBA_4 | TIM_DCR_DBA_2) /*!< TIMx_OR register is the DMA base address for DMA burst */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_DMABURST_LENGTH DMA Burst Length + * @{ + */ +#define LL_TIM_DMABURST_LENGTH_1TRANSFER 0x00000000U /*!< Transfer is done to 1 register starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_2TRANSFERS TIM_DCR_DBL_0 /*!< Transfer is done to 2 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_3TRANSFERS TIM_DCR_DBL_1 /*!< Transfer is done to 3 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_4TRANSFERS (TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 4 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_5TRANSFERS TIM_DCR_DBL_2 /*!< Transfer is done to 5 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_6TRANSFERS (TIM_DCR_DBL_2 | TIM_DCR_DBL_0) /*!< Transfer is done to 6 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_7TRANSFERS (TIM_DCR_DBL_2 | TIM_DCR_DBL_1) /*!< Transfer is done to 7 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_8TRANSFERS (TIM_DCR_DBL_2 | TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 1 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_9TRANSFERS TIM_DCR_DBL_3 /*!< Transfer is done to 9 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_10TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_0) /*!< Transfer is done to 10 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_11TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_1) /*!< Transfer is done to 11 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_12TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 12 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_13TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2) /*!< Transfer is done to 13 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_14TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2 | TIM_DCR_DBL_0) /*!< Transfer is done to 14 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_15TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2 | TIM_DCR_DBL_1) /*!< Transfer is done to 15 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_16TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2 | TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 16 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_17TRANSFERS TIM_DCR_DBL_4 /*!< Transfer is done to 17 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_18TRANSFERS (TIM_DCR_DBL_4 | TIM_DCR_DBL_0) /*!< Transfer is done to 18 registers starting from the DMA burst base address */ +/** + * @} + */ + + +/** @defgroup TIM_LL_EC_TIM2_ETR_RMP TIM2 External Trigger Remap + * @{ + */ +#define LL_TIM_TIM2_ETR_RMP_GPIO TIM2_OR_RMP_MASK /*!< TIM2_ETR is connected to Ored GPIO */ +#if defined(TIM_TIM2_REMAP_HSI_SUPPORT) +#define LL_TIM_TIM2_ETR_RMP_HSI (TIM2_OR_ETR_RMP_1 | TIM2_OR_ETR_RMP_0 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to HSI */ +#endif /* defined(TIM_TIM2_REMAP_HSI_SUPPORT) */ +#if defined(TIM_TIM2_REMAP_HSI48_SUPPORT) +#define LL_TIM_TIM2_ETR_RMP_HSI48 (TIM2_OR_ETR_RMP_2 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to HSI48 */ +#endif /* defined(TIM_TIM2_REMAP_HSI48_SUPPORT) */ +#define LL_TIM_TIM2_ETR_RMP_LSE (TIM2_OR_ETR_RMP_2 | TIM2_OR_ETR_RMP_0 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to LSE */ +#define LL_TIM_TIM2_ETR_RMP_COMP2 (TIM2_OR_ETR_RMP_2 | TIM2_OR_ETR_RMP_1 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to COMP2_OUT */ +#define LL_TIM_TIM2_ETR_RMP_COMP1 (TIM2_OR_ETR_RMP | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to COMP1_OUT */ + +/** + * @} + */ + +/** @defgroup TIM_LL_EC_TIM2_TI4_RMP TIM2 Timer Input Ch4 Remap + * @{ + */ +#define LL_TIM_TIM2_TI4_RMP_GPIO TIM2_OR_RMP_MASK /*!< TIM2 input capture 4 is connected to GPIO */ +#define LL_TIM_TIM2_TI4_RMP_COMP2 (TIM2_OR_TI4_RMP_0 | TIM2_OR_RMP_MASK) /*!< TIM2 input capture 4 is connected to COMP2_OUT */ +#define LL_TIM_TIM2_TI4_RMP_COMP1 (TIM2_OR_TI4_RMP_1 | TIM2_OR_RMP_MASK) /*!< TIM2 input capture 4 is connected to COMP1_OUT */ +/** + * @} + */ + +#if defined(TIM3_OR_ETR_RMP) +/** @defgroup TIM_LL_EC_TIM3_ETR_RMP TIM3 External Trigger Remap + * @{ + */ +#define LL_TIM_TIM3_ETR_RMP_GPIO TIM3_OR_RMP_MASK /*!< TIM3_ETR is connected to GPIO */ +#define LL_TIM_TIM3_ETR_RMP_HSI48DIV6 (TIM3_OR_ETR_RMP_1 | TIM3_OR_RMP_MASK) /*!< TIM3_ETR is connected to HSI48 divided by 6 */ +/** + * @} + */ +#endif /* defined(TIM3_OR_ETR_RMP) */ + +#if defined(TIM3_OR_TI1_RMP) || defined(TIM3_OR_TI2_RMP) || defined(TIM3_OR_TI4_RMP) +/** @defgroup TIM_LL_EC_TIM3_TI_RMP TIM3 External Inputs Remap + * @{ + */ +#define LL_TIM_TIM3_TI_RMP_TI1_USB_SOF TIM3_OR_RMP_MASK /*!< TIM3_TI1 input is connected to USB_SOF */ +#define LL_TIM_TIM3_TI_RMP_TI1_GPIO (TIM3_OR_TI1_RMP | TIM3_OR_RMP_MASK) /*!< TIM3_TI1 input is connected to PE3, PA6, PC6 or PB4 */ + +#define LL_TIM_TIM3_TI_RMP_TI2_GPIO_DEF TIM3_OR_RMP_MASK /*!< Mapping PB5 to TIM22_CH2 */ +#define LL_TIM_TIM3_TI_RMP_TI2_GPIOB5_AF4 (TIM3_OR_TI2_RMP | TIM3_OR_RMP_MASK) /*!< Mapping PB5 to TIM3_CH2 */ + +#define LL_TIM_TIM3_TI_RMP_TI4_GPIO_DEF (0x00000000U | TIM3_OR_RMP_MASK) /*!< Mapping PC9 to USB_OE */ +#define LL_TIM_TIM3_TI_RMP_TI4_GPIOC9_AF2 (TIM3_OR_TI4_RMP | TIM3_OR_RMP_MASK) /*!< Mapping PC9 to TIM3_CH4 */ +/** + * @} + */ +#endif /*defined(TIM3_OR_TI1_RMP) or defined(TIM3_OR_TI2_RMP) or defined(TIM3_OR_TI4_RMP)*/ + +/** @defgroup TIM_LL_EC_TIM21_ETR_RMP TIM21 External Trigger Remap + * @{ + */ +#define LL_TIM_TIM21_ETR_RMP_GPIO TIM21_OR_RMP_MASK /*!< TIM21_ETR is connected to Ored GPIO1 */ +#define LL_TIM_TIM21_ETR_RMP_COMP2 (TIM21_OR_ETR_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to COMP2_OUT */ +#define LL_TIM_TIM21_ETR_RMP_COMP1 (TIM21_OR_ETR_RMP_1 | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to COMP1_OUT */ +#define LL_TIM_TIM21_ETR_RMP_LSE (TIM21_OR_ETR_RMP | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to LSE */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_TIM21_TI1_RMP TIM21 External Input Ch1 Remap + * @{ + */ +#define LL_TIM_TIM21_TI1_RMP_GPIO TIM21_OR_RMP_MASK /*!< TIM21_TI1 is connected to Ored GPIO1 */ +#define LL_TIM_TIM21_TI1_RMP_RTC_WK (TIM21_OR_TI1_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to RTC_WAKEUP */ +#define LL_TIM_TIM21_TI1_RMP_HSE_RTC (TIM21_OR_TI1_RMP_1 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to HSE_RTC */ +#define LL_TIM_TIM21_TI1_RMP_MSI (TIM21_OR_TI1_RMP_1 | TIM21_OR_TI1_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to MSI */ +#define LL_TIM_TIM21_TI1_RMP_LSE (TIM21_OR_TI1_RMP_2 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to LSE */ +#define LL_TIM_TIM21_TI1_RMP_LSI (TIM21_OR_TI1_RMP_2 | TIM21_OR_TI1_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to LSI */ +#define LL_TIM_TIM21_TI1_RMP_COMP1 (TIM21_OR_TI1_RMP_2 | TIM21_OR_TI1_RMP_1 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to COMP1_OUT */ +#define LL_TIM_TIM21_TI1_RMP_MCO (TIM21_OR_TI1_RMP | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to MCO */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_TIM21_TI2_RMP TIM21 External Input Ch2 Remap + * @{ + */ +#define LL_TIM_TIM21_TI2_RMP_GPIO TIM21_OR_RMP_MASK /*!< TIM21_TI2 is connected to Ored GPIO1 */ +#define LL_TIM_TIM21_TI2_RMP_COMP2 (TIM21_OR_TI2_RMP | TIM21_OR_RMP_MASK) /*!< TIM21_TI2 is connected to COMP2_OUT */ +/** + * @} + */ + +#if defined(TIM22_OR_ETR_RMP) + +/** @defgroup TIM_LL_EC_TIM22_ETR_RMP TIM22 External Trigger Remap + * @{ + */ +#define LL_TIM_TIM22_ETR_RMP_GPIO TIM22_OR_RMP_MASK /*!< TIM22_ETR is connected to GPIO */ +#define LL_TIM_TIM22_ETR_RMP_COMP2 (TIM22_OR_ETR_RMP_0 | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to COMP2_OUT */ +#define LL_TIM_TIM22_ETR_RMP_COMP1 (TIM22_OR_ETR_RMP_1 | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to COMP1_OUT */ +#define LL_TIM_TIM22_ETR_RMP_LSE (TIM22_OR_ETR_RMP | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to LSE */ +/** + * @} + */ +#endif /* defined(TIM22_OR_ETR_RMP) */ + +#if defined(TIM22_OR_TI1_RMP) +/** @defgroup TIM_LL_EC_TIM22_TI1_RMP TIM22 External Input Ch1 Remap + * @{ + */ +#define LL_TIM_TIM22_TI1_RMP_GPIO1 TIM22_OR_RMP_MASK /*!< TIM22_TI1 is connected to GPIO1 */ +#define LL_TIM_TIM22_TI1_RMP_COMP2 (TIM22_OR_TI1_RMP_0 | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to COMP2_OUT */ +#define LL_TIM_TIM22_TI1_RMP_COMP1 (TIM22_OR_TI1_RMP_1 | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to COMP1_OUT */ +#define LL_TIM_TIM22_TI1_RMP_GPIO2 (TIM22_OR_TI1_RMP | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to GPIO2 */ +/** + * @} + */ +#endif /* defined(TIM22_OR_TI1_RMP) */ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup TIM_LL_Exported_Macros TIM Exported Macros + * @{ + */ + +/** @defgroup TIM_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ +/** + * @brief Write a value in TIM register. + * @param __INSTANCE__ TIM Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_TIM_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG((__INSTANCE__)->__REG__, (__VALUE__)) + +/** + * @brief Read a value in TIM register. + * @param __INSTANCE__ TIM Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_TIM_ReadReg(__INSTANCE__, __REG__) READ_REG((__INSTANCE__)->__REG__) +/** + * @} + */ + +/** @defgroup TIM_LL_EM_Exported_Macros Exported_Macros + * @{ + */ + +/** + * @brief HELPER macro calculating the prescaler value to achieve the required counter clock frequency. + * @note ex: @ref __LL_TIM_CALC_PSC (80000000, 1000000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __CNTCLK__ counter clock frequency (in Hz) + * @retval Prescaler value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_PSC(__TIMCLK__, __CNTCLK__) \ + (((__TIMCLK__) >= (__CNTCLK__)) ? (uint32_t)(((__TIMCLK__)/(__CNTCLK__)) - 1U) : 0U) + +/** + * @brief HELPER macro calculating the auto-reload value to achieve the required output signal frequency. + * @note ex: @ref __LL_TIM_CALC_ARR (1000000, @ref LL_TIM_GetPrescaler (), 10000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __FREQ__ output signal frequency (in Hz) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_ARR(__TIMCLK__, __PSC__, __FREQ__) \ + ((((__TIMCLK__)/((__PSC__) + 1U)) >= (__FREQ__)) ? (((__TIMCLK__)/((__FREQ__) * ((__PSC__) + 1U))) - 1U) : 0U) + +/** + * @brief HELPER macro calculating the compare value required to achieve the required timer output compare active/inactive delay. + * @note ex: @ref __LL_TIM_CALC_DELAY (1000000, @ref LL_TIM_GetPrescaler (), 10); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @retval Compare value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_DELAY(__TIMCLK__, __PSC__, __DELAY__) \ + ((uint32_t)(((uint64_t)(__TIMCLK__) * (uint64_t)(__DELAY__)) \ + / ((uint64_t)1000000U * (uint64_t)((__PSC__) + 1U)))) + +/** + * @brief HELPER macro calculating the auto-reload value to achieve the required pulse duration (when the timer operates in one pulse mode). + * @note ex: @ref __LL_TIM_CALC_PULSE (1000000, @ref LL_TIM_GetPrescaler (), 10, 20); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @param __PULSE__ pulse duration (in us) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_PULSE(__TIMCLK__, __PSC__, __DELAY__, __PULSE__) \ + ((uint32_t)(__LL_TIM_CALC_DELAY((__TIMCLK__), (__PSC__), (__PULSE__)) \ + + __LL_TIM_CALC_DELAY((__TIMCLK__), (__PSC__), (__DELAY__)))) + +/** + * @brief HELPER macro retrieving the ratio of the input capture prescaler + * @note ex: @ref __LL_TIM_GET_ICPSC_RATIO (@ref LL_TIM_IC_GetPrescaler ()); + * @param __ICPSC__ This parameter can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + * @retval Input capture prescaler ratio (1, 2, 4 or 8) + */ +#define __LL_TIM_GET_ICPSC_RATIO(__ICPSC__) \ + ((uint32_t)(0x01U << (((__ICPSC__) >> 16U) >> TIM_CCMR1_IC1PSC_Pos))) + + +/** + * @} + */ + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup TIM_LL_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @defgroup TIM_LL_EF_Time_Base Time Base configuration + * @{ + */ +/** + * @brief Enable timer counter. + * @rmtoll CR1 CEN LL_TIM_EnableCounter + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableCounter(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_CEN); +} + +/** + * @brief Disable timer counter. + * @rmtoll CR1 CEN LL_TIM_DisableCounter + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableCounter(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_CEN); +} + +/** + * @brief Indicates whether the timer counter is enabled. + * @rmtoll CR1 CEN LL_TIM_IsEnabledCounter + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledCounter(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR1, TIM_CR1_CEN) == (TIM_CR1_CEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable update event generation. + * @rmtoll CR1 UDIS LL_TIM_EnableUpdateEvent + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableUpdateEvent(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_UDIS); +} + +/** + * @brief Disable update event generation. + * @rmtoll CR1 UDIS LL_TIM_DisableUpdateEvent + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableUpdateEvent(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_UDIS); +} + +/** + * @brief Indicates whether update event generation is enabled. + * @rmtoll CR1 UDIS LL_TIM_IsEnabledUpdateEvent + * @param TIMx Timer instance + * @retval Inverted state of bit (0 or 1). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledUpdateEvent(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR1, TIM_CR1_UDIS) == (uint32_t)RESET) ? 1UL : 0UL); +} + +/** + * @brief Set update event source + * @note Update event source set to LL_TIM_UPDATESOURCE_REGULAR: any of the following events + * generate an update interrupt or DMA request if enabled: + * - Counter overflow/underflow + * - Setting the UG bit + * - Update generation through the slave mode controller + * @note Update event source set to LL_TIM_UPDATESOURCE_COUNTER: only counter + * overflow/underflow generates an update interrupt or DMA request if enabled. + * @rmtoll CR1 URS LL_TIM_SetUpdateSource + * @param TIMx Timer instance + * @param UpdateSource This parameter can be one of the following values: + * @arg @ref LL_TIM_UPDATESOURCE_REGULAR + * @arg @ref LL_TIM_UPDATESOURCE_COUNTER + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetUpdateSource(TIM_TypeDef *TIMx, uint32_t UpdateSource) +{ + MODIFY_REG(TIMx->CR1, TIM_CR1_URS, UpdateSource); +} + +/** + * @brief Get actual event update source + * @rmtoll CR1 URS LL_TIM_GetUpdateSource + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_UPDATESOURCE_REGULAR + * @arg @ref LL_TIM_UPDATESOURCE_COUNTER + */ +__STATIC_INLINE uint32_t LL_TIM_GetUpdateSource(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_URS)); +} + +/** + * @brief Set one pulse mode (one shot v.s. repetitive). + * @rmtoll CR1 OPM LL_TIM_SetOnePulseMode + * @param TIMx Timer instance + * @param OnePulseMode This parameter can be one of the following values: + * @arg @ref LL_TIM_ONEPULSEMODE_SINGLE + * @arg @ref LL_TIM_ONEPULSEMODE_REPETITIVE + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetOnePulseMode(TIM_TypeDef *TIMx, uint32_t OnePulseMode) +{ + MODIFY_REG(TIMx->CR1, TIM_CR1_OPM, OnePulseMode); +} + +/** + * @brief Get actual one pulse mode. + * @rmtoll CR1 OPM LL_TIM_GetOnePulseMode + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ONEPULSEMODE_SINGLE + * @arg @ref LL_TIM_ONEPULSEMODE_REPETITIVE + */ +__STATIC_INLINE uint32_t LL_TIM_GetOnePulseMode(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_OPM)); +} + +/** + * @brief Set the timer counter counting mode. + * @note Macro IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx) can be used to + * check whether or not the counter mode selection feature is supported + * by a timer instance. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * @rmtoll CR1 DIR LL_TIM_SetCounterMode\n + * CR1 CMS LL_TIM_SetCounterMode + * @param TIMx Timer instance + * @param CounterMode This parameter can be one of the following values: + * @arg @ref LL_TIM_COUNTERMODE_UP + * @arg @ref LL_TIM_COUNTERMODE_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP + * @arg @ref LL_TIM_COUNTERMODE_CENTER_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP_DOWN + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetCounterMode(TIM_TypeDef *TIMx, uint32_t CounterMode) +{ + MODIFY_REG(TIMx->CR1, (TIM_CR1_DIR | TIM_CR1_CMS), CounterMode); +} + +/** + * @brief Get actual counter mode. + * @note Macro IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx) can be used to + * check whether or not the counter mode selection feature is supported + * by a timer instance. + * @rmtoll CR1 DIR LL_TIM_GetCounterMode\n + * CR1 CMS LL_TIM_GetCounterMode + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_COUNTERMODE_UP + * @arg @ref LL_TIM_COUNTERMODE_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP + * @arg @ref LL_TIM_COUNTERMODE_CENTER_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP_DOWN + */ +__STATIC_INLINE uint32_t LL_TIM_GetCounterMode(TIM_TypeDef *TIMx) +{ + uint32_t counter_mode; + + counter_mode = (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_CMS)); + + if (counter_mode == 0U) + { + counter_mode = (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_DIR)); + } + + return counter_mode; +} + +/** + * @brief Enable auto-reload (ARR) preload. + * @rmtoll CR1 ARPE LL_TIM_EnableARRPreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableARRPreload(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_ARPE); +} + +/** + * @brief Disable auto-reload (ARR) preload. + * @rmtoll CR1 ARPE LL_TIM_DisableARRPreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableARRPreload(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_ARPE); +} + +/** + * @brief Indicates whether auto-reload (ARR) preload is enabled. + * @rmtoll CR1 ARPE LL_TIM_IsEnabledARRPreload + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledARRPreload(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR1, TIM_CR1_ARPE) == (TIM_CR1_ARPE)) ? 1UL : 0UL); +} + +/** + * @brief Set the division ratio between the timer clock and the sampling clock used by the dead-time generators (when supported) and the digital filters. + * @note Macro IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check + * whether or not the clock division feature is supported by the timer + * instance. + * @rmtoll CR1 CKD LL_TIM_SetClockDivision + * @param TIMx Timer instance + * @param ClockDivision This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetClockDivision(TIM_TypeDef *TIMx, uint32_t ClockDivision) +{ + MODIFY_REG(TIMx->CR1, TIM_CR1_CKD, ClockDivision); +} + +/** + * @brief Get the actual division ratio between the timer clock and the sampling clock used by the dead-time generators (when supported) and the digital filters. + * @note Macro IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check + * whether or not the clock division feature is supported by the timer + * instance. + * @rmtoll CR1 CKD LL_TIM_GetClockDivision + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + */ +__STATIC_INLINE uint32_t LL_TIM_GetClockDivision(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_CKD)); +} + +/** + * @brief Set the counter value. + * @rmtoll CNT CNT LL_TIM_SetCounter + * @param TIMx Timer instance + * @param Counter Counter value (between Min_Data=0 and Max_Data=0xFFFF) + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetCounter(TIM_TypeDef *TIMx, uint32_t Counter) +{ + WRITE_REG(TIMx->CNT, Counter); +} + +/** + * @brief Get the counter value. + * @rmtoll CNT CNT LL_TIM_GetCounter + * @param TIMx Timer instance + * @retval Counter value (between Min_Data=0 and Max_Data=0xFFFF) + */ +__STATIC_INLINE uint32_t LL_TIM_GetCounter(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CNT)); +} + +/** + * @brief Get the current direction of the counter + * @rmtoll CR1 DIR LL_TIM_GetDirection + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_COUNTERDIRECTION_UP + * @arg @ref LL_TIM_COUNTERDIRECTION_DOWN + */ +__STATIC_INLINE uint32_t LL_TIM_GetDirection(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_DIR)); +} + +/** + * @brief Set the prescaler value. + * @note The counter clock frequency CK_CNT is equal to fCK_PSC / (PSC[15:0] + 1). + * @note The prescaler can be changed on the fly as this control register is buffered. The new + * prescaler ratio is taken into account at the next update event. + * @note Helper macro @ref __LL_TIM_CALC_PSC can be used to calculate the Prescaler parameter + * @rmtoll PSC PSC LL_TIM_SetPrescaler + * @param TIMx Timer instance + * @param Prescaler between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Prescaler) +{ + WRITE_REG(TIMx->PSC, Prescaler); +} + +/** + * @brief Get the prescaler value. + * @rmtoll PSC PSC LL_TIM_GetPrescaler + * @param TIMx Timer instance + * @retval Prescaler value between Min_Data=0 and Max_Data=65535 + */ +__STATIC_INLINE uint32_t LL_TIM_GetPrescaler(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->PSC)); +} + +/** + * @brief Set the auto-reload value. + * @note The counter is blocked while the auto-reload value is null. + * @note Helper macro @ref __LL_TIM_CALC_ARR can be used to calculate the AutoReload parameter + * @rmtoll ARR ARR LL_TIM_SetAutoReload + * @param TIMx Timer instance + * @param AutoReload between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetAutoReload(TIM_TypeDef *TIMx, uint32_t AutoReload) +{ + WRITE_REG(TIMx->ARR, AutoReload); +} + +/** + * @brief Get the auto-reload value. + * @rmtoll ARR ARR LL_TIM_GetAutoReload + * @param TIMx Timer instance + * @retval Auto-reload value + */ +__STATIC_INLINE uint32_t LL_TIM_GetAutoReload(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->ARR)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Capture_Compare Capture Compare configuration + * @{ + */ +/** + * @brief Set the trigger of the capture/compare DMA request. + * @rmtoll CR2 CCDS LL_TIM_CC_SetDMAReqTrigger + * @param TIMx Timer instance + * @param DMAReqTrigger This parameter can be one of the following values: + * @arg @ref LL_TIM_CCDMAREQUEST_CC + * @arg @ref LL_TIM_CCDMAREQUEST_UPDATE + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_SetDMAReqTrigger(TIM_TypeDef *TIMx, uint32_t DMAReqTrigger) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_CCDS, DMAReqTrigger); +} + +/** + * @brief Get actual trigger of the capture/compare DMA request. + * @rmtoll CR2 CCDS LL_TIM_CC_GetDMAReqTrigger + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_CCDMAREQUEST_CC + * @arg @ref LL_TIM_CCDMAREQUEST_UPDATE + */ +__STATIC_INLINE uint32_t LL_TIM_CC_GetDMAReqTrigger(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR2, TIM_CR2_CCDS)); +} + +/** + * @brief Enable capture/compare channels. + * @rmtoll CCER CC1E LL_TIM_CC_EnableChannel\n + * CCER CC2E LL_TIM_CC_EnableChannel\n + * CCER CC3E LL_TIM_CC_EnableChannel\n + * CCER CC4E LL_TIM_CC_EnableChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_EnableChannel(TIM_TypeDef *TIMx, uint32_t Channels) +{ + SET_BIT(TIMx->CCER, Channels); +} + +/** + * @brief Disable capture/compare channels. + * @rmtoll CCER CC1E LL_TIM_CC_DisableChannel\n + * CCER CC2E LL_TIM_CC_DisableChannel\n + * CCER CC3E LL_TIM_CC_DisableChannel\n + * CCER CC4E LL_TIM_CC_DisableChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_DisableChannel(TIM_TypeDef *TIMx, uint32_t Channels) +{ + CLEAR_BIT(TIMx->CCER, Channels); +} + +/** + * @brief Indicate whether channel(s) is(are) enabled. + * @rmtoll CCER CC1E LL_TIM_CC_IsEnabledChannel\n + * CCER CC2E LL_TIM_CC_IsEnabledChannel\n + * CCER CC3E LL_TIM_CC_IsEnabledChannel\n + * CCER CC4E LL_TIM_CC_IsEnabledChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_CC_IsEnabledChannel(TIM_TypeDef *TIMx, uint32_t Channels) +{ + return ((READ_BIT(TIMx->CCER, Channels) == (Channels)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Output_Channel Output channel configuration + * @{ + */ +/** + * @brief Configure an output channel. + * @rmtoll CCMR1 CC1S LL_TIM_OC_ConfigOutput\n + * CCMR1 CC2S LL_TIM_OC_ConfigOutput\n + * CCMR2 CC3S LL_TIM_OC_ConfigOutput\n + * CCMR2 CC4S LL_TIM_OC_ConfigOutput\n + * CCER CC1P LL_TIM_OC_ConfigOutput\n + * CCER CC2P LL_TIM_OC_ConfigOutput\n + * CCER CC3P LL_TIM_OC_ConfigOutput\n + * CCER CC4P LL_TIM_OC_ConfigOutput\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH or @ref LL_TIM_OCPOLARITY_LOW + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_ConfigOutput(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Configuration) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_CC1S << SHIFT_TAB_OCxx[iChannel])); + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), + (Configuration & TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Define the behavior of the output reference signal OCxREF from which + * OCx and OCxN (when relevant) are derived. + * @rmtoll CCMR1 OC1M LL_TIM_OC_SetMode\n + * CCMR1 OC2M LL_TIM_OC_SetMode\n + * CCMR2 OC3M LL_TIM_OC_SetMode\n + * CCMR2 OC4M LL_TIM_OC_SetMode + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_TIM_OCMODE_FROZEN + * @arg @ref LL_TIM_OCMODE_ACTIVE + * @arg @ref LL_TIM_OCMODE_INACTIVE + * @arg @ref LL_TIM_OCMODE_TOGGLE + * @arg @ref LL_TIM_OCMODE_FORCED_INACTIVE + * @arg @ref LL_TIM_OCMODE_FORCED_ACTIVE + * @arg @ref LL_TIM_OCMODE_PWM1 + * @arg @ref LL_TIM_OCMODE_PWM2 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetMode(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Mode) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_OC1M | TIM_CCMR1_CC1S) << SHIFT_TAB_OCxx[iChannel]), Mode << SHIFT_TAB_OCxx[iChannel]); +} + +/** + * @brief Get the output compare mode of an output channel. + * @rmtoll CCMR1 OC1M LL_TIM_OC_GetMode\n + * CCMR1 OC2M LL_TIM_OC_GetMode\n + * CCMR2 OC3M LL_TIM_OC_GetMode\n + * CCMR2 OC4M LL_TIM_OC_GetMode + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCMODE_FROZEN + * @arg @ref LL_TIM_OCMODE_ACTIVE + * @arg @ref LL_TIM_OCMODE_INACTIVE + * @arg @ref LL_TIM_OCMODE_TOGGLE + * @arg @ref LL_TIM_OCMODE_FORCED_INACTIVE + * @arg @ref LL_TIM_OCMODE_FORCED_ACTIVE + * @arg @ref LL_TIM_OCMODE_PWM1 + * @arg @ref LL_TIM_OCMODE_PWM2 + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetMode(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return (READ_BIT(*pReg, ((TIM_CCMR1_OC1M | TIM_CCMR1_CC1S) << SHIFT_TAB_OCxx[iChannel])) >> SHIFT_TAB_OCxx[iChannel]); +} + +/** + * @brief Set the polarity of an output channel. + * @rmtoll CCER CC1P LL_TIM_OC_SetPolarity\n + * CCER CC2P LL_TIM_OC_SetPolarity\n + * CCER CC3P LL_TIM_OC_SetPolarity\n + * CCER CC4P LL_TIM_OC_SetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH + * @arg @ref LL_TIM_OCPOLARITY_LOW + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetPolarity(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Polarity) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), Polarity << SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Get the polarity of an output channel. + * @rmtoll CCER CC1P LL_TIM_OC_GetPolarity\n + * CCER CC2P LL_TIM_OC_GetPolarity\n + * CCER CC3P LL_TIM_OC_GetPolarity\n + * CCER CC4P LL_TIM_OC_GetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH + * @arg @ref LL_TIM_OCPOLARITY_LOW + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetPolarity(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel])) >> SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Enable fast mode for the output channel. + * @note Acts only if the channel is configured in PWM1 or PWM2 mode. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_EnableFast\n + * CCMR1 OC2FE LL_TIM_OC_EnableFast\n + * CCMR2 OC3FE LL_TIM_OC_EnableFast\n + * CCMR2 OC4FE LL_TIM_OC_EnableFast + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_EnableFast(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel])); + +} + +/** + * @brief Disable fast mode for the output channel. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_DisableFast\n + * CCMR1 OC2FE LL_TIM_OC_DisableFast\n + * CCMR2 OC3FE LL_TIM_OC_DisableFast\n + * CCMR2 OC4FE LL_TIM_OC_DisableFast + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_DisableFast(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel])); + +} + +/** + * @brief Indicates whether fast mode is enabled for the output channel. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_IsEnabledFast\n + * CCMR1 OC2FE LL_TIM_OC_IsEnabledFast\n + * CCMR2 OC3FE LL_TIM_OC_IsEnabledFast\n + * CCMR2 OC4FE LL_TIM_OC_IsEnabledFast\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledFast(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); +} + +/** + * @brief Enable compare register (TIMx_CCRx) preload for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_EnablePreload\n + * CCMR1 OC2PE LL_TIM_OC_EnablePreload\n + * CCMR2 OC3PE LL_TIM_OC_EnablePreload\n + * CCMR2 OC4PE LL_TIM_OC_EnablePreload + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_EnablePreload(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Disable compare register (TIMx_CCRx) preload for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_DisablePreload\n + * CCMR1 OC2PE LL_TIM_OC_DisablePreload\n + * CCMR2 OC3PE LL_TIM_OC_DisablePreload\n + * CCMR2 OC4PE LL_TIM_OC_DisablePreload + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_DisablePreload(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Indicates whether compare register (TIMx_CCRx) preload is enabled for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_IsEnabledPreload\n + * CCMR1 OC2PE LL_TIM_OC_IsEnabledPreload\n + * CCMR2 OC3PE LL_TIM_OC_IsEnabledPreload\n + * CCMR2 OC4PE LL_TIM_OC_IsEnabledPreload\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledPreload(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); +} + +/** + * @brief Enable clearing the output channel on an external event. + * @note This function can only be used in Output compare and PWM modes. It does not work in Forced mode. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_EnableClear\n + * CCMR1 OC2CE LL_TIM_OC_EnableClear\n + * CCMR2 OC3CE LL_TIM_OC_EnableClear\n + * CCMR2 OC4CE LL_TIM_OC_EnableClear + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_EnableClear(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Disable clearing the output channel on an external event. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_DisableClear\n + * CCMR1 OC2CE LL_TIM_OC_DisableClear\n + * CCMR2 OC3CE LL_TIM_OC_DisableClear\n + * CCMR2 OC4CE LL_TIM_OC_DisableClear + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_DisableClear(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Indicates clearing the output channel on an external event is enabled for the output channel. + * @note This function enables clearing the output channel on an external event. + * @note This function can only be used in Output compare and PWM modes. It does not work in Forced mode. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_IsEnabledClear\n + * CCMR1 OC2CE LL_TIM_OC_IsEnabledClear\n + * CCMR2 OC3CE LL_TIM_OC_IsEnabledClear\n + * CCMR2 OC4CE LL_TIM_OC_IsEnabledClear\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledClear(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); +} + +/** + * @brief Set compare value for output channel 1 (TIMx_CCR1). + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * output channel 1 is supported by a timer instance. + * @rmtoll CCR1 CCR1 LL_TIM_OC_SetCompareCH1 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH1(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR1, CompareValue); +} + +/** + * @brief Set compare value for output channel 2 (TIMx_CCR2). + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * output channel 2 is supported by a timer instance. + * @rmtoll CCR2 CCR2 LL_TIM_OC_SetCompareCH2 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH2(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR2, CompareValue); +} + +/** + * @brief Set compare value for output channel 3 (TIMx_CCR3). + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * output channel is supported by a timer instance. + * @rmtoll CCR3 CCR3 LL_TIM_OC_SetCompareCH3 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH3(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR3, CompareValue); +} + +/** + * @brief Set compare value for output channel 4 (TIMx_CCR4). + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * output channel 4 is supported by a timer instance. + * @rmtoll CCR4 CCR4 LL_TIM_OC_SetCompareCH4 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH4(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR4, CompareValue); +} + +/** + * @brief Get compare value (TIMx_CCR1) set for output channel 1. + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * output channel 1 is supported by a timer instance. + * @rmtoll CCR1 CCR1 LL_TIM_OC_GetCompareCH1 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH1(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR1)); +} + +/** + * @brief Get compare value (TIMx_CCR2) set for output channel 2. + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * output channel 2 is supported by a timer instance. + * @rmtoll CCR2 CCR2 LL_TIM_OC_GetCompareCH2 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH2(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR2)); +} + +/** + * @brief Get compare value (TIMx_CCR3) set for output channel 3. + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * output channel 3 is supported by a timer instance. + * @rmtoll CCR3 CCR3 LL_TIM_OC_GetCompareCH3 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH3(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR3)); +} + +/** + * @brief Get compare value (TIMx_CCR4) set for output channel 4. + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * output channel 4 is supported by a timer instance. + * @rmtoll CCR4 CCR4 LL_TIM_OC_GetCompareCH4 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH4(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR4)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Input_Channel Input channel configuration + * @{ + */ +/** + * @brief Configure input channel. + * @rmtoll CCMR1 CC1S LL_TIM_IC_Config\n + * CCMR1 IC1PSC LL_TIM_IC_Config\n + * CCMR1 IC1F LL_TIM_IC_Config\n + * CCMR1 CC2S LL_TIM_IC_Config\n + * CCMR1 IC2PSC LL_TIM_IC_Config\n + * CCMR1 IC2F LL_TIM_IC_Config\n + * CCMR2 CC3S LL_TIM_IC_Config\n + * CCMR2 IC3PSC LL_TIM_IC_Config\n + * CCMR2 IC3F LL_TIM_IC_Config\n + * CCMR2 CC4S LL_TIM_IC_Config\n + * CCMR2 IC4PSC LL_TIM_IC_Config\n + * CCMR2 IC4F LL_TIM_IC_Config\n + * CCER CC1P LL_TIM_IC_Config\n + * CCER CC1NP LL_TIM_IC_Config\n + * CCER CC2P LL_TIM_IC_Config\n + * CCER CC2NP LL_TIM_IC_Config\n + * CCER CC3P LL_TIM_IC_Config\n + * CCER CC3NP LL_TIM_IC_Config\n + * CCER CC4P LL_TIM_IC_Config\n + * CCER CC4NP LL_TIM_IC_Config + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI or @ref LL_TIM_ACTIVEINPUT_INDIRECTTI or @ref LL_TIM_ACTIVEINPUT_TRC + * @arg @ref LL_TIM_ICPSC_DIV1 or ... or @ref LL_TIM_ICPSC_DIV8 + * @arg @ref LL_TIM_IC_FILTER_FDIV1 or ... or @ref LL_TIM_IC_FILTER_FDIV32_N8 + * @arg @ref LL_TIM_IC_POLARITY_RISING or @ref LL_TIM_IC_POLARITY_FALLING or @ref LL_TIM_IC_POLARITY_BOTHEDGE + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_Config(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Configuration) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), + ((Configuration >> 16U) & (TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S)) << SHIFT_TAB_ICxx[iChannel]); + MODIFY_REG(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), + (Configuration & (TIM_CCER_CC1NP | TIM_CCER_CC1P)) << SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Set the active input. + * @rmtoll CCMR1 CC1S LL_TIM_IC_SetActiveInput\n + * CCMR1 CC2S LL_TIM_IC_SetActiveInput\n + * CCMR2 CC3S LL_TIM_IC_SetActiveInput\n + * CCMR2 CC4S LL_TIM_IC_SetActiveInput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICActiveInput This parameter can be one of the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_INDIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_TRC + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetActiveInput(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICActiveInput) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), (ICActiveInput >> 16U) << SHIFT_TAB_ICxx[iChannel]); +} + +/** + * @brief Get the current active input. + * @rmtoll CCMR1 CC1S LL_TIM_IC_GetActiveInput\n + * CCMR1 CC2S LL_TIM_IC_GetActiveInput\n + * CCMR2 CC3S LL_TIM_IC_GetActiveInput\n + * CCMR2 CC4S LL_TIM_IC_GetActiveInput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_INDIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_TRC + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetActiveInput(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); +} + +/** + * @brief Set the prescaler of input channel. + * @rmtoll CCMR1 IC1PSC LL_TIM_IC_SetPrescaler\n + * CCMR1 IC2PSC LL_TIM_IC_SetPrescaler\n + * CCMR2 IC3PSC LL_TIM_IC_SetPrescaler\n + * CCMR2 IC4PSC LL_TIM_IC_SetPrescaler + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICPrescaler This parameter can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICPrescaler) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel]), (ICPrescaler >> 16U) << SHIFT_TAB_ICxx[iChannel]); +} + +/** + * @brief Get the current prescaler value acting on an input channel. + * @rmtoll CCMR1 IC1PSC LL_TIM_IC_GetPrescaler\n + * CCMR1 IC2PSC LL_TIM_IC_GetPrescaler\n + * CCMR2 IC3PSC LL_TIM_IC_GetPrescaler\n + * CCMR2 IC4PSC LL_TIM_IC_GetPrescaler + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetPrescaler(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); +} + +/** + * @brief Set the input filter duration. + * @rmtoll CCMR1 IC1F LL_TIM_IC_SetFilter\n + * CCMR1 IC2F LL_TIM_IC_SetFilter\n + * CCMR2 IC3F LL_TIM_IC_SetFilter\n + * CCMR2 IC4F LL_TIM_IC_SetFilter + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICFilter This parameter can be one of the following values: + * @arg @ref LL_TIM_IC_FILTER_FDIV1 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetFilter(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICFilter) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel]), (ICFilter >> 16U) << SHIFT_TAB_ICxx[iChannel]); +} + +/** + * @brief Get the input filter duration. + * @rmtoll CCMR1 IC1F LL_TIM_IC_GetFilter\n + * CCMR1 IC2F LL_TIM_IC_GetFilter\n + * CCMR2 IC3F LL_TIM_IC_GetFilter\n + * CCMR2 IC4F LL_TIM_IC_GetFilter + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_IC_FILTER_FDIV1 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N8 + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetFilter(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); +} + +/** + * @brief Set the input channel polarity. + * @rmtoll CCER CC1P LL_TIM_IC_SetPolarity\n + * CCER CC1NP LL_TIM_IC_SetPolarity\n + * CCER CC2P LL_TIM_IC_SetPolarity\n + * CCER CC2NP LL_TIM_IC_SetPolarity\n + * CCER CC3P LL_TIM_IC_SetPolarity\n + * CCER CC3NP LL_TIM_IC_SetPolarity\n + * CCER CC4P LL_TIM_IC_SetPolarity\n + * CCER CC4NP LL_TIM_IC_SetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_IC_POLARITY_RISING + * @arg @ref LL_TIM_IC_POLARITY_FALLING + * @arg @ref LL_TIM_IC_POLARITY_BOTHEDGE + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetPolarity(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICPolarity) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), + ICPolarity << SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Get the current input channel polarity. + * @rmtoll CCER CC1P LL_TIM_IC_GetPolarity\n + * CCER CC1NP LL_TIM_IC_GetPolarity\n + * CCER CC2P LL_TIM_IC_GetPolarity\n + * CCER CC2NP LL_TIM_IC_GetPolarity\n + * CCER CC3P LL_TIM_IC_GetPolarity\n + * CCER CC3NP LL_TIM_IC_GetPolarity\n + * CCER CC4P LL_TIM_IC_GetPolarity\n + * CCER CC4NP LL_TIM_IC_GetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_IC_POLARITY_RISING + * @arg @ref LL_TIM_IC_POLARITY_FALLING + * @arg @ref LL_TIM_IC_POLARITY_BOTHEDGE + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetPolarity(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel])) >> + SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Connect the TIMx_CH1, CH2 and CH3 pins to the TI1 input (XOR combination). + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_EnableXORCombination + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_EnableXORCombination(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR2, TIM_CR2_TI1S); +} + +/** + * @brief Disconnect the TIMx_CH1, CH2 and CH3 pins from the TI1 input. + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_DisableXORCombination + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_DisableXORCombination(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR2, TIM_CR2_TI1S); +} + +/** + * @brief Indicates whether the TIMx_CH1, CH2 and CH3 pins are connectected to the TI1 input. + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_IsEnabledXORCombination + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IC_IsEnabledXORCombination(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR2, TIM_CR2_TI1S) == (TIM_CR2_TI1S)) ? 1UL : 0UL); +} + +/** + * @brief Get captured value for input channel 1. + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * input channel 1 is supported by a timer instance. + * @rmtoll CCR1 CCR1 LL_TIM_IC_GetCaptureCH1 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH1(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR1)); +} + +/** + * @brief Get captured value for input channel 2. + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * input channel 2 is supported by a timer instance. + * @rmtoll CCR2 CCR2 LL_TIM_IC_GetCaptureCH2 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH2(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR2)); +} + +/** + * @brief Get captured value for input channel 3. + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * input channel 3 is supported by a timer instance. + * @rmtoll CCR3 CCR3 LL_TIM_IC_GetCaptureCH3 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH3(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR3)); +} + +/** + * @brief Get captured value for input channel 4. + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * input channel 4 is supported by a timer instance. + * @rmtoll CCR4 CCR4 LL_TIM_IC_GetCaptureCH4 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH4(TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR4)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Clock_Selection Counter clock selection + * @{ + */ +/** + * @brief Enable external clock mode 2. + * @note When external clock mode 2 is enabled the counter is clocked by any active edge on the ETRF signal. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_EnableExternalClock + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableExternalClock(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->SMCR, TIM_SMCR_ECE); +} + +/** + * @brief Disable external clock mode 2. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_DisableExternalClock + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableExternalClock(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->SMCR, TIM_SMCR_ECE); +} + +/** + * @brief Indicate whether external clock mode 2 is enabled. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_IsEnabledExternalClock + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledExternalClock(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SMCR, TIM_SMCR_ECE) == (TIM_SMCR_ECE)) ? 1UL : 0UL); +} + +/** + * @brief Set the clock source of the counter clock. + * @note when selected clock source is external clock mode 1, the timer input + * the external clock is applied is selected by calling the @ref LL_TIM_SetTriggerInput() + * function. This timer input must be configured by calling + * the @ref LL_TIM_IC_Config() function. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode1. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR SMS LL_TIM_SetClockSource\n + * SMCR ECE LL_TIM_SetClockSource + * @param TIMx Timer instance + * @param ClockSource This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKSOURCE_INTERNAL + * @arg @ref LL_TIM_CLOCKSOURCE_EXT_MODE1 + * @arg @ref LL_TIM_CLOCKSOURCE_EXT_MODE2 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetClockSource(TIM_TypeDef *TIMx, uint32_t ClockSource) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS | TIM_SMCR_ECE, ClockSource); +} + +/** + * @brief Set the encoder interface mode. + * @note Macro IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the encoder mode. + * @rmtoll SMCR SMS LL_TIM_SetEncoderMode + * @param TIMx Timer instance + * @param EncoderMode This parameter can be one of the following values: + * @arg @ref LL_TIM_ENCODERMODE_X2_TI1 + * @arg @ref LL_TIM_ENCODERMODE_X2_TI2 + * @arg @ref LL_TIM_ENCODERMODE_X4_TI12 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetEncoderMode(TIM_TypeDef *TIMx, uint32_t EncoderMode) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS, EncoderMode); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Timer_Synchronization Timer synchronisation configuration + * @{ + */ +/** + * @brief Set the trigger output (TRGO) used for timer synchronization . + * @note Macro IS_TIM_MASTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance can operate as a master timer. + * @rmtoll CR2 MMS LL_TIM_SetTriggerOutput + * @param TIMx Timer instance + * @param TimerSynchronization This parameter can be one of the following values: + * @arg @ref LL_TIM_TRGO_RESET + * @arg @ref LL_TIM_TRGO_ENABLE + * @arg @ref LL_TIM_TRGO_UPDATE + * @arg @ref LL_TIM_TRGO_CC1IF + * @arg @ref LL_TIM_TRGO_OC1REF + * @arg @ref LL_TIM_TRGO_OC2REF + * @arg @ref LL_TIM_TRGO_OC3REF + * @arg @ref LL_TIM_TRGO_OC4REF + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetTriggerOutput(TIM_TypeDef *TIMx, uint32_t TimerSynchronization) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_MMS, TimerSynchronization); +} + +/** + * @brief Set the synchronization mode of a slave timer. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR SMS LL_TIM_SetSlaveMode + * @param TIMx Timer instance + * @param SlaveMode This parameter can be one of the following values: + * @arg @ref LL_TIM_SLAVEMODE_DISABLED + * @arg @ref LL_TIM_SLAVEMODE_RESET + * @arg @ref LL_TIM_SLAVEMODE_GATED + * @arg @ref LL_TIM_SLAVEMODE_TRIGGER + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetSlaveMode(TIM_TypeDef *TIMx, uint32_t SlaveMode) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS, SlaveMode); +} + +/** + * @brief Set the selects the trigger input to be used to synchronize the counter. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR TS LL_TIM_SetTriggerInput + * @param TIMx Timer instance + * @param TriggerInput This parameter can be one of the following values: + * @arg @ref LL_TIM_TS_ITR0 + * @arg @ref LL_TIM_TS_ITR1 + * @arg @ref LL_TIM_TS_ITR2 + * @arg @ref LL_TIM_TS_ITR3 + * @arg @ref LL_TIM_TS_TI1F_ED + * @arg @ref LL_TIM_TS_TI1FP1 + * @arg @ref LL_TIM_TS_TI2FP2 + * @arg @ref LL_TIM_TS_ETRF + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetTriggerInput(TIM_TypeDef *TIMx, uint32_t TriggerInput) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_TS, TriggerInput); +} + +/** + * @brief Enable the Master/Slave mode. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_EnableMasterSlaveMode + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableMasterSlaveMode(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->SMCR, TIM_SMCR_MSM); +} + +/** + * @brief Disable the Master/Slave mode. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_DisableMasterSlaveMode + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableMasterSlaveMode(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->SMCR, TIM_SMCR_MSM); +} + +/** + * @brief Indicates whether the Master/Slave mode is enabled. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_IsEnabledMasterSlaveMode + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledMasterSlaveMode(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SMCR, TIM_SMCR_MSM) == (TIM_SMCR_MSM)) ? 1UL : 0UL); +} + +/** + * @brief Configure the external trigger (ETR) input. + * @note Macro IS_TIM_ETR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an external trigger input. + * @rmtoll SMCR ETP LL_TIM_ConfigETR\n + * SMCR ETPS LL_TIM_ConfigETR\n + * SMCR ETF LL_TIM_ConfigETR + * @param TIMx Timer instance + * @param ETRPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_POLARITY_NONINVERTED + * @arg @ref LL_TIM_ETR_POLARITY_INVERTED + * @param ETRPrescaler This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_PRESCALER_DIV1 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV2 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV4 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV8 + * @param ETRFilter This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_FILTER_FDIV1 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigETR(TIM_TypeDef *TIMx, uint32_t ETRPolarity, uint32_t ETRPrescaler, + uint32_t ETRFilter) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_ETP | TIM_SMCR_ETPS | TIM_SMCR_ETF, ETRPolarity | ETRPrescaler | ETRFilter); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_DMA_Burst_Mode DMA burst mode configuration + * @{ + */ +/** + * @brief Configures the timer DMA burst feature. + * @note Macro IS_TIM_DMABURST_INSTANCE(TIMx) can be used to check whether or + * not a timer instance supports the DMA burst mode. + * @rmtoll DCR DBL LL_TIM_ConfigDMABurst\n + * DCR DBA LL_TIM_ConfigDMABurst + * @param TIMx Timer instance + * @param DMABurstBaseAddress This parameter can be one of the following values: + * @arg @ref LL_TIM_DMABURST_BASEADDR_CR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_SMCR + * @arg @ref LL_TIM_DMABURST_BASEADDR_DIER + * @arg @ref LL_TIM_DMABURST_BASEADDR_SR + * @arg @ref LL_TIM_DMABURST_BASEADDR_EGR + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCMR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCMR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCER + * @arg @ref LL_TIM_DMABURST_BASEADDR_CNT + * @arg @ref LL_TIM_DMABURST_BASEADDR_PSC + * @arg @ref LL_TIM_DMABURST_BASEADDR_ARR + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR3 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR4 + * @arg @ref LL_TIM_DMABURST_BASEADDR_OR + * @param DMABurstLength This parameter can be one of the following values: + * @arg @ref LL_TIM_DMABURST_LENGTH_1TRANSFER + * @arg @ref LL_TIM_DMABURST_LENGTH_2TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_3TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_4TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_5TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_6TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_7TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_8TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_9TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_10TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_11TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_12TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_13TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_14TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_15TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_16TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_17TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_18TRANSFERS + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigDMABurst(TIM_TypeDef *TIMx, uint32_t DMABurstBaseAddress, uint32_t DMABurstLength) +{ + MODIFY_REG(TIMx->DCR, (TIM_DCR_DBL | TIM_DCR_DBA), (DMABurstBaseAddress | DMABurstLength)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Timer_Inputs_Remapping Timer input remapping + * @{ + */ +/** + * @brief Remap TIM inputs (input channel, internal/external triggers). + * @note Macro IS_TIM_REMAP_INSTANCE(TIMx) can be used to check whether or not + * a some timer inputs can be remapped. + * @rmtoll TIM2_OR ETR_RMP LL_TIM_SetRemap\n + * TIM2_OR TI4_RMP LL_TIM_SetRemap\n + * TIM21_OR ETR_RMP LL_TIM_SetRemap\n + * TIM21_OR TI1_RMP LL_TIM_SetRemap\n + * TIM21_OR TI2_RMP LL_TIM_SetRemap\n + * TIM22_OR ETR_RMP LL_TIM_SetRemap\n + * TIM22_OR TI1_RMP LL_TIM_SetRemap\n + * TIM3_OR ETR_RMP LL_TIM_SetRemap\n + * TIM3_OR TI1_RMP LL_TIM_SetRemap\n + * TIM3_OR TI2_RMP LL_TIM_SetRemap\n + * TIM3_OR TI4_RMP LL_TIM_SetRemap + * @param TIMx Timer instance + * @param Remap Remap params depends on the TIMx. Description available only + * in CHM version of the User Manual (not in .pdf). + * Otherwise see Reference Manual description of OR registers. + * + * Below description summarizes "Timer Instance" and "Remap" param combinations: + * + * TIM2: any combination of ETR_RMP, TI4_RMP where + * + * . . ETR_RMP can be one of the following values + * @arg @ref LL_TIM_TIM2_ETR_RMP_GPIO + * @arg @ref LL_TIM_TIM2_ETR_RMP_HSI (*) + * @arg @ref LL_TIM_TIM2_ETR_RMP_HSI48 (*) + * @arg @ref LL_TIM_TIM2_ETR_RMP_LSE + * @arg @ref LL_TIM_TIM2_ETR_RMP_COMP2 + * @arg @ref LL_TIM_TIM2_ETR_RMP_COMP1 + * + * . . TI4_RMP can be one of the following values + * @arg @ref LL_TIM_TIM2_TI4_RMP_GPIO + * @arg @ref LL_TIM_TIM2_TI4_RMP_COMP1 + * @arg @ref LL_TIM_TIM2_TI4_RMP_COMP2 + * + * TIM3: any combination of the following values (**) + * + * . . ETR_RMP can be one of the following values (**) + * @arg @ref LL_TIM_TIM3_ETR_RMP_GPIO + * @arg @ref LL_TIM_TIM3_ETR_RMP_HSI48DIV6 + * + * . . TI_RMP_TI1 can be one of the following values (**) + * @arg @ref LL_TIM_TIM3_TI_RMP_TI1_USB_SOF + * @arg @ref LL_TIM_TIM3_TI_RMP_TI1_GPIO + * + * . . TI_RMP_TI2 can be one of the following values (**) + * @arg @ref LL_TIM_TIM3_TI_RMP_TI2_GPIO_DEF + * @arg @ref LL_TIM_TIM3_TI_RMP_TI2_GPIOB5_AF4 + * + * . . TI_RMP_TI4 can be one of the following values (**) + * @arg @ref LL_TIM_TIM3_TI_RMP_TI4_GPIO_DEF + * @arg @ref LL_TIM_TIM3_TI_RMP_TI4_GPIOC9_AF2 + * + * TIM21: any combination of ETR_RMP, TI1_RMP, TI2_RMP where + * + * . . ETR_RMP can be one of the following values + * @arg @ref LL_TIM_TIM21_ETR_RMP_GPIO + * @arg @ref LL_TIM_TIM21_ETR_RMP_COMP2 + * @arg @ref LL_TIM_TIM21_ETR_RMP_COMP1 + * @arg @ref LL_TIM_TIM21_ETR_RMP_LSE + * + * . . TI1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM21_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM21_TI1_RMP_RTC_WK + * @arg @ref LL_TIM_TIM21_TI1_RMP_HSE_RTC + * @arg @ref LL_TIM_TIM21_TI1_RMP_MSI + * @arg @ref LL_TIM_TIM21_TI1_RMP_LSE + * @arg @ref LL_TIM_TIM21_TI1_RMP_LSI + * @arg @ref LL_TIM_TIM21_TI1_RMP_COMP1 + * @arg @ref LL_TIM_TIM21_TI1_RMP_MCO + * + * . . TI2_RMP can be one of the following values + * @arg @ref LL_TIM_TIM21_TI2_RMP_GPIO + * @arg @ref LL_TIM_TIM21_TI2_RMP_COMP2 + * + * TIM22: any combination of ETR_RMP, TI1_RMP where (**) + * + * . . ETR_RMP can be one of the following values (**) + * @arg @ref LL_TIM_TIM22_ETR_RMP_GPIO + * @arg @ref LL_TIM_TIM22_ETR_RMP_COMP2 + * @arg @ref LL_TIM_TIM22_ETR_RMP_COMP1 + * @arg @ref LL_TIM_TIM22_ETR_RMP_LSE + * + * . . TI1_RMP can be one of the following values (**) + * @arg @ref LL_TIM_TIM22_TI1_RMP_GPIO1 + * @arg @ref LL_TIM_TIM22_TI1_RMP_COMP2 + * @arg @ref LL_TIM_TIM22_TI1_RMP_COMP1 + * @arg @ref LL_TIM_TIM22_TI1_RMP_GPIO2 + * + * (*) Value not defined in all devices. \n + * (*) Register not available in all devices. + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetRemap(TIM_TypeDef *TIMx, uint32_t Remap) +{ + MODIFY_REG(TIMx->OR, (Remap >> TIMx_OR_RMP_SHIFT), (Remap & TIMx_OR_RMP_MASK)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_FLAG_Management FLAG-Management + * @{ + */ +/** + * @brief Clear the update interrupt flag (UIF). + * @rmtoll SR UIF LL_TIM_ClearFlag_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_UPDATE(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_UIF)); +} + +/** + * @brief Indicate whether update interrupt flag (UIF) is set (update interrupt is pending). + * @rmtoll SR UIF LL_TIM_IsActiveFlag_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_UPDATE(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_UIF) == (TIM_SR_UIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 1 interrupt flag (CC1F). + * @rmtoll SR CC1IF LL_TIM_ClearFlag_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC1(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC1IF)); +} + +/** + * @brief Indicate whether Capture/Compare 1 interrupt flag (CC1F) is set (Capture/Compare 1 interrupt is pending). + * @rmtoll SR CC1IF LL_TIM_IsActiveFlag_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC1IF) == (TIM_SR_CC1IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 2 interrupt flag (CC2F). + * @rmtoll SR CC2IF LL_TIM_ClearFlag_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC2(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC2IF)); +} + +/** + * @brief Indicate whether Capture/Compare 2 interrupt flag (CC2F) is set (Capture/Compare 2 interrupt is pending). + * @rmtoll SR CC2IF LL_TIM_IsActiveFlag_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC2IF) == (TIM_SR_CC2IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 3 interrupt flag (CC3F). + * @rmtoll SR CC3IF LL_TIM_ClearFlag_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC3(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC3IF)); +} + +/** + * @brief Indicate whether Capture/Compare 3 interrupt flag (CC3F) is set (Capture/Compare 3 interrupt is pending). + * @rmtoll SR CC3IF LL_TIM_IsActiveFlag_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC3IF) == (TIM_SR_CC3IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 4 interrupt flag (CC4F). + * @rmtoll SR CC4IF LL_TIM_ClearFlag_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC4(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC4IF)); +} + +/** + * @brief Indicate whether Capture/Compare 4 interrupt flag (CC4F) is set (Capture/Compare 4 interrupt is pending). + * @rmtoll SR CC4IF LL_TIM_IsActiveFlag_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC4IF) == (TIM_SR_CC4IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the trigger interrupt flag (TIF). + * @rmtoll SR TIF LL_TIM_ClearFlag_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_TRIG(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_TIF)); +} + +/** + * @brief Indicate whether trigger interrupt flag (TIF) is set (trigger interrupt is pending). + * @rmtoll SR TIF LL_TIM_IsActiveFlag_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_TRIG(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_TIF) == (TIM_SR_TIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 1 over-capture interrupt flag (CC1OF). + * @rmtoll SR CC1OF LL_TIM_ClearFlag_CC1OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC1OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC1OF)); +} + +/** + * @brief Indicate whether Capture/Compare 1 over-capture interrupt flag (CC1OF) is set (Capture/Compare 1 interrupt is pending). + * @rmtoll SR CC1OF LL_TIM_IsActiveFlag_CC1OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1OVR(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC1OF) == (TIM_SR_CC1OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 2 over-capture interrupt flag (CC2OF). + * @rmtoll SR CC2OF LL_TIM_ClearFlag_CC2OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC2OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC2OF)); +} + +/** + * @brief Indicate whether Capture/Compare 2 over-capture interrupt flag (CC2OF) is set (Capture/Compare 2 over-capture interrupt is pending). + * @rmtoll SR CC2OF LL_TIM_IsActiveFlag_CC2OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2OVR(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC2OF) == (TIM_SR_CC2OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 3 over-capture interrupt flag (CC3OF). + * @rmtoll SR CC3OF LL_TIM_ClearFlag_CC3OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC3OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC3OF)); +} + +/** + * @brief Indicate whether Capture/Compare 3 over-capture interrupt flag (CC3OF) is set (Capture/Compare 3 over-capture interrupt is pending). + * @rmtoll SR CC3OF LL_TIM_IsActiveFlag_CC3OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3OVR(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC3OF) == (TIM_SR_CC3OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 4 over-capture interrupt flag (CC4OF). + * @rmtoll SR CC4OF LL_TIM_ClearFlag_CC4OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC4OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC4OF)); +} + +/** + * @brief Indicate whether Capture/Compare 4 over-capture interrupt flag (CC4OF) is set (Capture/Compare 4 over-capture interrupt is pending). + * @rmtoll SR CC4OF LL_TIM_IsActiveFlag_CC4OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4OVR(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC4OF) == (TIM_SR_CC4OF)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_IT_Management IT-Management + * @{ + */ +/** + * @brief Enable update interrupt (UIE). + * @rmtoll DIER UIE LL_TIM_EnableIT_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_UPDATE(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_UIE); +} + +/** + * @brief Disable update interrupt (UIE). + * @rmtoll DIER UIE LL_TIM_DisableIT_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_UPDATE(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_UIE); +} + +/** + * @brief Indicates whether the update interrupt (UIE) is enabled. + * @rmtoll DIER UIE LL_TIM_IsEnabledIT_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_UPDATE(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_UIE) == (TIM_DIER_UIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 1 interrupt (CC1IE). + * @rmtoll DIER CC1IE LL_TIM_EnableIT_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC1(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC1IE); +} + +/** + * @brief Disable capture/compare 1 interrupt (CC1IE). + * @rmtoll DIER CC1IE LL_TIM_DisableIT_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC1(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC1IE); +} + +/** + * @brief Indicates whether the capture/compare 1 interrupt (CC1IE) is enabled. + * @rmtoll DIER CC1IE LL_TIM_IsEnabledIT_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC1(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC1IE) == (TIM_DIER_CC1IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 2 interrupt (CC2IE). + * @rmtoll DIER CC2IE LL_TIM_EnableIT_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC2IE); +} + +/** + * @brief Disable capture/compare 2 interrupt (CC2IE). + * @rmtoll DIER CC2IE LL_TIM_DisableIT_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC2(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC2IE); +} + +/** + * @brief Indicates whether the capture/compare 2 interrupt (CC2IE) is enabled. + * @rmtoll DIER CC2IE LL_TIM_IsEnabledIT_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC2(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC2IE) == (TIM_DIER_CC2IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 3 interrupt (CC3IE). + * @rmtoll DIER CC3IE LL_TIM_EnableIT_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC3(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC3IE); +} + +/** + * @brief Disable capture/compare 3 interrupt (CC3IE). + * @rmtoll DIER CC3IE LL_TIM_DisableIT_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC3(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC3IE); +} + +/** + * @brief Indicates whether the capture/compare 3 interrupt (CC3IE) is enabled. + * @rmtoll DIER CC3IE LL_TIM_IsEnabledIT_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC3(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC3IE) == (TIM_DIER_CC3IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 4 interrupt (CC4IE). + * @rmtoll DIER CC4IE LL_TIM_EnableIT_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC4(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC4IE); +} + +/** + * @brief Disable capture/compare 4 interrupt (CC4IE). + * @rmtoll DIER CC4IE LL_TIM_DisableIT_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC4(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC4IE); +} + +/** + * @brief Indicates whether the capture/compare 4 interrupt (CC4IE) is enabled. + * @rmtoll DIER CC4IE LL_TIM_IsEnabledIT_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC4(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC4IE) == (TIM_DIER_CC4IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable trigger interrupt (TIE). + * @rmtoll DIER TIE LL_TIM_EnableIT_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_TRIG(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_TIE); +} + +/** + * @brief Disable trigger interrupt (TIE). + * @rmtoll DIER TIE LL_TIM_DisableIT_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_TRIG(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_TIE); +} + +/** + * @brief Indicates whether the trigger interrupt (TIE) is enabled. + * @rmtoll DIER TIE LL_TIM_IsEnabledIT_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_TRIG(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_TIE) == (TIM_DIER_TIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_DMA_Management DMA-Management + * @{ + */ +/** + * @brief Enable update DMA request (UDE). + * @rmtoll DIER UDE LL_TIM_EnableDMAReq_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_UPDATE(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_UDE); +} + +/** + * @brief Disable update DMA request (UDE). + * @rmtoll DIER UDE LL_TIM_DisableDMAReq_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_UPDATE(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_UDE); +} + +/** + * @brief Indicates whether the update DMA request (UDE) is enabled. + * @rmtoll DIER UDE LL_TIM_IsEnabledDMAReq_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_UPDATE(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_UDE) == (TIM_DIER_UDE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 1 DMA request (CC1DE). + * @rmtoll DIER CC1DE LL_TIM_EnableDMAReq_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC1(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC1DE); +} + +/** + * @brief Disable capture/compare 1 DMA request (CC1DE). + * @rmtoll DIER CC1DE LL_TIM_DisableDMAReq_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC1(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC1DE); +} + +/** + * @brief Indicates whether the capture/compare 1 DMA request (CC1DE) is enabled. + * @rmtoll DIER CC1DE LL_TIM_IsEnabledDMAReq_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC1(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC1DE) == (TIM_DIER_CC1DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 2 DMA request (CC2DE). + * @rmtoll DIER CC2DE LL_TIM_EnableDMAReq_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC2DE); +} + +/** + * @brief Disable capture/compare 2 DMA request (CC2DE). + * @rmtoll DIER CC2DE LL_TIM_DisableDMAReq_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC2(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC2DE); +} + +/** + * @brief Indicates whether the capture/compare 2 DMA request (CC2DE) is enabled. + * @rmtoll DIER CC2DE LL_TIM_IsEnabledDMAReq_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC2(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC2DE) == (TIM_DIER_CC2DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 3 DMA request (CC3DE). + * @rmtoll DIER CC3DE LL_TIM_EnableDMAReq_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC3(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC3DE); +} + +/** + * @brief Disable capture/compare 3 DMA request (CC3DE). + * @rmtoll DIER CC3DE LL_TIM_DisableDMAReq_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC3(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC3DE); +} + +/** + * @brief Indicates whether the capture/compare 3 DMA request (CC3DE) is enabled. + * @rmtoll DIER CC3DE LL_TIM_IsEnabledDMAReq_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC3(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC3DE) == (TIM_DIER_CC3DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 4 DMA request (CC4DE). + * @rmtoll DIER CC4DE LL_TIM_EnableDMAReq_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC4(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC4DE); +} + +/** + * @brief Disable capture/compare 4 DMA request (CC4DE). + * @rmtoll DIER CC4DE LL_TIM_DisableDMAReq_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC4(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC4DE); +} + +/** + * @brief Indicates whether the capture/compare 4 DMA request (CC4DE) is enabled. + * @rmtoll DIER CC4DE LL_TIM_IsEnabledDMAReq_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC4(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC4DE) == (TIM_DIER_CC4DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable trigger interrupt (TDE). + * @rmtoll DIER TDE LL_TIM_EnableDMAReq_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_TRIG(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_TDE); +} + +/** + * @brief Disable trigger interrupt (TDE). + * @rmtoll DIER TDE LL_TIM_DisableDMAReq_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_TRIG(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_TDE); +} + +/** + * @brief Indicates whether the trigger interrupt (TDE) is enabled. + * @rmtoll DIER TDE LL_TIM_IsEnabledDMAReq_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_TRIG(TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_TDE) == (TIM_DIER_TDE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_EVENT_Management EVENT-Management + * @{ + */ +/** + * @brief Generate an update event. + * @rmtoll EGR UG LL_TIM_GenerateEvent_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_UPDATE(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_UG); +} + +/** + * @brief Generate Capture/Compare 1 event. + * @rmtoll EGR CC1G LL_TIM_GenerateEvent_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC1(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC1G); +} + +/** + * @brief Generate Capture/Compare 2 event. + * @rmtoll EGR CC2G LL_TIM_GenerateEvent_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC2G); +} + +/** + * @brief Generate Capture/Compare 3 event. + * @rmtoll EGR CC3G LL_TIM_GenerateEvent_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC3(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC3G); +} + +/** + * @brief Generate Capture/Compare 4 event. + * @rmtoll EGR CC4G LL_TIM_GenerateEvent_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC4(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC4G); +} + +/** + * @brief Generate trigger event. + * @rmtoll EGR TG LL_TIM_GenerateEvent_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_TRIG(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_TG); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_EF_Init Initialisation and deinitialisation functions + * @{ + */ + +ErrorStatus LL_TIM_DeInit(TIM_TypeDef *TIMx); +void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct); +ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, LL_TIM_InitTypeDef *TIM_InitStruct); +void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct); +ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct); +void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct); +void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); +ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* TIM1 || TIM3 || TIM21 || TIM22 || TIM6 || TIM7 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L0xx_LL_TIM_H */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/fw/Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h b/fw/Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h index e6861f0..129bd8b 100644 --- a/fw/Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h +++ b/fw/Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h @@ -223,7 +223,6 @@ __STATIC_INLINE void LL_InitTick(uint32_t HCLKFrequency, uint32_t Ticks) SysTick->LOAD = (uint32_t)((HCLKFrequency / Ticks) - 1UL); /* set reload register */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */ } diff --git a/fw/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c b/fw/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c new file mode 100644 index 0000000..08e5dca --- /dev/null +++ b/fw/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c @@ -0,0 +1,847 @@ +/** + ****************************************************************************** + * @file stm32l0xx_ll_tim.c + * @author MCD Application Team + * @brief TIM LL module driver. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l0xx_ll_tim.h" +#include "stm32l0xx_ll_bus.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32L0xx_LL_Driver + * @{ + */ + +#if defined (TIM2) || defined (TIM3) || defined (TIM21) || defined (TIM22) || defined (TIM6) || defined (TIM7) + +/** @addtogroup TIM_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup TIM_LL_Private_Macros + * @{ + */ +#define IS_LL_TIM_COUNTERMODE(__VALUE__) (((__VALUE__) == LL_TIM_COUNTERMODE_UP) \ + || ((__VALUE__) == LL_TIM_COUNTERMODE_DOWN) \ + || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP) \ + || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_DOWN) \ + || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP_DOWN)) + +#define IS_LL_TIM_CLOCKDIVISION(__VALUE__) (((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV1) \ + || ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV2) \ + || ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV4)) + +#define IS_LL_TIM_OCMODE(__VALUE__) (((__VALUE__) == LL_TIM_OCMODE_FROZEN) \ + || ((__VALUE__) == LL_TIM_OCMODE_ACTIVE) \ + || ((__VALUE__) == LL_TIM_OCMODE_INACTIVE) \ + || ((__VALUE__) == LL_TIM_OCMODE_TOGGLE) \ + || ((__VALUE__) == LL_TIM_OCMODE_FORCED_INACTIVE) \ + || ((__VALUE__) == LL_TIM_OCMODE_FORCED_ACTIVE) \ + || ((__VALUE__) == LL_TIM_OCMODE_PWM1) \ + || ((__VALUE__) == LL_TIM_OCMODE_PWM2)) + +#define IS_LL_TIM_OCSTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCSTATE_DISABLE) \ + || ((__VALUE__) == LL_TIM_OCSTATE_ENABLE)) + +#define IS_LL_TIM_OCPOLARITY(__VALUE__) (((__VALUE__) == LL_TIM_OCPOLARITY_HIGH) \ + || ((__VALUE__) == LL_TIM_OCPOLARITY_LOW)) + +#define IS_LL_TIM_ACTIVEINPUT(__VALUE__) (((__VALUE__) == LL_TIM_ACTIVEINPUT_DIRECTTI) \ + || ((__VALUE__) == LL_TIM_ACTIVEINPUT_INDIRECTTI) \ + || ((__VALUE__) == LL_TIM_ACTIVEINPUT_TRC)) + +#define IS_LL_TIM_ICPSC(__VALUE__) (((__VALUE__) == LL_TIM_ICPSC_DIV1) \ + || ((__VALUE__) == LL_TIM_ICPSC_DIV2) \ + || ((__VALUE__) == LL_TIM_ICPSC_DIV4) \ + || ((__VALUE__) == LL_TIM_ICPSC_DIV8)) + +#define IS_LL_TIM_IC_FILTER(__VALUE__) (((__VALUE__) == LL_TIM_IC_FILTER_FDIV1) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N2) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N4) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N8) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N6) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N8) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N6) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N8) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N6) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N8) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N5) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N6) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N8) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N5) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N6) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N8)) + +#define IS_LL_TIM_IC_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \ + || ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING) \ + || ((__VALUE__) == LL_TIM_IC_POLARITY_BOTHEDGE)) + +#define IS_LL_TIM_ENCODERMODE(__VALUE__) (((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI1) \ + || ((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI2) \ + || ((__VALUE__) == LL_TIM_ENCODERMODE_X4_TI12)) + +#define IS_LL_TIM_IC_POLARITY_ENCODER(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \ + || ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING)) +/** + * @} + */ + + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup TIM_LL_Private_Functions TIM Private Functions + * @{ + */ +static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIM_LL_Exported_Functions + * @{ + */ + +/** @addtogroup TIM_LL_EF_Init + * @{ + */ + +/** + * @brief Set TIMx registers to their reset values. + * @param TIMx Timer instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: invalid TIMx instance + */ +ErrorStatus LL_TIM_DeInit(TIM_TypeDef *TIMx) +{ + ErrorStatus result = SUCCESS; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(TIMx)); + + if (TIMx == TIM2) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM2); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM2); + } +#if defined(TIM3) + else if (TIMx == TIM3) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM3); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM3); + } +#endif /* TIM3 */ +#if defined(TIM6) + else if (TIMx == TIM6) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM6); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM6); + } +#endif /* TIM6 */ +#if defined(TIM7) + else if (TIMx == TIM7) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM7); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM7); + } +#endif /* TIM7 */ + else if (TIMx == TIM21) + { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM21); + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM21); + } +#if defined(TIM22) + else if (TIMx == TIM22) + { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM22); + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM22); + } +#endif /* TIM22 */ + else + { + result = ERROR; + } + + return result; +} + +/** + * @brief Set the fields of the time base unit configuration data structure + * to their default values. + * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (time base unit configuration data structure) + * @retval None + */ +void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct) +{ + /* Set the default configuration */ + TIM_InitStruct->Prescaler = (uint16_t)0x0000; + TIM_InitStruct->CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct->Autoreload = 0xFFFFFFFFU; + TIM_InitStruct->ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; +} + +/** + * @brief Configure the TIMx time base unit. + * @param TIMx Timer Instance + * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (TIMx time base unit configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, LL_TIM_InitTypeDef *TIM_InitStruct) +{ + uint32_t tmpcr1; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_COUNTERMODE(TIM_InitStruct->CounterMode)); + assert_param(IS_LL_TIM_CLOCKDIVISION(TIM_InitStruct->ClockDivision)); + + tmpcr1 = LL_TIM_ReadReg(TIMx, CR1); + + if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx)) + { + /* Select the Counter Mode */ + MODIFY_REG(tmpcr1, (TIM_CR1_DIR | TIM_CR1_CMS), TIM_InitStruct->CounterMode); + } + + if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx)) + { + /* Set the clock division */ + MODIFY_REG(tmpcr1, TIM_CR1_CKD, TIM_InitStruct->ClockDivision); + } + + /* Write to TIMx CR1 */ + LL_TIM_WriteReg(TIMx, CR1, tmpcr1); + + /* Set the Autoreload value */ + LL_TIM_SetAutoReload(TIMx, TIM_InitStruct->Autoreload); + + /* Set the Prescaler value */ + LL_TIM_SetPrescaler(TIMx, TIM_InitStruct->Prescaler); + /* Generate an update event to reload the Prescaler + and the repetition counter value (if applicable) immediately */ + LL_TIM_GenerateEvent_UPDATE(TIMx); + + return SUCCESS; +} + +/** + * @brief Set the fields of the TIMx output channel configuration data + * structure to their default values. + * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (the output channel configuration data structure) + * @retval None + */ +void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct) +{ + /* Set the default configuration */ + TIM_OC_InitStruct->OCMode = LL_TIM_OCMODE_FROZEN; + TIM_OC_InitStruct->OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct->CompareValue = 0x00000000U; + TIM_OC_InitStruct->OCPolarity = LL_TIM_OCPOLARITY_HIGH; +} + +/** + * @brief Configure the TIMx output channel. + * @param TIMx Timer Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (TIMx output channel configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx output channel is initialized + * - ERROR: TIMx output channel is not initialized + */ +ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct) +{ + ErrorStatus result = ERROR; + + switch (Channel) + { + case LL_TIM_CHANNEL_CH1: + result = OC1Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH2: + result = OC2Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH3: + result = OC3Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH4: + result = OC4Config(TIMx, TIM_OC_InitStruct); + break; + default: + break; + } + + return result; +} + +/** + * @brief Set the fields of the TIMx input channel configuration data + * structure to their default values. + * @param TIM_ICInitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (the input channel configuration data structure) + * @retval None + */ +void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Set the default configuration */ + TIM_ICInitStruct->ICPolarity = LL_TIM_IC_POLARITY_RISING; + TIM_ICInitStruct->ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; + TIM_ICInitStruct->ICPrescaler = LL_TIM_ICPSC_DIV1; + TIM_ICInitStruct->ICFilter = LL_TIM_IC_FILTER_FDIV1; +} + +/** + * @brief Configure the TIMx input channel. + * @param TIMx Timer Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param TIM_IC_InitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (TIMx input channel configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx output channel is initialized + * - ERROR: TIMx output channel is not initialized + */ +ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct) +{ + ErrorStatus result = ERROR; + + switch (Channel) + { + case LL_TIM_CHANNEL_CH1: + result = IC1Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH2: + result = IC2Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH3: + result = IC3Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH4: + result = IC4Config(TIMx, TIM_IC_InitStruct); + break; + default: + break; + } + + return result; +} + +/** + * @brief Fills each TIM_EncoderInitStruct field with its default value + * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (encoder interface configuration data structure) + * @retval None + */ +void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct) +{ + /* Set the default configuration */ + TIM_EncoderInitStruct->EncoderMode = LL_TIM_ENCODERMODE_X2_TI1; + TIM_EncoderInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING; + TIM_EncoderInitStruct->IC1ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; + TIM_EncoderInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1; + TIM_EncoderInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1; + TIM_EncoderInitStruct->IC2Polarity = LL_TIM_IC_POLARITY_RISING; + TIM_EncoderInitStruct->IC2ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; + TIM_EncoderInitStruct->IC2Prescaler = LL_TIM_ICPSC_DIV1; + TIM_EncoderInitStruct->IC2Filter = LL_TIM_IC_FILTER_FDIV1; +} + +/** + * @brief Configure the encoder interface of the timer instance. + * @param TIMx Timer Instance + * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (TIMx encoder interface configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_ENCODERMODE(TIM_EncoderInitStruct->EncoderMode)); + assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC1Polarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC1ActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC1Prescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC1Filter)); + assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC2Polarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC2ActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC2Prescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC2Filter)); + + /* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */ + TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Configure TI1 */ + tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1ActiveInput >> 16U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Filter >> 16U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Prescaler >> 16U); + + /* Configure TI2 */ + tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2ActiveInput >> 8U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Filter >> 8U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Prescaler >> 8U); + + /* Set TI1 and TI2 polarity and enable TI1 and TI2 */ + tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC1Polarity); + tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC2Polarity << 4U); + tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E); + + /* Set encoder mode */ + LL_TIM_SetEncoderMode(TIMx, TIM_EncoderInitStruct->EncoderMode); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup TIM_LL_Private_Functions TIM Private Functions + * @brief Private functions + * @{ + */ +/** + * @brief Configure the TIMx output channel 1. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 1 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + + /* Disable the Channel 1: Reset the CC1E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC1E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC1S); + + /* Set the Output Compare Mode */ + MODIFY_REG(tmpccmr1, TIM_CCMR1_OC1M, TIM_OCInitStruct->OCMode); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC1P, TIM_OCInitStruct->OCPolarity); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC1E, TIM_OCInitStruct->OCState); + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH1(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 2. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 2 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + + /* Disable the Channel 2: Reset the CC2E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC2E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC2S); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr1, TIM_CCMR1_OC2M, TIM_OCInitStruct->OCMode << 8U); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC2P, TIM_OCInitStruct->OCPolarity << 4U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC2E, TIM_OCInitStruct->OCState << 4U); + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH2(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 3. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 3 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + + /* Disable the Channel 3: Reset the CC3E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC3E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC3S); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr2, TIM_CCMR2_OC3M, TIM_OCInitStruct->OCMode); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC3P, TIM_OCInitStruct->OCPolarity << 8U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC3E, TIM_OCInitStruct->OCState << 8U); + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR2 */ + LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH3(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 4. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 4 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + + /* Disable the Channel 4: Reset the CC4E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC4E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC4S); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr2, TIM_CCMR2_OC4M, TIM_OCInitStruct->OCMode << 8U); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC4P, TIM_OCInitStruct->OCPolarity << 12U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC4E, TIM_OCInitStruct->OCState << 12U); + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR2 */ + LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH4(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + + +/** + * @brief Configure the TIMx input channel 1. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 1 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC1E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR1, + (TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U); + + /* Select the Polarity and set the CC1E Bit */ + MODIFY_REG(TIMx->CCER, + (TIM_CCER_CC1P | TIM_CCER_CC1NP), + (TIM_ICInitStruct->ICPolarity | TIM_CCER_CC1E)); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 2. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 2 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC2E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR1, + (TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U); + + /* Select the Polarity and set the CC2E Bit */ + MODIFY_REG(TIMx->CCER, + (TIM_CCER_CC2P | TIM_CCER_CC2NP), + ((TIM_ICInitStruct->ICPolarity << 4U) | TIM_CCER_CC2E)); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 3. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 3 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC3E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR2, + (TIM_CCMR2_CC3S | TIM_CCMR2_IC3F | TIM_CCMR2_IC3PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U); + + /* Select the Polarity and set the CC3E Bit */ + MODIFY_REG(TIMx->CCER, + (TIM_CCER_CC3P | TIM_CCER_CC3NP), + ((TIM_ICInitStruct->ICPolarity << 8U) | TIM_CCER_CC3E)); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 4. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 4 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC4E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR2, + (TIM_CCMR2_CC4S | TIM_CCMR2_IC4F | TIM_CCMR2_IC4PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U); + + /* Select the Polarity and set the CC2E Bit */ + MODIFY_REG(TIMx->CCER, + (TIM_CCER_CC4P | TIM_CCER_CC4NP), + ((TIM_ICInitStruct->ICPolarity << 12U) | TIM_CCER_CC4E)); + + return SUCCESS; +} + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* TIM1 || TIM3 || TIM21 || TIM22 || TIM6 || TIM7 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/fw/iaq_wired_sensor.ioc b/fw/iaq_wired_sensor.ioc index 5978da7..004d448 100644 --- a/fw/iaq_wired_sensor.ioc +++ b/fw/iaq_wired_sensor.ioc @@ -8,110 +8,119 @@ ProjectManager.ProjectFileName=iaq_wired_sensor.ioc ProjectManager.KeepUserCode=true PA10.Mode=I2C Mcu.UserName=STM32L011F4Ux -Mcu.PinsNb=10 +Mcu.PinsNb=12 ProjectManager.NoMain=false +TIM21.IPParameters=Prescaler,Period,AutoReloadPreload,ClockDivision PA0-CK_IN.Mode=Asynchronous -RCC.LPUARTFreq_Value=2097000 -RCC.PLLCLKFreq_Value=24000000 -ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-LL-true,2-MX_DMA_Init-DMA-false-LL-true,3-SystemClock_Config-RCC-false-LL-false,4-MX_I2C1_Init-I2C1-false-LL-true,5-MX_LPUART1_UART_Init-LPUART1-false-LL-true -Dma.LPUART1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE +RCC.LPUARTFreq_Value=12000000 +RCC.PLLCLKFreq_Value=12000000 +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-LL-true,2-SystemClock_Config-RCC-false-LL-false,3-MX_I2C1_Init-I2C1-false-LL-true,4-MX_LPUART1_UART_Init-LPUART1-false-LL-true,5-MX_TIM21_Init-TIM21-false-LL-true RCC.RTCFreq_Value=37000 -LPUART1.WordLength=UART_WORDLENGTH_8B +TIM21.ClockDivision=TIM_CLOCKDIVISION_DIV1 +LPUART1.WordLength=UART_WORDLENGTH_9B ProjectManager.DefaultFWLocation=true -PA6.GPIO_Label=LED_G PA6.PinState=GPIO_PIN_SET -RCC.USART2Freq_Value=2097000 -Dma.LPUART1_RX.0.Direction=DMA_PERIPH_TO_MEMORY -Dma.LPUART1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority +PA6.GPIO_Label=LED_G +RCC.USART2Freq_Value=12000000 NVIC.SVC_IRQn=true\:0\:0\:false\:false\:true\:false\:false ProjectManager.DeletePrevious=true +RCC.TimerFreq_Value=12000000 PA5.PinState=GPIO_PIN_SET -Dma.LPUART1_RX.0.Instance=DMA1_Channel3 -LPUART1.IPParameters=BaudRate,SwapParam,OneBitSampling,WordLength +LPUART1.IPParameters=BaudRate,SwapParam,OneBitSampling,WordLength,Parity PinOutPanel.RotationAngle=0 RCC.FamilyName=M +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK ProjectManager.StackSize=0x400 -Dma.LPUART1_RX.0.PeriphInc=DMA_PINC_DISABLE RCC.WatchDogFreq_Value=37000 PA13.Signal=SYS_SWDIO -Mcu.IP4=RCC +Mcu.IP4=SYS RCC.HSI16_VALUE=16000000 -Mcu.IP5=SYS -Mcu.IP2=LPUART1 -Mcu.IP3=NVIC +RCC.FCLKCortexFreq_Value=12000000 +Mcu.IP5=TIM21 +I2C1.IPParameters=Timing +Mcu.IP2=NVIC +Mcu.IP3=RCC LPUART1.OneBitSampling=UART_ONE_BIT_SAMPLE_ENABLE -Mcu.IP0=DMA +Mcu.IP0=I2C1 PA9.Mode=I2C -Mcu.IP1=I2C1 +Mcu.IP1=LPUART1 +TIM21.Period=tim21_period +RCC.PLLDIV=RCC_PLLDIV_4 Mcu.UserConstants= PA7.PinState=GPIO_PIN_SET ProjectManager.TargetToolchain=STM32CubeIDE Mcu.ThirdPartyNb=0 +NVIC.LPUART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true +RCC.HCLKFreq_Value=12000000 Mcu.IPNb=6 ProjectManager.PreviousToolchain= -RCC.APB2TimFreq_Value=2097000 +RCC.APB2TimFreq_Value=12000000 PA9.Signal=I2C1_SCL -Mcu.Pin6=PA10 -Mcu.Pin7=PA13 +I2C1.Timing=0x40000A0B +LPUART1.Parity=UART_PARITY_EVEN +Mcu.Pin6=PA9 +Mcu.Pin7=PA10 ProjectManager.RegisterCallBack= -Mcu.Pin8=PA14 -Mcu.Pin9=VP_SYS_VS_Systick +Mcu.Pin8=PA13 +Mcu.Pin9=PA14 PA0-CK_IN.GPIO_PuPd=GPIO_PULLUP RCC.LSE_VALUE=32768 PA1.GPIO_PuPd=GPIO_PULLUP PA1.Signal=LPUART1_TX -RCC.AHBFreq_Value=2097000 +RCC.AHBFreq_Value=12000000 Mcu.Pin0=PA0-CK_IN Mcu.Pin1=PA1 GPIO.groupedBy=Group By Peripherals Mcu.Pin2=PA5 Mcu.Pin3=PA6 Mcu.Pin4=PA7 -Mcu.Pin5=PA9 -Dma.LPUART1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE +Mcu.Pin5=PB1 PA5.Signal=GPIO_Output ProjectManager.ProjectBuild=false RCC.HSE_VALUE=8000000 +RCC.MCOPinFreq_Value=12000000 board=custom RCC.VCOOutputFreq_Value=48000000 -Dma.LPUART1_RX.0.MemInc=DMA_MINC_ENABLE NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true ProjectManager.LastFirmware=true ProjectManager.FirmwarePackage=STM32Cube FW_L0 V1.12.0 PA0-CK_IN.Signal=LPUART1_RX -MxDb.Version=DB.6.0.10 -RCC.APB2Freq_Value=2097000 +MxDb.Version=DB.6.0.21 +RCC.APB2Freq_Value=12000000 PA1.Mode=Asynchronous PA1.GPIOParameters=GPIO_PuPd ProjectManager.BackupPrevious=false -MxCube.Version=6.1.0 -RCC.I2C1Freq_Value=2097000 +MxCube.Version=6.2.1 +VP_TIM21_VS_ClockSourceINT.Mode=Internal +RCC.I2C1Freq_Value=12000000 PA14.Mode=Serial_Wire +TIM21.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM21.Prescaler=tim21_prescaler File.Version=6 VP_SYS_VS_Systick.Mode=SysTick +TIM21.IPParametersWithoutCheck=Prescaler,Period PA9.Locked=true NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false -Dma.LPUART1_RX.0.Priority=DMA_PRIORITY_MEDIUM +NVIC.TIM21_IRQn=true\:0\:0\:false\:false\:true\:true\:true NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false PA13.Mode=Serial_Wire ProjectManager.FreePins=false -RCC.IPParameters=AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FamilyName,HSE_VALUE,HSI16_VALUE,HSI_VALUE,I2C1Freq_Value,LPTIMFreq_Value,LPUARTFreq_Value,LSE_VALUE,LSI_VALUE,MSI_VALUE,PLLCLKFreq_Value,PWRFreq_Value,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,TIMFreq_Value,USART2Freq_Value,VCOOutputFreq_Value,WatchDogFreq_Value +RCC.IPParameters=AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI16_VALUE,HSI_VALUE,I2C1Freq_Value,LPTIMFreq_Value,LPUARTFreq_Value,LSE_VALUE,LSI_VALUE,MCOPinFreq_Value,MSI_VALUE,PLLCLKFreq_Value,PLLDIV,PWRFreq_Value,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,TIMFreq_Value,TimerFreq_Value,USART2Freq_Value,VCOOutputFreq_Value,WatchDogFreq_Value ProjectManager.AskForMigrate=true Mcu.Name=STM32L011F(3-4)Ux -Dma.RequestsNb=1 ProjectManager.HalAssertFull=false LPUART1.BaudRate=115200 RCC.RTCHSEDivFreq_Value=4000000 ProjectManager.ProjectName=iaq_wired_sensor ProjectManager.UnderRoot=true ProjectManager.CoupleFile=false -RCC.SYSCLKFreq_VALUE=2097000 +RCC.SYSCLKFreq_VALUE=12000000 Mcu.Package=UFQFPN20 +PB1.Signal=LPUART1_DE PA6.Signal=GPIO_Output PA7.GPIO_Label=LED_R -Dma.LPUART1_RX.0.Mode=DMA_CIRCULAR -PA7.Locked=true PA5.Locked=true +PA7.Locked=true LPUART1.SwapParam=UART_ADVFEATURE_SWAP_DISABLE PA5.GPIO_Label=LED_B NVIC.ForceEnableDMAVector=true @@ -124,20 +133,22 @@ PA10.Signal=I2C1_SDA PA14.Signal=SYS_SWCLK ProjectManager.HeapSize=0x200 NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false +PB1.Mode=Hardware Flow Control (RS485) PA5.GPIOParameters=PinState,GPIO_Label ProjectManager.ComputerToolchain=false RCC.HSI_VALUE=16000000 -NVIC.DMA1_Channel2_3_IRQn=true\:0\:0\:false\:false\:true\:false\:true -RCC.APB1TimFreq_Value=2097000 -RCC.PWRFreq_Value=2097000 -RCC.APB1Freq_Value=2097000 -Dma.Request0=LPUART1_RX +Mcu.Pin11=VP_TIM21_VS_ClockSourceINT +Mcu.Pin10=VP_SYS_VS_Systick +RCC.APB1TimFreq_Value=12000000 +RCC.PWRFreq_Value=12000000 +RCC.APB1Freq_Value=12000000 PA7.GPIOParameters=PinState,GPIO_Label ProjectManager.CustomerFirmwarePackage= ProjectManager.DeviceId=STM32L011F4Ux ProjectManager.LibraryCopy=1 -RCC.LPTIMFreq_Value=2097000 +RCC.LPTIMFreq_Value=12000000 PA7.Signal=GPIO_Output -RCC.TIMFreq_Value=2097000 +VP_TIM21_VS_ClockSourceINT.Signal=TIM21_VS_ClockSourceINT +RCC.TIMFreq_Value=12000000 PA6.Locked=true isbadioc=false From 23f1f27c0e3831b7bfa7a9e79736678c276a453a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20=C5=BDaitl=C3=ADk?= Date: Mon, 19 Jul 2021 17:30:47 +0200 Subject: [PATCH 2/2] Implemented UART communication (initial version). Needs more testing and make the buffer smaller to save space. RX and TX have been swapped in the system for debug (bad solder joint). --- fw/Core/Src/main.c | 31 ++++++++++++++----------------- fw/Core/Src/stm32l0xx_it.c | 4 ++-- fw/iaq_wired_sensor.ioc | 21 +++++++++------------ 3 files changed, 25 insertions(+), 31 deletions(-) diff --git a/fw/Core/Src/main.c b/fw/Core/Src/main.c index 262d0d4..879c817 100644 --- a/fw/Core/Src/main.c +++ b/fw/Core/Src/main.c @@ -47,8 +47,8 @@ * Desired interrupt period 60s */ const uint16_t tim21_prescaler = 60000-1; // 100Hz -const uint16_t tim21_period = 12000-1; // 60s -//const uint16_t tim21_period = 1200-1; // 6s +//const uint16_t tim21_period = 12000-1; // 60s +const uint16_t tim21_period = 1200-1; // 6s //const uint16_t tim21_period = 200-1; // 1s /* USER CODE END PV */ @@ -158,6 +158,11 @@ int main(void) if (lpuart1_rx_done == 1) { /* Process the message */ + uint8_t buff_pom[255]; + for (uint8_t j = 0; j < lpuart1_rx_message_len; j ++) + { + buff_pom[j] = lpuart1_rx_message[j]; + } /* process_modbus_message(lpuart1_rx_message, lpuart1_rx_message_len); */ /* Reset the RX DONE flag */ @@ -193,6 +198,9 @@ int main(void) tim21_elapsed_period = 0; } /* TEST START */ + + //LL_LPUART_TransmitData9(LPUART1, 0x69); + //LL_mDelay(250); /* TODO: DELETE TEST */ /* RS485 test */ @@ -350,11 +358,9 @@ static void MX_LPUART1_UART_Init(void) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPUART1); LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); - LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB); /**LPUART1 GPIO Configuration PA0-CK_IN ------> LPUART1_RX PA1 ------> LPUART1_TX - PB1 ------> LPUART1_DE */ GPIO_InitStruct.Pin = LL_GPIO_PIN_0; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; @@ -372,14 +378,6 @@ static void MX_LPUART1_UART_Init(void) GPIO_InitStruct.Alternate = LL_GPIO_AF_6; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); - GPIO_InitStruct.Pin = LL_GPIO_PIN_1; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_4; - LL_GPIO_Init(GPIOB, &GPIO_InitStruct); - /* LPUART1 interrupt Init */ NVIC_SetPriority(LPUART1_IRQn, 0); NVIC_EnableIRQ(LPUART1_IRQn); @@ -394,10 +392,7 @@ static void MX_LPUART1_UART_Init(void) LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX; LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; LL_LPUART_Init(LPUART1, &LPUART_InitStruct); - LL_LPUART_EnableDEMode(LPUART1); - LL_LPUART_SetDESignalPolarity(LPUART1, LL_LPUART_DE_POLARITY_HIGH); - LL_LPUART_SetDEAssertionTime(LPUART1, 0); - LL_LPUART_SetDEDeassertionTime(LPUART1, 0); + LL_LPUART_SetTXRXSwap(LPUART1, LL_LPUART_TXRX_SWAPPED); /* USER CODE BEGIN LPUART1_Init 2 */ /* Enable IDLE Interrupt */ @@ -406,6 +401,9 @@ static void MX_LPUART1_UART_Init(void) /* Enable RX Not Empty Interrupt */ LL_LPUART_EnableIT_RXNE(LPUART1); + LL_LPUART_EnableDirectionRx(LPUART1); + LL_LPUART_EnableDirectionTx(LPUART1); + LL_LPUART_Enable(LPUART1); /* USER CODE END LPUART1_Init 2 */ } @@ -460,7 +458,6 @@ static void MX_GPIO_Init(void) /* GPIO Ports Clock Enable */ LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); - LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB); /**/ LL_GPIO_SetOutputPin(LED_B_GPIO_Port, LED_B_Pin); diff --git a/fw/Core/Src/stm32l0xx_it.c b/fw/Core/Src/stm32l0xx_it.c index 8e22949..fd2c6ca 100644 --- a/fw/Core/Src/stm32l0xx_it.c +++ b/fw/Core/Src/stm32l0xx_it.c @@ -179,13 +179,13 @@ void LPUART1_IRQHandler(void) /* USER CODE END LPUART1_IRQn 0 */ /* USER CODE BEGIN LPUART1_IRQn 1 */ /* If the IDLE flag is active */ - if (LL_LPUART_IsActiveFlag_IDLE(LPUART1) == 1) + if (LL_LPUART_IsActiveFlag_IDLE(LPUART1) && LL_LPUART_IsEnabledIT_IDLE(LPUART1)) { /* Clear the IDLE flag */ LL_LPUART_ClearFlag_IDLE(LPUART1); /* Reset the buffer index */ - lpuart1_rx_message_len = lpuart1_rx_message_index + 1; + lpuart1_rx_message_len = lpuart1_rx_message_index; lpuart1_rx_message_index = 0; lpuart1_rx_done = 1; } diff --git a/fw/iaq_wired_sensor.ioc b/fw/iaq_wired_sensor.ioc index 004d448..61eed32 100644 --- a/fw/iaq_wired_sensor.ioc +++ b/fw/iaq_wired_sensor.ioc @@ -8,7 +8,7 @@ ProjectManager.ProjectFileName=iaq_wired_sensor.ioc ProjectManager.KeepUserCode=true PA10.Mode=I2C Mcu.UserName=STM32L011F4Ux -Mcu.PinsNb=12 +Mcu.PinsNb=11 ProjectManager.NoMain=false TIM21.IPParameters=Prescaler,Period,AutoReloadPreload,ClockDivision PA0-CK_IN.Mode=Asynchronous @@ -34,8 +34,8 @@ ProjectManager.StackSize=0x400 RCC.WatchDogFreq_Value=37000 PA13.Signal=SYS_SWDIO Mcu.IP4=SYS -RCC.HSI16_VALUE=16000000 RCC.FCLKCortexFreq_Value=12000000 +RCC.HSI16_VALUE=16000000 Mcu.IP5=TIM21 I2C1.IPParameters=Timing Mcu.IP2=NVIC @@ -58,11 +58,11 @@ RCC.APB2TimFreq_Value=12000000 PA9.Signal=I2C1_SCL I2C1.Timing=0x40000A0B LPUART1.Parity=UART_PARITY_EVEN -Mcu.Pin6=PA9 -Mcu.Pin7=PA10 +Mcu.Pin6=PA10 +Mcu.Pin7=PA13 ProjectManager.RegisterCallBack= -Mcu.Pin8=PA13 -Mcu.Pin9=PA14 +Mcu.Pin8=PA14 +Mcu.Pin9=VP_SYS_VS_Systick PA0-CK_IN.GPIO_PuPd=GPIO_PULLUP RCC.LSE_VALUE=32768 PA1.GPIO_PuPd=GPIO_PULLUP @@ -74,7 +74,7 @@ GPIO.groupedBy=Group By Peripherals Mcu.Pin2=PA5 Mcu.Pin3=PA6 Mcu.Pin4=PA7 -Mcu.Pin5=PB1 +Mcu.Pin5=PA9 PA5.Signal=GPIO_Output ProjectManager.ProjectBuild=false RCC.HSE_VALUE=8000000 @@ -116,12 +116,11 @@ ProjectManager.UnderRoot=true ProjectManager.CoupleFile=false RCC.SYSCLKFreq_VALUE=12000000 Mcu.Package=UFQFPN20 -PB1.Signal=LPUART1_DE PA6.Signal=GPIO_Output PA7.GPIO_Label=LED_R PA5.Locked=true PA7.Locked=true -LPUART1.SwapParam=UART_ADVFEATURE_SWAP_DISABLE +LPUART1.SwapParam=UART_ADVFEATURE_SWAP_ENABLE PA5.GPIO_Label=LED_B NVIC.ForceEnableDMAVector=true KeepUserPlacement=false @@ -133,12 +132,10 @@ PA10.Signal=I2C1_SDA PA14.Signal=SYS_SWCLK ProjectManager.HeapSize=0x200 NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false -PB1.Mode=Hardware Flow Control (RS485) PA5.GPIOParameters=PinState,GPIO_Label ProjectManager.ComputerToolchain=false RCC.HSI_VALUE=16000000 -Mcu.Pin11=VP_TIM21_VS_ClockSourceINT -Mcu.Pin10=VP_SYS_VS_Systick +Mcu.Pin10=VP_TIM21_VS_ClockSourceINT RCC.APB1TimFreq_Value=12000000 RCC.PWRFreq_Value=12000000 RCC.APB1Freq_Value=12000000