From ea70f82c925779b5acb138f6fbefdc76c4af9202 Mon Sep 17 00:00:00 2001 From: Adam Prochazka Date: Tue, 9 May 2023 17:36:09 +0200 Subject: [PATCH] Push local changes for complete and functioning probe --- Firmware/.mxproject | 4 +- Firmware/Core/Cam/Cam.c | 171 +- Firmware/Core/Cam/Cam.h | 104 +- Firmware/Core/Cam/OV5642_regs.h | 10 + Firmware/Core/Inc/main.h | 22 +- Firmware/Core/Inc/stm32l4xx_hal_conf.h | 4 +- Firmware/Core/Inc/stm32l4xx_it.h | 1 - Firmware/Core/Inc/tusb_config.h | 13 +- Firmware/Core/Inc/vl53l1_platform.h | 47 +- Firmware/Core/Src/main.c | 258 +- Firmware/Core/Src/stm32l4xx_hal_msp.c | 98 +- Firmware/Core/Src/stm32l4xx_it.c | 15 - Firmware/Core/Src/usb_descriptors.c | 23 +- Firmware/Core/Src/vl53l1_platform.c | 27 +- .../Inc/stm32l4xx_hal_uart.h | 1788 - .../Inc/stm32l4xx_hal_uart_ex.h | 743 - .../Inc/stm32l4xx_ll_lpuart.h | 2881 -- .../Inc/stm32l4xx_ll_tim.h | 5092 +++ .../Inc/stm32l4xx_ll_usart.h | 4701 --- .../Src/stm32l4xx_hal_uart.c | 4840 --- .../Src/stm32l4xx_hal_uart_ex.c | 1074 - Firmware/Probe.ioc | 47 +- HW/Probe.kicad_pcb | 1 + HW/Probe.kicad_prl | 2 +- Probe_Assembled.jpg | Bin 0 -> 40257 bytes Probe_Render.png | Bin 0 -> 140379 bytes README.md | 66 +- Receiver/.vscode/settings.json | 3 +- Receiver/Displayer.cpp | 39 +- Receiver/Displayer.hpp | 64 +- Receiver/Doxyfile | 2763 ++ Receiver/Makefile | 5 +- Receiver/Receiver.cpp | 91 +- Receiver/Receiver.hpp | 94 +- Receiver/main.cpp | 99 +- Receiver/main.hpp | 8 + Receiver/out.txt | 33720 ---------------- Test/Makefile | 16 - Test/uart_jpeg.c | 121 - 39 files changed, 8657 insertions(+), 50398 deletions(-) delete mode 100644 Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h delete mode 100644 Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h delete mode 100644 Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_lpuart.h create mode 100644 Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_tim.h delete mode 100644 Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usart.h delete mode 100644 Firmware/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c delete mode 100644 Firmware/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c create mode 100644 Probe_Assembled.jpg create mode 100644 Probe_Render.png create mode 100644 Receiver/Doxyfile delete mode 100644 Receiver/out.txt delete mode 100644 Test/Makefile delete mode 100644 Test/uart_jpeg.c diff --git a/Firmware/.mxproject b/Firmware/.mxproject index b0ef27c..031b9e4 100644 --- a/Firmware/.mxproject +++ b/Firmware/.mxproject @@ -1,8 +1,8 @@ [PreviousLibFiles] -LibFiles=Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_bus.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_crs.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_system.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_utils.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_dmamux.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_lpuart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_bus.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_crs.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_system.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_utils.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_dmamux.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_lpuart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l432xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/core_armv81mml.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/cmsis_armclang_ltm.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm35p.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h; +LibFiles=Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_bus.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_crs.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_system.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_utils.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_dmamux.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_bus.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_crs.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_system.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_utils.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_dmamux.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l432xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/core_armv81mml.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/cmsis_armclang_ltm.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm35p.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h; [PreviousUsedMakefileFiles] -SourceFiles=Core/Src/main.c;Core/Src/stm32l4xx_it.c;Core/Src/stm32l4xx_hal_msp.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;Core/Src/system_stm32l4xx.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;Core/Src/system_stm32l4xx.c;;; +SourceFiles=Core/Src/main.c;Core/Src/stm32l4xx_it.c;Core/Src/stm32l4xx_hal_msp.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;Core/Src/system_stm32l4xx.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;Core/Src/system_stm32l4xx.c;;; HeaderPath=Drivers/STM32L4xx_HAL_Driver/Inc;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy;Drivers/CMSIS/Device/ST/STM32L4xx/Include;Drivers/CMSIS/Include;Core/Inc; CDefines=USE_HAL_DRIVER;STM32L432xx;USE_HAL_DRIVER;USE_HAL_DRIVER; diff --git a/Firmware/Core/Cam/Cam.c b/Firmware/Core/Cam/Cam.c index b0cd3b8..9dd28eb 100644 --- a/Firmware/Core/Cam/Cam.c +++ b/Firmware/Core/Cam/Cam.c @@ -1,3 +1,12 @@ +/** + ****************************************************************************** + * @file : Cam.c + * @brief : Interacting with camera module + * This file contains the methods for communication with camera module, including I2C and SPI communication, sending commands to camera and reading data from it. + * @author : Adam Prochazka + ****************************************************************************** + */ + #include "Cam.h" void CS_Off() @@ -120,19 +129,24 @@ void Cam_I2C_write_bulk(I2C_HandleTypeDef *hi2c, const struct sensor_reg regList void Cam_Init(I2C_HandleTypeDef *hi2c, SPI_HandleTypeDef *hspi) { + // Test SPI communication Cam_SPI_write(hspi, 0x07, 0x80); HAL_Delay(100); Cam_SPI_write(hspi, 0x07, 0x00); HAL_Delay(100); + // Reset camera chip Cam_I2C_write(hi2c, (uint16_t)0x3008, 0x80); + + // Delay for reset complete. HAL_Delay(5); + + // Set registers for desired configuration - need to be in this specific order Cam_I2C_write_bulk(hi2c, OV5642_QVGA_Preview); - HAL_Delay(200); + HAL_Delay(200); // Delay for first configuration to take effect Cam_I2C_write_bulk(hi2c, OV5642_JPEG_Capture_QSXGA); Cam_I2C_write_bulk(hi2c, ov5642_1024x768); - //Cam_I2C_write_bulk(hi2c, ov5642_320x240); HAL_Delay(100); Cam_I2C_write(hi2c, (uint16_t)0x3818, 0xa8); // TIMING CONTROL - ENABLE COMPRESSION, THUMBNAIL MODE DISABLE, VERTICAL FLIP, MIRROR @@ -141,16 +155,17 @@ void Cam_Init(I2C_HandleTypeDef *hi2c, SPI_HandleTypeDef *hspi) Cam_I2C_write(hi2c, (uint16_t)0x4407, 0x09); // COMPRESSION CONTROL HAL_Delay(5); - // Setup camera, H-sync: High, V-sync:high, Sensor_delay: no Delay, FIFO_mode:FIFO enabled, power_mode:Low_power + + // H-sync: High, V-sync:high, Sensor_delay: no Delay, FIFO_mode:FIFO enabled, power_mode:Low_power Cam_SPI_write(hspi, 0x03, 0x02); HAL_Delay(5); - Cam_I2C_write_bulk(hi2c, ov5642_1024x768); - //Cam_I2C_write_bulk(hi2c, ov5642_320x240); - HAL_Delay(1000); + Cam_I2C_write_bulk(hi2c, ov5642_1024x768); // Necessary to be called again + + HAL_Delay(1000); // Delay for camera to stabilize - Cam_SPI_write(hspi, 0x04, 0x01); + Cam_SPI_write(hspi, 0x04, 0x01); // Reset camera capture status and memory flags HAL_Delay(5); @@ -159,145 +174,32 @@ void Cam_Init(I2C_HandleTypeDef *hi2c, SPI_HandleTypeDef *hspi) HAL_Delay(5); } -void Cam_Refresh(I2C_HandleTypeDef *hi2c, SPI_HandleTypeDef *hspi){ - /*Cam_I2C_write(hi2c, (uint16_t)0x3008, 0x80); - - Cam_I2C_write_bulk(hi2c, OV5642_QVGA_Preview); - - Cam_I2C_write_bulk(hi2c, OV5642_JPEG_Capture_QSXGA); - - Cam_I2C_write(hi2c, (uint16_t)0x3818, 0xa8); // TIMING CONTROL - ENABLE COMPRESSION, THUMBNAIL MODE DISABLE, VERTICAL FLIP, MIRROR - Cam_I2C_write(hi2c, (uint16_t)0x3621, 0x10); // REGISTER FOR CORRECT MIRROR FUNCTION - Cam_I2C_write(hi2c, (uint16_t)0x3801, 0xb0); // TIMING HORIZONTAL START - ALSO FOR MIRROR - Cam_I2C_write(hi2c, (uint16_t)0x4407, 0x04); // COMPRESSION CONTROL - - Cam_I2C_write_bulk(hi2c, ov5642_1280x960); - - // Setup camera, H-sync: High, V-sync:high, Sensor_delay: no Delay, FIFO_mode:FIFO enabled, power_mode:Low_power - Cam_SPI_write(hspi, 0x03, 0x02); - Cam_SPI_write(hspi, 0x01, 0x00); // Capture Control Register - Set to capture n+1 frames - - HAL_Delay(5);*/ - - // SAFE TO REMOVE - //Cam_I2C_write(hi2c, (uint16_t)0x3008, 0x80); - - Cam_I2C_write_bulk(hi2c, OV5642_QVGA_Preview); - - Cam_I2C_write_bulk(hi2c, OV5642_JPEG_Capture_QSXGA); - - Cam_I2C_write(hi2c, (uint16_t)0x3818, 0xa8); // TIMING CONTROL - ENABLE COMPRESSION, THUMBNAIL MODE DISABLE, VERTICAL FLIP, MIRROR - Cam_I2C_write(hi2c, (uint16_t)0x3621, 0x10); // REGISTER FOR CORRECT MIRROR FUNCTION - Cam_I2C_write(hi2c, (uint16_t)0x3801, 0xb0); // TIMING HORIZONTAL START - ALSO FOR MIRROR - Cam_I2C_write(hi2c, (uint16_t)0x4407, 0x04); // COMPRESSION CONTROL - Cam_I2C_write(hi2c, (uint16_t)0x5000, 0xFF); - - Cam_I2C_write_bulk(hi2c, ov5642_1024x768); - // Setup camera, H-sync: High, V-sync:high, Sensor_delay: no Delay, FIFO_mode:FIFO enabled, power_mode:Low_power - Cam_SPI_write(hspi, 0x03, 0x02); - - - // Brightness 4 - Cam_I2C_write(hi2c, (uint16_t)0x5001, 0xff); - Cam_I2C_write(hi2c, (uint16_t)0x5589, 0x30); - Cam_I2C_write(hi2c, (uint16_t)0x5580, 0x04); - Cam_I2C_write(hi2c, (uint16_t)0x558a, 0x00); - //Cam_I2C_write(hi2c, (uint16_t)0x558a, 0x08); - - //Contrast 0 - //Cam_I2C_write(hi2c, (uint16_t)0x5587, 0xff); - //Cam_I2C_write(hi2c, (uint16_t)0x5588, 0xff); - - /* - // Exposure _17 - Cam_I2C_write(hi2c, (uint16_t)0x3a0f, 0x10); - Cam_I2C_write(hi2c, (uint16_t)0x3a10, 0x08); - Cam_I2C_write(hi2c, (uint16_t)0x3a1b, 0x10); - Cam_I2C_write(hi2c, (uint16_t)0x3a1e, 0x08); - Cam_I2C_write(hi2c, (uint16_t)0x3a11, 0x20); - Cam_I2C_write(hi2c, (uint16_t)0x3a1f, 0x10); - - - - //Exposure 17 v2 - Cam_I2C_write(hi2c, (uint16_t)0x3a0f, 0x60); - Cam_I2C_write(hi2c, (uint16_t)0x3a10, 0x58); - Cam_I2C_write(hi2c, (uint16_t)0x3a11, 0xa0); - Cam_I2C_write(hi2c, (uint16_t)0x3a1b, 0x60); - Cam_I2C_write(hi2c, (uint16_t)0x3a1e, 0x58); - Cam_I2C_write(hi2c, (uint16_t)0x3a1f, 0x20); - */ - - // Exposure Manual - Cam_I2C_write(hi2c, (uint16_t)0x3503, 0x3); - Cam_I2C_write(hi2c, (uint16_t)0x350C, 0xFF); - Cam_I2C_write(hi2c, (uint16_t)0x350D, 0xFF); - - Cam_I2C_write(hi2c, (uint16_t)0x3500, 0x0); - Cam_I2C_write(hi2c, (uint16_t)0x3501, 0x00); - Cam_I2C_write(hi2c, (uint16_t)0x3502, 0x0f); - - //Gain MAX - Cam_I2C_write(hi2c, (uint16_t)0x350A, 0x0); - Cam_I2C_write(hi2c, (uint16_t)0x350B, 0x35); - Cam_I2C_write(hi2c, (uint16_t)0x3508, 0x0); - Cam_I2C_write(hi2c, (uint16_t)0x3509, 0x35); - - // AWB - Cam_I2C_write(hi2c, (uint16_t)0x3406, 0x1); - - Cam_I2C_write(hi2c, (uint16_t)0x3400, 0xf); - Cam_I2C_write(hi2c, (uint16_t)0x3401, 0xff); - Cam_I2C_write(hi2c, (uint16_t)0x3402, 0xf); - Cam_I2C_write(hi2c, (uint16_t)0x3403, 0x7f); - Cam_I2C_write(hi2c, (uint16_t)0x3404, 0xf); - Cam_I2C_write(hi2c, (uint16_t)0x3405, 0xff); - - - HAL_Delay(50); -} - int Cam_FIFO_length(SPI_HandleTypeDef *hspi) { uint32_t len1, len2, len3, len = 0; len1 = Cam_SPI_read(hspi, 0x42); len2 = Cam_SPI_read(hspi, 0x43); len3 = Cam_SPI_read(hspi, 0x44)& 0x7f; - len = ((len3 << 16) | (len2 << 8) | len1) & 0x07fffff; + len = ((len3 << 16) | (len2 << 8) | len1) & 0x07fffff; // logic & operation needed, because content of the registry 0x44 isn't all length data. return len; } void Cam_Start_Capture(SPI_HandleTypeDef *hspi) { - /* - uint8_t FIFO_Reg = Cam_SPI_read(hspi, 0x04); - uint8_t FIFO_Reg_Clear_Flags = FIFO_Reg | 0x01; - Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); // Clear FIFO Write Done Flaf - Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); - HAL_Delay(1); - - FIFO_Reg = Cam_SPI_read(hspi, 0x04); - FIFO_Reg_Clear_Flags = FIFO_Reg | 0x10; - Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); // Reset FIFO Write Pointer - Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); - HAL_Delay(1); - - FIFO_Reg = Cam_SPI_read(hspi, 0x04); - FIFO_Reg_Clear_Flags = FIFO_Reg | 0x20; - Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); // Reset FIFO Read Pointer - Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); -*/ - Cam_SPI_write(hspi, 0x04, 0x01); + // Reset memory pointers and capture status flags + Cam_SPI_write(hspi, 0x04, 0x01); HAL_Delay(3); Cam_SPI_write(hspi, 0x04, 0x01); + // Start capture HAL_Delay(3); - Cam_SPI_write(hspi, 0x04, 0x02); // Start capture + Cam_SPI_write(hspi, 0x04, 0x02); HAL_Delay(3); } void Cam_Wait_Capture_Done(SPI_HandleTypeDef *hspi) { + // Check if bit meaning capture is done in registry 0x41 is set while (1) { uint8_t regValue = Cam_SPI_read(hspi, 0x41); @@ -309,34 +211,25 @@ void Cam_Wait_Capture_Done(SPI_HandleTypeDef *hspi) void Cam_Start_Burst_Read(SPI_HandleTypeDef *hspi) { - - /* - uint8_t FIFO_Reg = Cam_SPI_read(hspi, 0x04); - uint8_t FIFO_Reg_Clear_Flags = FIFO_Reg | 0x20; - Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); // Reset FIFO Read Pointer - Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); -*/ - + // Reset memory pointers and capture status flags Cam_SPI_write(hspi, 0x04, 0x01); Cam_SPI_write(hspi, 0x04, 0x01); uint8_t BURST_FIFO_READ = 0x3c; uint8_t empty = 0x00; + // Set camera CS chip to high for SPI communication CS_On(); + // Send command for burst read HAL_SPI_TransmitReceive(hspi, &BURST_FIFO_READ, &empty, 1, HAL_MAX_DELAY); } void Cam_Capture(SPI_HandleTypeDef *hspi) { - //LED_On(); - Cam_SPI_write(hspi, 0x01, 0x00); // Capture Control Register - Set to capture n+1 frames Cam_Start_Capture(hspi); Cam_Wait_Capture_Done(hspi); - - //LED_Off(); -} \ No newline at end of file +} diff --git a/Firmware/Core/Cam/Cam.h b/Firmware/Core/Cam/Cam.h index f7bd48c..5db79ea 100644 --- a/Firmware/Core/Cam/Cam.h +++ b/Firmware/Core/Cam/Cam.h @@ -1,28 +1,128 @@ - +/** + ****************************************************************************** + * @file : Cam.h + * @brief : Methods for interacting with camera module + * This file contains the definitions the methods for interacting with camera module. + * @author : Adam Prochazka + ****************************************************************************** + */ #include "OV5642_regs.h" #include "stm32l4xx_hal.h" +/** + * @brief Disables the chip select line for the camera module. + */ void CS_Off(); + +/** + * @brief Enables the chip select line for the camera module. + */ void CS_On(); + +/** + * @brief Turns on the LED on Nucleo board. + */ void LED_On(); + +/** + * @brief Turns on the LED on Nucleo board. + */ void LED_Off(); + +/** + * @brief Turns on the optional debug LED. + */ void Debug_LED_On(); + +/** + * @brief Turns off the optional debug LED. + */ void Debug_LED_Off(); +/** + * @brief Initializes SPI communication with the camera module. + * @param hspi Pointer to an SPI_HandleTypeDef structure that contains the configuration information for the specified SPI. + */ void SPI_Init(SPI_HandleTypeDef *hspi); + +/** + * @brief Reads data from the camera module using SPI. + * @param hspi Pointer to an SPI_HandleTypeDef structure that contains the configuration information for the specified SPI. + * @param address The address to read data from. + * @return The data read from the specified address. + */ int Cam_SPI_read(SPI_HandleTypeDef *hspi, uint8_t address); + +/** + * @brief Writes data to the camera module using SPI. + * @param hspi Pointer to an SPI_HandleTypeDef structure that contains the configuration information for the specified SPI. + * @param addr The address to write data to. + * @param data The data to write to the specified address. + * @return Status of the write operation (0 for success, non-zero for failure). + */ int Cam_SPI_write(SPI_HandleTypeDef *hspi, uint8_t addr, uint8_t data); + + +/** + * @brief Writes data to the camera module using I2C. + * @param hi2c Pointer to an I2C_HandleTypeDef structure that contains the configuration information for the specified I2C. + * @param address The address to write data to. + * @param data The data to write to the specified address. + * @return Status of the write operation (1 for success, 0 for failure). + */ int Cam_I2C_write(I2C_HandleTypeDef *hi2c, uint16_t address, uint8_t data); + +/** + * @brief Writes a sensor register structure to the camera module using I2C. + * @param hi2c Pointer to an I2C_HandleTypeDef structure that contains the configuration information for the specified I2C. + * @param reg The sensor register structure to write. + * @return Status of the write operation (1 for success, 0 for failure). + */ int Cam_I2C_write_struct(I2C_HandleTypeDef *hi2c, sensor_reg reg); + +/** + * @brief Writes a list of sensor registers to the camera module using I2C. + * @param hi2c Pointer to an I2C_HandleTypeDef structure that contains the configuration information for the specified I2C. + * @param regList An array of sensor register structures to write. + */ void Cam_I2C_write_bulk(I2C_HandleTypeDef *hi2c, const struct sensor_reg regList[]); + +/** + * @brief Initializes the camera module. + * @param hi2c Pointer to an I2C_HandleTypeDef structure that contains the configuration information for the specified I2C. + * @param hspi Pointer to an SPI_HandleTypeDef structure that contains the configuration information for the specified SPI. + */ void Cam_Init(I2C_HandleTypeDef *hi2c, SPI_HandleTypeDef *hspi); -void Cam_Refresh(I2C_HandleTypeDef *hi2c, SPI_HandleTypeDef *hspi); +/** + * @brief Retrieves the length of the FIFO buffer in the camera module. + * @param hspi Pointer to an SPI_HandleTypeDef structure that contains the configuration information for the specified SPI. + * @return The length of the FIFO buffer. + */ int Cam_FIFO_length(SPI_HandleTypeDef *hspi); + +/** + * @brief Captures an image using the camera module. + * @param hspi Pointer to an SPI_HandleTypeDef structure that contains the configuration information for the specified SPI. + */ void Cam_Capture(SPI_HandleTypeDef *hspi); +/** + * @brief Starts the capture process in the camera module. + * @param hspi Pointer to an SPI_HandleTypeDef structure that contains the configuration information for the specified SPI +*/ void Cam_Start_Capture(SPI_HandleTypeDef *hspi); + +/** + * @brief Waits for the capture process to complete in the camera module. + * @param hspi Pointer to an SPI_HandleTypeDef structure that contains the configuration information for the specified SPI. +*/ void Cam_Wait_Capture_Done(SPI_HandleTypeDef *hspi); + +/** +* @brief Starts the burst read process from the camera module's FIFO buffer. +* @param hspi Pointer to an SPI_HandleTypeDef structure that contains the configuration information for the specified SPI. +*/ void Cam_Start_Burst_Read(SPI_HandleTypeDef *hspi); diff --git a/Firmware/Core/Cam/OV5642_regs.h b/Firmware/Core/Cam/OV5642_regs.h index bed3f03..4745598 100644 --- a/Firmware/Core/Cam/OV5642_regs.h +++ b/Firmware/Core/Cam/OV5642_regs.h @@ -1,3 +1,13 @@ +/** + ****************************************************************************** + * @file : OV5642_regs.h + * @brief : Predefined registers configurations for camera chip. + * This file contains settings for registers to achieve specific camera chip configuration. + * This file was taken over from ArduCam repository and edited to work for this specific project. + * @author : Adam Prochazka + ****************************************************************************** + */ + #include "stdint.h" #include "stdlib.h" #include "stdio.h" diff --git a/Firmware/Core/Inc/main.h b/Firmware/Core/Inc/main.h index 2e40a16..5a929c3 100644 --- a/Firmware/Core/Inc/main.h +++ b/Firmware/Core/Inc/main.h @@ -4,16 +4,11 @@ * @file : main.h * @brief : Header for main.c file. * This file contains the common defines of the application. + * @author : Adam Prochazka ****************************************************************************** * @attention * - * Copyright (c) 2023 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * + * Code outside of "USER CODE" blocks was generated by STM32CubeMX by STMicroelectronics and was not written by the author. ****************************************************************************** */ /* USER CODE END Header */ @@ -62,6 +57,8 @@ extern "C" { /* USER CODE END EM */ +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + /* Exported functions prototypes ---------------------------------------------*/ void Error_Handler(void); @@ -70,28 +67,23 @@ void Error_Handler(void); /* USER CODE END EFP */ /* Private defines -----------------------------------------------------------*/ - -extern I2C_HandleTypeDef hi2c1; - - #define MCO_Pin GPIO_PIN_0 #define MCO_GPIO_Port GPIOA #define DEBUG_LED_Pin GPIO_PIN_1 #define DEBUG_LED_GPIO_Port GPIOA -#define VCP_TX_Pin GPIO_PIN_2 -#define VCP_TX_GPIO_Port GPIOA #define CHIP_SELECT_Pin GPIO_PIN_0 #define CHIP_SELECT_GPIO_Port GPIOB +#define VSET_LED_Pin GPIO_PIN_8 +#define VSET_LED_GPIO_Port GPIOA #define SWDIO_Pin GPIO_PIN_13 #define SWDIO_GPIO_Port GPIOA #define SWCLK_Pin GPIO_PIN_14 #define SWCLK_GPIO_Port GPIOA -#define VCP_RX_Pin GPIO_PIN_15 -#define VCP_RX_GPIO_Port GPIOA #define LD3_Pin GPIO_PIN_3 #define LD3_GPIO_Port GPIOB /* USER CODE BEGIN Private defines */ +extern I2C_HandleTypeDef hi2c1; #define CDC_BUFF_SIZE 51200 #define CDC_FRAME_SIZE 64 #define CDC_FRAME_DELAY 1 diff --git a/Firmware/Core/Inc/stm32l4xx_hal_conf.h b/Firmware/Core/Inc/stm32l4xx_hal_conf.h index b0fea05..04ec5f8 100644 --- a/Firmware/Core/Inc/stm32l4xx_hal_conf.h +++ b/Firmware/Core/Inc/stm32l4xx_hal_conf.h @@ -76,9 +76,9 @@ #define HAL_SPI_MODULE_ENABLED /*#define HAL_SRAM_MODULE_ENABLED */ /*#define HAL_SWPMI_MODULE_ENABLED */ -/*#define HAL_TIM_MODULE_ENABLED */ +#define HAL_TIM_MODULE_ENABLED /*#define HAL_TSC_MODULE_ENABLED */ -#define HAL_UART_MODULE_ENABLED +/*#define HAL_UART_MODULE_ENABLED */ /*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */ /*#define HAL_EXTI_MODULE_ENABLED */ diff --git a/Firmware/Core/Inc/stm32l4xx_it.h b/Firmware/Core/Inc/stm32l4xx_it.h index f9f33dc..94b05c8 100644 --- a/Firmware/Core/Inc/stm32l4xx_it.h +++ b/Firmware/Core/Inc/stm32l4xx_it.h @@ -58,7 +58,6 @@ void SysTick_Handler(void); void DMA1_Channel2_IRQHandler(void); void DMA1_Channel3_IRQHandler(void); void SPI1_IRQHandler(void); -void USART2_IRQHandler(void); void USB_IRQHandler(void); /* USER CODE BEGIN EFP */ diff --git a/Firmware/Core/Inc/tusb_config.h b/Firmware/Core/Inc/tusb_config.h index 7525bdc..eac79b0 100644 --- a/Firmware/Core/Inc/tusb_config.h +++ b/Firmware/Core/Inc/tusb_config.h @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * @file : tusb_config.h + * @brief : Configuration file for USB communication. + * @author : Adam Prochazka + ****************************************************************************** + + * @attention + * + * File was from the large part taken from the TinyUSB repository and just slightly configured for projects usecase. + * Original file contains this disclaimer: + * * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) diff --git a/Firmware/Core/Inc/vl53l1_platform.h b/Firmware/Core/Inc/vl53l1_platform.h index fb4a3d5..63abd9b 100644 --- a/Firmware/Core/Inc/vl53l1_platform.h +++ b/Firmware/Core/Inc/vl53l1_platform.h @@ -1,6 +1,7 @@ /** * @file vl53l1_platform.h - * @brief Those platform functions are platform dependent and have to be implemented by the user + * @brief Large portion of this file was taken and edited from the VL53L1 Platform. + * @author Adam Prochazka */ #ifndef _VL53L1_PLATFORM_H_ @@ -19,66 +20,74 @@ typedef struct { typedef VL53L1_Dev_t *VL53L1_DEV; -/** @brief VL53L1_WriteMulti() definition.\n - * To be implemented by the developer +/** + * @brief VL53L1_WriteMulti() definition. */ int8_t VL53L1_WriteMulti( uint16_t dev, uint16_t index, uint8_t *pdata, uint32_t count); -/** @brief VL53L1_ReadMulti() definition.\n - * To be implemented by the developer + +/** + * @brief VL53L1_ReadMulti() definition. */ int8_t VL53L1_ReadMulti( uint16_t dev, uint16_t index, uint8_t *pdata, uint32_t count); -/** @brief VL53L1_WrByte() definition.\n - * To be implemented by the developer + +/** + * @brief VL53L1_WrByte() definition. */ int8_t VL53L1_WrByte( uint16_t dev, uint16_t index, uint8_t data); -/** @brief VL53L1_WrWord() definition.\n - * To be implemented by the developer + +/** + * @brief VL53L1_WrWord() definition. */ int8_t VL53L1_WrWord( uint16_t dev, uint16_t index, uint16_t data); -/** @brief VL53L1_WrDWord() definition.\n - * To be implemented by the developer + +/** + * @brief VL53L1_WrDWord() definition. */ int8_t VL53L1_WrDWord( uint16_t dev, uint16_t index, uint32_t data); -/** @brief VL53L1_RdByte() definition.\n - * To be implemented by the developer + +/** + * @brief VL53L1_RdByte() definition. */ int8_t VL53L1_RdByte( uint16_t dev, uint16_t index, uint8_t *pdata); -/** @brief VL53L1_RdWord() definition.\n - * To be implemented by the developer + +/** + * @brief VL53L1_RdWord() definition. */ int8_t VL53L1_RdWord( uint16_t dev, uint16_t index, uint16_t *pdata); -/** @brief VL53L1_RdDWord() definition.\n - * To be implemented by the developer + +/** + * @brief VL53L1_RdDWord() definition. */ int8_t VL53L1_RdDWord( uint16_t dev, uint16_t index, uint32_t *data); -/** @brief VL53L1_WaitMs() definition.\n - * To be implemented by the developer + +/** + * @brief VL53L1_WaitMs() definition. */ int8_t VL53L1_WaitMs( uint16_t dev, diff --git a/Firmware/Core/Src/main.c b/Firmware/Core/Src/main.c index 8c1fa21..1ec4af4 100644 --- a/Firmware/Core/Src/main.c +++ b/Firmware/Core/Src/main.c @@ -3,15 +3,11 @@ ****************************************************************************** * @file : main.c * @brief : Main program body + * @author : Adam Prochazka ****************************************************************************** * @attention * - * Copyright (c) 2023 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. + * Code outside of "USER CODE" blocks was generated by STM32CubeMX by STMicroelectronics and was not written by the author. * ****************************************************************************** */ @@ -40,23 +36,22 @@ /* Private variables ---------------------------------------------------------*/ I2C_HandleTypeDef hi2c1; + SPI_HandleTypeDef hspi1; DMA_HandleTypeDef hdma_spi1_rx; DMA_HandleTypeDef hdma_spi1_tx; -UART_HandleTypeDef huart2; +TIM_HandleTypeDef htim15; PCD_HandleTypeDef hpcd_USB_FS; -uint16_t dev=0x52; +/* USER CODE BEGIN PV */ + +uint16_t DistSensorAddr=0x52; int status=0; volatile int IntCount; -#define isInterrupt 1 /* If isInterrupt = 1 then device working in interrupt mode, else device working in polling mode */ -/* USER CODE BEGIN PV */ -//DAC_HandleTypeDef hdac1; - -//TIM_HandleTypeDef htim15; +#define isInterrupt 0 /* If isInterrupt = 1 then device working in interrupt mode, else device working in polling mode */ int SPI_Rx_Done_Flag = 0; /* USER CODE END PV */ @@ -65,14 +60,12 @@ int SPI_Rx_Done_Flag = 0; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); -static void MX_USART2_UART_Init(void); static void MX_SPI1_Init(void); static void MX_I2C1_Init(void); static void MX_USB_PCD_Init(void); +static void MX_TIM15_Init(void); /* USER CODE BEGIN PFP */ -//static void MX_DAC1_Init(void); -//static void MX_TIM15_Init(void); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ @@ -86,15 +79,12 @@ static void MX_USB_PCD_Init(void); int main(void) { /* USER CODE BEGIN 1 */ - //uint8_t byteData, sensorState=0; - //uint16_t wordData; - //uint8_t ToFSensor = 1; // 0=Left, 1=Center(default), 2=Right + uint16_t Distance = 0; uint16_t SignalRate; uint16_t AmbientRate; uint16_t SpadNum; uint8_t RangeStatus; - //uint8_t dataReady; /* USER CODE END 1 */ @@ -118,50 +108,58 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); - MX_USART2_UART_Init(); MX_SPI1_Init(); MX_I2C1_Init(); MX_USB_PCD_Init(); + MX_TIM15_Init(); /* USER CODE BEGIN 2 */ + + // Signalize user that device has started + LED_On(); + + // Enable power to USB, without TinyUSB will not initialize HAL_PWREx_EnableVddUSB(); + // Wait for power to stabilize HAL_Delay(100); - //ToFSensor = 1; // Select ToFSensor: 0=Left, 1=Center, 2=Right + // Initialize distance sensor + status = VL53L1X_SensorInit(DistSensorAddr); + + // Set distance mode of distance sensor for long distance (2) + status = VL53L1X_SetDistanceMode(DistSensorAddr, 2); - status = VL53L1X_SensorInit(dev); - status = VL53L1X_SetDistanceMode(dev, 2); - status = VL53L1X_SetTimingBudgetInMs(dev, 100); - status = VL53L1X_SetInterMeasurementInMs(dev, 100); - status = VL53L1X_StartRanging(dev); + // Set timing budget for each measurement + status = VL53L1X_SetTimingBudgetInMs(DistSensorAddr, 100); + status = VL53L1X_SetInterMeasurementInMs(DistSensorAddr, 100); + // Start first measurement to wake sensor up + status = VL53L1X_StartRanging(DistSensorAddr); + + HAL_Delay(1000); - status = VL53L1X_GetRangeStatus(dev, &RangeStatus); - status = VL53L1X_GetDistance(dev, &Distance); - status = VL53L1X_GetSignalRate(dev, &SignalRate); - status = VL53L1X_GetAmbientRate(dev, &AmbientRate); - status = VL53L1X_GetSpadNb(dev, &SpadNum); - status = VL53L1X_ClearInterrupt(dev); - - LED_On(); - - HAL_Delay(1); - + // Initialize TinyUSB tud_init(BOARD_DEVICE_RHPORT_NUM); - HAL_Delay(10); SPI_Init(&hspi1); + // USB utility function tud_task(); + // Define variables for correct frame sending and capturing int last_sent_idx = 0; int buff_stop_idx = 0; uint16_t image_size = 0; uint8_t cdc_buff[CDC_BUFF_SIZE+CDC_FRAME_SIZE]; - for(int i = 0; i < (CDC_BUFF_SIZE+CDC_FRAME_SIZE); i++) cdc_buff[i] = 0x00; + for(int i = 0; i < (CDC_BUFF_SIZE+CDC_FRAME_SIZE); i++) cdc_buff[i] = 0x00; // Clear frame buffer - //Distance_Sensor_Init(&hi2c1); + int Laser_LED_Switch = 0; // Variable for switching between LASER and LED + // Initial states of LED and LASER (LED off, LASER on) + HAL_GPIO_WritePin(VSET_LED_GPIO_Port, VSET_LED_Pin, GPIO_PIN_RESET); + HAL_TIM_PWM_Start(&htim15, TIM_CHANNEL_1); + + // Initialize camera module Cam_Init(&hi2c1, &hspi1); /* USER CODE END 2 */ @@ -170,41 +168,53 @@ int main(void) /* USER CODE BEGIN WHILE */ while (1) { + // USB utility function tud_task(); + // If there wasn't any image captured yet or the last one was sent out completely if(buff_stop_idx >= (int)image_size){ - LED_Off(); - + // Reset variables responsible for sending correct amount of received image buff_stop_idx = 0; last_sent_idx = 0; - //for(int i = 0; i < CDC_BUFF_SIZE; i++) cdc_buff[i] = 0x00; - - VL53L1X_GetDistance(dev, &Distance); - HAL_Delay(2); - VL53L1X_ClearInterrupt(dev); + // Get current distance of probe inside the barrel + VL53L1X_GetDistance(DistSensorAddr, &Distance); CS_Off(); CS_On(); + // Start capturing frame and wait until it is done capturing Cam_Capture(&hspi1); - image_size = Cam_FIFO_length(&hspi1); - Cam_Start_Burst_Read(&hspi1); + // Switch between LASER and LED, so the optical output power of diodes has time to stabilize until next capture + if(Laser_LED_Switch == 1){ + Laser_LED_Switch = 0; + __HAL_TIM_SET_COMPARE(&htim15, TIM_CHANNEL_1, 40); + HAL_GPIO_WritePin(VSET_LED_GPIO_Port, VSET_LED_Pin, GPIO_PIN_RESET); + } + else{ + Laser_LED_Switch = 1; + __HAL_TIM_SET_COMPARE(&htim15, TIM_CHANNEL_1, 0); + HAL_GPIO_WritePin(VSET_LED_GPIO_Port, VSET_LED_Pin, GPIO_PIN_SET); + } - //getDistance(&hi2c1); + // Get size of captured image, so that correct number of bytec can be read from camera and sent out + image_size = Cam_FIFO_length(&hspi1); - LED_On(); + // Activate burst read out mode of camera module (no need for requesting each byte individually) + Cam_Start_Burst_Read(&hspi1); continue; - } + + // Image has not been completely sent out else { - LED_Off(); + // Variable to save number of bytes that should be read from camera module int number_to_read = 0; - //for(int i = 0; i < CDC_BUFF_SIZE; i++) cdc_buff[i] = 0x00; + + // Determine how many bytes should be read from camera module - Is remaining image data to be read larger or smaller than framebuffer? if((buff_stop_idx + CDC_BUFF_SIZE) > (int) image_size){ number_to_read = (int) image_size - buff_stop_idx; } @@ -212,35 +222,58 @@ int main(void) number_to_read = CDC_BUFF_SIZE; } + // Read determined amount of bytes from camera in blocking mode HAL_SPI_Receive(&hspi1, cdc_buff, number_to_read, HAL_MAX_DELAY); + // Increment index of already read buffer data buff_stop_idx = buff_stop_idx + number_to_read; - - LED_On(); } + // Variable to store how many bytes were sent during this iteration int current_sending_idx = 0; + + // Inform user that image data transfer started + LED_On(); + + // Loop to send all image data inside cdc_buff in small CDC chunks do{ + + // USB utility function - has to be called between each cdc_write_flush() tud_task(); + + // How many bytes should be send in current CDC block int sendLen = CDC_FRAME_SIZE; if(last_sent_idx + CDC_FRAME_SIZE > buff_stop_idx){ sendLen = buff_stop_idx - last_sent_idx; } + // Select bytes, that will be send during next CDC transfer tud_cdc_write(&cdc_buff[current_sending_idx], sendLen); + + // Increment index of data to be sent for next loop iteration current_sending_idx = current_sending_idx + sendLen; last_sent_idx = last_sent_idx + sendLen; + // Transfer selected data through CDC tud_cdc_write_flush(); - //Delay between sends + + //Delay between sends - necessary for USB synchronization int i = 0; for(;i<4000;i++); } + // Repeat until all data from buffer has been sent while(last_sent_idx < buff_stop_idx); - + + // If whole image has been sent, send distance data of where image was captured if(buff_stop_idx >= (int)image_size){ - HAL_Delay(100); + + // Delay for synchronization + HAL_Delay(20); + + // USB utility function - has to be called, because it wasnt called after last tud_cdc_write_flush() tud_task(); + + // Format distance data between predefined header and footer, for clear decoding by receiver uint8_t distance_buff[12]; distance_buff[0] = 0xff; distance_buff[1] = 0xff; @@ -255,12 +288,26 @@ int main(void) distance_buff[10] = '\n'; distance_buff[11] = '\r'; + + // Prepare to send formatted distance data of image through CDC tud_cdc_write(&distance_buff[0], 12); + + // Necessary delay for synchronization HAL_Delay(1); + + // Transfer prepared Distance data through CDC tud_cdc_write_flush(); + + // Necessary delay for synchronization HAL_Delay(1); + + // USB utility function - after write_flush() tud_task(); } + + // Inform user that transfer has been completed + LED_Off(); + /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ @@ -407,37 +454,77 @@ static void MX_SPI1_Init(void) } /** - * @brief USART2 Initialization Function + * @brief TIM15 Initialization Function * @param None * @retval None */ -static void MX_USART2_UART_Init(void) +static void MX_TIM15_Init(void) { - /* USER CODE BEGIN USART2_Init 0 */ + /* USER CODE BEGIN TIM15_Init 0 */ + + /* USER CODE END TIM15_Init 0 */ - /* USER CODE END USART2_Init 0 */ + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; - /* USER CODE BEGIN USART2_Init 1 */ + /* USER CODE BEGIN TIM15_Init 1 */ - /* USER CODE END USART2_Init 1 */ - huart2.Instance = USART2; - huart2.Init.BaudRate = 115200; - huart2.Init.WordLength = UART_WORDLENGTH_8B; - huart2.Init.StopBits = UART_STOPBITS_1; - huart2.Init.Parity = UART_PARITY_NONE; - huart2.Init.Mode = UART_MODE_TX_RX; - huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; - huart2.Init.OverSampling = UART_OVERSAMPLING_16; - huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; - huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; - if (HAL_UART_Init(&huart2) != HAL_OK) + /* USER CODE END TIM15_Init 1 */ + htim15.Instance = TIM15; + htim15.Init.Prescaler = 40; + htim15.Init.CounterMode = TIM_COUNTERMODE_UP; + htim15.Init.Period = 1000; + htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim15.Init.RepetitionCounter = 0; + htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim15) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim15, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_Init(&htim15) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim15, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 500; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; + sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; + if (HAL_TIM_PWM_ConfigChannel(&htim15, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; + sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; + sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; + sBreakDeadTimeConfig.DeadTime = 0; + sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; + sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; + sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; + if (HAL_TIMEx_ConfigBreakDeadTime(&htim15, &sBreakDeadTimeConfig) != HAL_OK) { Error_Handler(); } - /* USER CODE BEGIN USART2_Init 2 */ + /* USER CODE BEGIN TIM15_Init 2 */ - /* USER CODE END USART2_Init 2 */ + /* USER CODE END TIM15_Init 2 */ + HAL_TIM_MspPostInit(&htim15); } @@ -508,17 +595,17 @@ static void MX_GPIO_Init(void) __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(DEBUG_LED_GPIO_Port, DEBUG_LED_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOA, DEBUG_LED_Pin|VSET_LED_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, CHIP_SELECT_Pin|LD3_Pin, GPIO_PIN_RESET); - /*Configure GPIO pin : DEBUG_LED_Pin */ - GPIO_InitStruct.Pin = DEBUG_LED_Pin; + /*Configure GPIO pins : DEBUG_LED_Pin VSET_LED_Pin */ + GPIO_InitStruct.Pin = DEBUG_LED_Pin|VSET_LED_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(DEBUG_LED_GPIO_Port, &GPIO_InitStruct); + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pins : CHIP_SELECT_Pin LD3_Pin */ GPIO_InitStruct.Pin = CHIP_SELECT_Pin|LD3_Pin; @@ -535,11 +622,6 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) SPI_Rx_Done_Flag = 1; } -void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) -{ - // do nothing here -} - /* USER CODE END 4 */ /** diff --git a/Firmware/Core/Src/stm32l4xx_hal_msp.c b/Firmware/Core/Src/stm32l4xx_hal_msp.c index 3decb60..eaa630f 100644 --- a/Firmware/Core/Src/stm32l4xx_hal_msp.c +++ b/Firmware/Core/Src/stm32l4xx_hal_msp.c @@ -60,7 +60,9 @@ extern DMA_HandleTypeDef hdma_spi1_tx; /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ -/** + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + /** * Initializes the Global MSP. */ void HAL_MspInit(void) @@ -268,89 +270,71 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) } /** -* @brief UART MSP Initialization +* @brief TIM_Base MSP Initialization * This function configures the hardware resources used in this example -* @param huart: UART handle pointer +* @param htim_base: TIM_Base handle pointer * @retval None */ -void HAL_UART_MspInit(UART_HandleTypeDef* huart) +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; - if(huart->Instance==USART2) + if(htim_base->Instance==TIM15) { - /* USER CODE BEGIN USART2_MspInit 0 */ + /* USER CODE BEGIN TIM15_MspInit 0 */ - /* USER CODE END USART2_MspInit 0 */ + /* USER CODE END TIM15_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM15_CLK_ENABLE(); + /* USER CODE BEGIN TIM15_MspInit 1 */ - /** Initializes the peripherals clock - */ - PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2; - PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) - { - Error_Handler(); - } + /* USER CODE END TIM15_MspInit 1 */ + } - /* Peripheral clock enable */ - __HAL_RCC_USART2_CLK_ENABLE(); +} + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(htim->Instance==TIM15) + { + /* USER CODE BEGIN TIM15_MspPostInit 0 */ + + /* USER CODE END TIM15_MspPostInit 0 */ __HAL_RCC_GPIOA_CLK_ENABLE(); - /**USART2 GPIO Configuration - PA2 ------> USART2_TX - PA15 (JTDI) ------> USART2_RX + /**TIM15 GPIO Configuration + PA2 ------> TIM15_CH1 */ - GPIO_InitStruct.Pin = VCP_TX_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF7_USART2; - HAL_GPIO_Init(VCP_TX_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = VCP_RX_Pin; + GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF3_USART2; - HAL_GPIO_Init(VCP_RX_GPIO_Port, &GPIO_InitStruct); + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF14_TIM15; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - /* USART2 interrupt Init */ - HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(USART2_IRQn); - /* USER CODE BEGIN USART2_MspInit 1 */ + /* USER CODE BEGIN TIM15_MspPostInit 1 */ - /* USER CODE END USART2_MspInit 1 */ + /* USER CODE END TIM15_MspPostInit 1 */ } } - /** -* @brief UART MSP De-Initialization +* @brief TIM_Base MSP De-Initialization * This function freeze the hardware resources used in this example -* @param huart: UART handle pointer +* @param htim_base: TIM_Base handle pointer * @retval None */ -void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { - if(huart->Instance==USART2) + if(htim_base->Instance==TIM15) { - /* USER CODE BEGIN USART2_MspDeInit 0 */ + /* USER CODE BEGIN TIM15_MspDeInit 0 */ - /* USER CODE END USART2_MspDeInit 0 */ + /* USER CODE END TIM15_MspDeInit 0 */ /* Peripheral clock disable */ - __HAL_RCC_USART2_CLK_DISABLE(); - - /**USART2 GPIO Configuration - PA2 ------> USART2_TX - PA15 (JTDI) ------> USART2_RX - */ - HAL_GPIO_DeInit(GPIOA, VCP_TX_Pin|VCP_RX_Pin); - - /* USART2 interrupt DeInit */ - HAL_NVIC_DisableIRQ(USART2_IRQn); - /* USER CODE BEGIN USART2_MspDeInit 1 */ + __HAL_RCC_TIM15_CLK_DISABLE(); + /* USER CODE BEGIN TIM15_MspDeInit 1 */ - /* USER CODE END USART2_MspDeInit 1 */ + /* USER CODE END TIM15_MspDeInit 1 */ } } diff --git a/Firmware/Core/Src/stm32l4xx_it.c b/Firmware/Core/Src/stm32l4xx_it.c index 811991e..f097ce9 100644 --- a/Firmware/Core/Src/stm32l4xx_it.c +++ b/Firmware/Core/Src/stm32l4xx_it.c @@ -58,7 +58,6 @@ extern DMA_HandleTypeDef hdma_spi1_rx; extern DMA_HandleTypeDef hdma_spi1_tx; extern SPI_HandleTypeDef hspi1; -extern UART_HandleTypeDef huart2; extern PCD_HandleTypeDef hpcd_USB_FS; /* USER CODE BEGIN EV */ @@ -244,20 +243,6 @@ void SPI1_IRQHandler(void) /* USER CODE END SPI1_IRQn 1 */ } -/** - * @brief This function handles USART2 global interrupt. - */ -void USART2_IRQHandler(void) -{ - /* USER CODE BEGIN USART2_IRQn 0 */ - - /* USER CODE END USART2_IRQn 0 */ - HAL_UART_IRQHandler(&huart2); - /* USER CODE BEGIN USART2_IRQn 1 */ - - /* USER CODE END USART2_IRQn 1 */ -} - /** * @brief This function handles USB event interrupt through EXTI line 17. */ diff --git a/Firmware/Core/Src/usb_descriptors.c b/Firmware/Core/Src/usb_descriptors.c index 7ddb426..fe347ba 100644 --- a/Firmware/Core/Src/usb_descriptors.c +++ b/Firmware/Core/Src/usb_descriptors.c @@ -1,4 +1,15 @@ -/* +/** + ****************************************************************************** + * @file : usb_descriptors.c + * @brief : Descriptors of usb communication. + * @author : Adam Prochazka + ****************************************************************************** + + * @attention + * + * File was from the large part taken from the TinyUSB repository and just slightly configured for projects usecase. + * Original file contains this disclaimer: + * * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -216,11 +227,11 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) // array of pointer to string descriptors char const* string_desc_arr [] = { - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "TinyUSB", // 1: Manufacturer - "TinyUSB test STM32L432", // 2: Product - "123456", // 3: Serials, should use chip ID - "TinyUSB CDC", // 4: CDC Interface + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "Adam Prochazka", // 1: Manufacturer + "Profilometer Probe", // 2: Product + "2023", // 3: Serials, should use chip ID + "TinyUSB CDC", // 4: CDC Interface }; static uint16_t _desc_str[32]; diff --git a/Firmware/Core/Src/vl53l1_platform.c b/Firmware/Core/Src/vl53l1_platform.c index 1fa6d3f..c705d7a 100644 --- a/Firmware/Core/Src/vl53l1_platform.c +++ b/Firmware/Core/Src/vl53l1_platform.c @@ -1,5 +1,15 @@ - -/* +/** +****************************************************************************** +* @file : vl53l1_platform.c +* @brief : Platform specific configuration of distance sencor communication. +* @author : Adam Prochazka +****************************************************************************** + +* @attention +* File was partly taken from the VL53L1 Platform and configured for NucleoL432KC platform. +* Configuration consisted mainly of implementing basic I2C communication functions, that were specific for this project. +* Original file contains this disclaimer: +* * This file is part of VL53L1 Platform * * Copyright (c) 2016, STMicroelectronics - All Rights Reserved @@ -36,7 +46,6 @@ #include "vl53l1_platform.h" #include "vl53l1_platform_log.h" -//#include "vl53l1_api.h" #include "vl53l1_platform_user_config.h" #include "stm32xxx_hal.h" #include "main.h" @@ -44,7 +53,6 @@ #include #include #include "vl53l1_error_codes.h" -//#include "X-NUCLEO-53L1A1.h" #define I2C_TIME_OUT_BASE 10 @@ -78,25 +86,16 @@ uint8_t _I2CBuffer[256]; int _I2CWrite(uint16_t Dev, uint8_t *pdata, uint32_t count) { int status; - //int i2c_time_out = I2C_TIME_OUT_BASE+ count* I2C_TIME_OUT_BYTE; status = HAL_I2C_Master_Transmit(&hi2c1, Dev, pdata, count, HAL_MAX_DELAY); - if (status) { - //VL6180x_ErrLog("I2C error 0x%x %d len", dev->I2cAddr, len); - //XNUCLEO6180XA1_I2C1_Init(&hi2c1); - } return status; } int _I2CRead(uint16_t Dev, uint8_t *pdata, uint32_t count) { int status; - //int i2c_time_out = I2C_TIME_OUT_BASE+ count* I2C_TIME_OUT_BYTE; status = HAL_I2C_Master_Receive(&hi2c1, Dev|1, pdata, count, HAL_MAX_DELAY); - if (status) { - //VL6180x_ErrLog("I2C error 0x%x %d len", dev->I2cAddr, len); - //XNUCLEO6180XA1_I2C1_Init(&hi2c1); - } + return status; } diff --git a/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h b/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h deleted file mode 100644 index 73bdece..0000000 --- a/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h +++ /dev/null @@ -1,1788 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l4xx_hal_uart.h - * @author MCD Application Team - * @brief Header file of UART HAL module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef STM32L4xx_HAL_UART_H -#define STM32L4xx_HAL_UART_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l4xx_hal_def.h" - -/** @addtogroup STM32L4xx_HAL_Driver - * @{ - */ - -/** @addtogroup UART - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/** @defgroup UART_Exported_Types UART Exported Types - * @{ - */ - -/** - * @brief UART Init Structure definition - */ -typedef struct -{ - uint32_t BaudRate; /*!< This member configures the UART communication baud rate. - The baud rate register is computed using the following formula: - LPUART: - ======= - Baud Rate Register = ((256 * lpuart_ker_ckpres) / ((huart->Init.BaudRate))) - where lpuart_ker_ck_pres is the UART input clock - (divided by a prescaler if applicable) - UART: - ===== - - If oversampling is 16 or in LIN mode, - Baud Rate Register = ((uart_ker_ckpres) / ((huart->Init.BaudRate))) - - If oversampling is 8, - Baud Rate Register[15:4] = ((2 * uart_ker_ckpres) / - ((huart->Init.BaudRate)))[15:4] - Baud Rate Register[3] = 0 - Baud Rate Register[2:0] = (((2 * uart_ker_ckpres) / - ((huart->Init.BaudRate)))[3:0]) >> 1 - where uart_ker_ck_pres is the UART input clock - (divided by a prescaler if applicable) */ - - uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. - This parameter can be a value of @ref UARTEx_Word_Length. */ - - uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. - This parameter can be a value of @ref UART_Stop_Bits. */ - - uint32_t Parity; /*!< Specifies the parity mode. - This parameter can be a value of @ref UART_Parity - @note When parity is enabled, the computed parity is inserted - at the MSB position of the transmitted data (9th bit when - the word length is set to 9 data bits; 8th bit when the - word length is set to 8 data bits). */ - - uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. - This parameter can be a value of @ref UART_Mode. */ - - uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled - or disabled. - This parameter can be a value of @ref UART_Hardware_Flow_Control. */ - - uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, - to achieve higher speed (up to f_PCLK/8). - This parameter can be a value of @ref UART_Over_Sampling. */ - - uint32_t OneBitSampling; /*!< Specifies whether a single sample or three samples' majority vote is selected. - Selecting the single sample method increases the receiver tolerance to clock - deviations. This parameter can be a value of @ref UART_OneBit_Sampling. */ - -#if defined(USART_PRESC_PRESCALER) - uint32_t ClockPrescaler; /*!< Specifies the prescaler value used to divide the UART clock source. - This parameter can be a value of @ref UART_ClockPrescaler. */ -#endif /* USART_PRESC_PRESCALER */ - -} UART_InitTypeDef; - -/** - * @brief UART Advanced Features initialization structure definition - */ -typedef struct -{ - uint32_t AdvFeatureInit; /*!< Specifies which advanced UART features is initialized. Several - Advanced Features may be initialized at the same time . - This parameter can be a value of - @ref UART_Advanced_Features_Initialization_Type. */ - - uint32_t TxPinLevelInvert; /*!< Specifies whether the TX pin active level is inverted. - This parameter can be a value of @ref UART_Tx_Inv. */ - - uint32_t RxPinLevelInvert; /*!< Specifies whether the RX pin active level is inverted. - This parameter can be a value of @ref UART_Rx_Inv. */ - - uint32_t DataInvert; /*!< Specifies whether data are inverted (positive/direct logic - vs negative/inverted logic). - This parameter can be a value of @ref UART_Data_Inv. */ - - uint32_t Swap; /*!< Specifies whether TX and RX pins are swapped. - This parameter can be a value of @ref UART_Rx_Tx_Swap. */ - - uint32_t OverrunDisable; /*!< Specifies whether the reception overrun detection is disabled. - This parameter can be a value of @ref UART_Overrun_Disable. */ - - uint32_t DMADisableonRxError; /*!< Specifies whether the DMA is disabled in case of reception error. - This parameter can be a value of @ref UART_DMA_Disable_on_Rx_Error. */ - - uint32_t AutoBaudRateEnable; /*!< Specifies whether auto Baud rate detection is enabled. - This parameter can be a value of @ref UART_AutoBaudRate_Enable. */ - - uint32_t AutoBaudRateMode; /*!< If auto Baud rate detection is enabled, specifies how the rate - detection is carried out. - This parameter can be a value of @ref UART_AutoBaud_Rate_Mode. */ - - uint32_t MSBFirst; /*!< Specifies whether MSB is sent first on UART line. - This parameter can be a value of @ref UART_MSB_First. */ -} UART_AdvFeatureInitTypeDef; - -/** - * @brief HAL UART State definition - * @note HAL UART State value is a combination of 2 different substates: - * gState and RxState (see @ref UART_State_Definition). - * - gState contains UART state information related to global Handle management - * and also information related to Tx operations. - * gState value coding follow below described bitmap : - * b7-b6 Error information - * 00 : No Error - * 01 : (Not Used) - * 10 : Timeout - * 11 : Error - * b5 Peripheral initialization status - * 0 : Reset (Peripheral not initialized) - * 1 : Init done (Peripheral initialized. HAL UART Init function already called) - * b4-b3 (not used) - * xx : Should be set to 00 - * b2 Intrinsic process state - * 0 : Ready - * 1 : Busy (Peripheral busy with some configuration or internal operations) - * b1 (not used) - * x : Should be set to 0 - * b0 Tx state - * 0 : Ready (no Tx operation ongoing) - * 1 : Busy (Tx operation ongoing) - * - RxState contains information related to Rx operations. - * RxState value coding follow below described bitmap : - * b7-b6 (not used) - * xx : Should be set to 00 - * b5 Peripheral initialization status - * 0 : Reset (Peripheral not initialized) - * 1 : Init done (Peripheral initialized) - * b4-b2 (not used) - * xxx : Should be set to 000 - * b1 Rx state - * 0 : Ready (no Rx operation ongoing) - * 1 : Busy (Rx operation ongoing) - * b0 (not used) - * x : Should be set to 0. - */ -typedef uint32_t HAL_UART_StateTypeDef; - -/** - * @brief UART clock sources definition - */ -typedef enum -{ - UART_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ - UART_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ - UART_CLOCKSOURCE_HSI = 0x02U, /*!< HSI clock source */ - UART_CLOCKSOURCE_SYSCLK = 0x04U, /*!< SYSCLK clock source */ - UART_CLOCKSOURCE_LSE = 0x08U, /*!< LSE clock source */ - UART_CLOCKSOURCE_UNDEFINED = 0x10U /*!< Undefined clock source */ -} UART_ClockSourceTypeDef; - -/** - * @brief HAL UART Reception type definition - * @note HAL UART Reception type value aims to identify which type of Reception is ongoing. - * It is expected to admit following values : - * HAL_UART_RECEPTION_STANDARD = 0x00U, - * HAL_UART_RECEPTION_TOIDLE = 0x01U, - * HAL_UART_RECEPTION_TORTO = 0x02U, - * HAL_UART_RECEPTION_TOCHARMATCH = 0x03U, - */ -typedef uint32_t HAL_UART_RxTypeTypeDef; - -/** - * @brief UART handle Structure definition - */ -typedef struct __UART_HandleTypeDef -{ - USART_TypeDef *Instance; /*!< UART registers base address */ - - UART_InitTypeDef Init; /*!< UART communication parameters */ - - UART_AdvFeatureInitTypeDef AdvancedInit; /*!< UART Advanced Features initialization parameters */ - - const uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */ - - uint16_t TxXferSize; /*!< UART Tx Transfer size */ - - __IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */ - - uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */ - - uint16_t RxXferSize; /*!< UART Rx Transfer size */ - - __IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */ - - uint16_t Mask; /*!< UART Rx RDR register mask */ - -#if defined(USART_CR1_FIFOEN) - uint32_t FifoMode; /*!< Specifies if the FIFO mode is being used. - This parameter can be a value of @ref UARTEx_FIFO_mode. */ - - uint16_t NbRxDataToProcess; /*!< Number of data to process during RX ISR execution */ - - uint16_t NbTxDataToProcess; /*!< Number of data to process during TX ISR execution */ - -#endif /*USART_CR1_FIFOEN */ - __IO HAL_UART_RxTypeTypeDef ReceptionType; /*!< Type of ongoing reception */ - - void (*RxISR)(struct __UART_HandleTypeDef *huart); /*!< Function pointer on Rx IRQ handler */ - - void (*TxISR)(struct __UART_HandleTypeDef *huart); /*!< Function pointer on Tx IRQ handler */ - - DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */ - - DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */ - - HAL_LockTypeDef Lock; /*!< Locking object */ - - __IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management - and also related to Tx operations. This parameter - can be a value of @ref HAL_UART_StateTypeDef */ - - __IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations. This - parameter can be a value of @ref HAL_UART_StateTypeDef */ - - __IO uint32_t ErrorCode; /*!< UART Error code */ - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - void (* TxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Half Complete Callback */ - void (* TxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Complete Callback */ - void (* RxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Half Complete Callback */ - void (* RxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Complete Callback */ - void (* ErrorCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Error Callback */ - void (* AbortCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Complete Callback */ - void (* AbortTransmitCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Transmit Complete Callback */ - void (* AbortReceiveCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Receive Complete Callback */ - void (* WakeupCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Wakeup Callback */ -#if defined(USART_CR1_FIFOEN) - void (* RxFifoFullCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Fifo Full Callback */ - void (* TxFifoEmptyCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Fifo Empty Callback */ -#endif /* USART_CR1_FIFOEN */ - void (* RxEventCallback)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< UART Reception Event Callback */ - - void (* MspInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp Init callback */ - void (* MspDeInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp DeInit callback */ -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - -} UART_HandleTypeDef; - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) -/** - * @brief HAL UART Callback ID enumeration definition - */ -typedef enum -{ - HAL_UART_TX_HALFCOMPLETE_CB_ID = 0x00U, /*!< UART Tx Half Complete Callback ID */ - HAL_UART_TX_COMPLETE_CB_ID = 0x01U, /*!< UART Tx Complete Callback ID */ - HAL_UART_RX_HALFCOMPLETE_CB_ID = 0x02U, /*!< UART Rx Half Complete Callback ID */ - HAL_UART_RX_COMPLETE_CB_ID = 0x03U, /*!< UART Rx Complete Callback ID */ - HAL_UART_ERROR_CB_ID = 0x04U, /*!< UART Error Callback ID */ - HAL_UART_ABORT_COMPLETE_CB_ID = 0x05U, /*!< UART Abort Complete Callback ID */ - HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID = 0x06U, /*!< UART Abort Transmit Complete Callback ID */ - HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID = 0x07U, /*!< UART Abort Receive Complete Callback ID */ - HAL_UART_WAKEUP_CB_ID = 0x08U, /*!< UART Wakeup Callback ID */ -#if defined(USART_CR1_FIFOEN) - HAL_UART_RX_FIFO_FULL_CB_ID = 0x09U, /*!< UART Rx Fifo Full Callback ID */ - HAL_UART_TX_FIFO_EMPTY_CB_ID = 0x0AU, /*!< UART Tx Fifo Empty Callback ID */ -#endif /* USART_CR1_FIFOEN */ - - HAL_UART_MSPINIT_CB_ID = 0x0BU, /*!< UART MspInit callback ID */ - HAL_UART_MSPDEINIT_CB_ID = 0x0CU /*!< UART MspDeInit callback ID */ - -} HAL_UART_CallbackIDTypeDef; - -/** - * @brief HAL UART Callback pointer definition - */ -typedef void (*pUART_CallbackTypeDef)(UART_HandleTypeDef *huart); /*!< pointer to an UART callback function */ -typedef void (*pUART_RxEventCallbackTypeDef) -(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< pointer to a UART Rx Event specific callback function */ - -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - -/** - * @} - */ - -/* Exported constants --------------------------------------------------------*/ -/** @defgroup UART_Exported_Constants UART Exported Constants - * @{ - */ - -/** @defgroup UART_State_Definition UART State Code Definition - * @{ - */ -#define HAL_UART_STATE_RESET 0x00000000U /*!< Peripheral is not initialized - Value is allowed for gState and RxState */ -#define HAL_UART_STATE_READY 0x00000020U /*!< Peripheral Initialized and ready for use - Value is allowed for gState and RxState */ -#define HAL_UART_STATE_BUSY 0x00000024U /*!< an internal process is ongoing - Value is allowed for gState only */ -#define HAL_UART_STATE_BUSY_TX 0x00000021U /*!< Data Transmission process is ongoing - Value is allowed for gState only */ -#define HAL_UART_STATE_BUSY_RX 0x00000022U /*!< Data Reception process is ongoing - Value is allowed for RxState only */ -#define HAL_UART_STATE_BUSY_TX_RX 0x00000023U /*!< Data Transmission and Reception process is ongoing - Not to be used for neither gState nor RxState.Value is result - of combination (Or) between gState and RxState values */ -#define HAL_UART_STATE_TIMEOUT 0x000000A0U /*!< Timeout state - Value is allowed for gState only */ -#define HAL_UART_STATE_ERROR 0x000000E0U /*!< Error - Value is allowed for gState only */ -/** - * @} - */ - -/** @defgroup UART_Error_Definition UART Error Definition - * @{ - */ -#define HAL_UART_ERROR_NONE (0x00000000U) /*!< No error */ -#define HAL_UART_ERROR_PE (0x00000001U) /*!< Parity error */ -#define HAL_UART_ERROR_NE (0x00000002U) /*!< Noise error */ -#define HAL_UART_ERROR_FE (0x00000004U) /*!< Frame error */ -#define HAL_UART_ERROR_ORE (0x00000008U) /*!< Overrun error */ -#define HAL_UART_ERROR_DMA (0x00000010U) /*!< DMA transfer error */ -#define HAL_UART_ERROR_RTO (0x00000020U) /*!< Receiver Timeout error */ - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) -#define HAL_UART_ERROR_INVALID_CALLBACK (0x00000040U) /*!< Invalid Callback error */ -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ -/** - * @} - */ - -/** @defgroup UART_Stop_Bits UART Number of Stop Bits - * @{ - */ -#define UART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< UART frame with 0.5 stop bit */ -#define UART_STOPBITS_1 0x00000000U /*!< UART frame with 1 stop bit */ -#define UART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< UART frame with 1.5 stop bits */ -#define UART_STOPBITS_2 USART_CR2_STOP_1 /*!< UART frame with 2 stop bits */ -/** - * @} - */ - -/** @defgroup UART_Parity UART Parity - * @{ - */ -#define UART_PARITY_NONE 0x00000000U /*!< No parity */ -#define UART_PARITY_EVEN USART_CR1_PCE /*!< Even parity */ -#define UART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Odd parity */ -/** - * @} - */ - -/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control - * @{ - */ -#define UART_HWCONTROL_NONE 0x00000000U /*!< No hardware control */ -#define UART_HWCONTROL_RTS USART_CR3_RTSE /*!< Request To Send */ -#define UART_HWCONTROL_CTS USART_CR3_CTSE /*!< Clear To Send */ -#define UART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) /*!< Request and Clear To Send */ -/** - * @} - */ - -/** @defgroup UART_Mode UART Transfer Mode - * @{ - */ -#define UART_MODE_RX USART_CR1_RE /*!< RX mode */ -#define UART_MODE_TX USART_CR1_TE /*!< TX mode */ -#define UART_MODE_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< RX and TX mode */ -/** - * @} - */ - -/** @defgroup UART_State UART State - * @{ - */ -#define UART_STATE_DISABLE 0x00000000U /*!< UART disabled */ -#define UART_STATE_ENABLE USART_CR1_UE /*!< UART enabled */ -/** - * @} - */ - -/** @defgroup UART_Over_Sampling UART Over Sampling - * @{ - */ -#define UART_OVERSAMPLING_16 0x00000000U /*!< Oversampling by 16 */ -#define UART_OVERSAMPLING_8 USART_CR1_OVER8 /*!< Oversampling by 8 */ -/** - * @} - */ - -/** @defgroup UART_OneBit_Sampling UART One Bit Sampling Method - * @{ - */ -#define UART_ONE_BIT_SAMPLE_DISABLE 0x00000000U /*!< One-bit sampling disable */ -#define UART_ONE_BIT_SAMPLE_ENABLE USART_CR3_ONEBIT /*!< One-bit sampling enable */ -/** - * @} - */ - -#if defined(USART_PRESC_PRESCALER) -/** @defgroup UART_ClockPrescaler UART Clock Prescaler - * @{ - */ -#define UART_PRESCALER_DIV1 0x00000000U /*!< fclk_pres = fclk */ -#define UART_PRESCALER_DIV2 0x00000001U /*!< fclk_pres = fclk/2 */ -#define UART_PRESCALER_DIV4 0x00000002U /*!< fclk_pres = fclk/4 */ -#define UART_PRESCALER_DIV6 0x00000003U /*!< fclk_pres = fclk/6 */ -#define UART_PRESCALER_DIV8 0x00000004U /*!< fclk_pres = fclk/8 */ -#define UART_PRESCALER_DIV10 0x00000005U /*!< fclk_pres = fclk/10 */ -#define UART_PRESCALER_DIV12 0x00000006U /*!< fclk_pres = fclk/12 */ -#define UART_PRESCALER_DIV16 0x00000007U /*!< fclk_pres = fclk/16 */ -#define UART_PRESCALER_DIV32 0x00000008U /*!< fclk_pres = fclk/32 */ -#define UART_PRESCALER_DIV64 0x00000009U /*!< fclk_pres = fclk/64 */ -#define UART_PRESCALER_DIV128 0x0000000AU /*!< fclk_pres = fclk/128 */ -#define UART_PRESCALER_DIV256 0x0000000BU /*!< fclk_pres = fclk/256 */ -/** - * @} - */ - -#endif /* USART_PRESC_PRESCALER */ -/** @defgroup UART_AutoBaud_Rate_Mode UART Advanced Feature AutoBaud Rate Mode - * @{ - */ -#define UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT 0x00000000U /*!< Auto Baud rate detection - on start bit */ -#define UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE USART_CR2_ABRMODE_0 /*!< Auto Baud rate detection - on falling edge */ -#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME USART_CR2_ABRMODE_1 /*!< Auto Baud rate detection - on 0x7F frame detection */ -#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME USART_CR2_ABRMODE /*!< Auto Baud rate detection - on 0x55 frame detection */ -/** - * @} - */ - -/** @defgroup UART_Receiver_Timeout UART Receiver Timeout - * @{ - */ -#define UART_RECEIVER_TIMEOUT_DISABLE 0x00000000U /*!< UART Receiver Timeout disable */ -#define UART_RECEIVER_TIMEOUT_ENABLE USART_CR2_RTOEN /*!< UART Receiver Timeout enable */ -/** - * @} - */ - -/** @defgroup UART_LIN UART Local Interconnection Network mode - * @{ - */ -#define UART_LIN_DISABLE 0x00000000U /*!< Local Interconnect Network disable */ -#define UART_LIN_ENABLE USART_CR2_LINEN /*!< Local Interconnect Network enable */ -/** - * @} - */ - -/** @defgroup UART_LIN_Break_Detection UART LIN Break Detection - * @{ - */ -#define UART_LINBREAKDETECTLENGTH_10B 0x00000000U /*!< LIN 10-bit break detection length */ -#define UART_LINBREAKDETECTLENGTH_11B USART_CR2_LBDL /*!< LIN 11-bit break detection length */ -/** - * @} - */ - -/** @defgroup UART_DMA_Tx UART DMA Tx - * @{ - */ -#define UART_DMA_TX_DISABLE 0x00000000U /*!< UART DMA TX disabled */ -#define UART_DMA_TX_ENABLE USART_CR3_DMAT /*!< UART DMA TX enabled */ -/** - * @} - */ - -/** @defgroup UART_DMA_Rx UART DMA Rx - * @{ - */ -#define UART_DMA_RX_DISABLE 0x00000000U /*!< UART DMA RX disabled */ -#define UART_DMA_RX_ENABLE USART_CR3_DMAR /*!< UART DMA RX enabled */ -/** - * @} - */ - -/** @defgroup UART_Half_Duplex_Selection UART Half Duplex Selection - * @{ - */ -#define UART_HALF_DUPLEX_DISABLE 0x00000000U /*!< UART half-duplex disabled */ -#define UART_HALF_DUPLEX_ENABLE USART_CR3_HDSEL /*!< UART half-duplex enabled */ -/** - * @} - */ - -/** @defgroup UART_WakeUp_Methods UART WakeUp Methods - * @{ - */ -#define UART_WAKEUPMETHOD_IDLELINE 0x00000000U /*!< UART wake-up on idle line */ -#define UART_WAKEUPMETHOD_ADDRESSMARK USART_CR1_WAKE /*!< UART wake-up on address mark */ -/** - * @} - */ - -/** @defgroup UART_Request_Parameters UART Request Parameters - * @{ - */ -#define UART_AUTOBAUD_REQUEST USART_RQR_ABRRQ /*!< Auto-Baud Rate Request */ -#define UART_SENDBREAK_REQUEST USART_RQR_SBKRQ /*!< Send Break Request */ -#define UART_MUTE_MODE_REQUEST USART_RQR_MMRQ /*!< Mute Mode Request */ -#define UART_RXDATA_FLUSH_REQUEST USART_RQR_RXFRQ /*!< Receive Data flush Request */ -#define UART_TXDATA_FLUSH_REQUEST USART_RQR_TXFRQ /*!< Transmit data flush Request */ -/** - * @} - */ - -/** @defgroup UART_Advanced_Features_Initialization_Type UART Advanced Feature Initialization Type - * @{ - */ -#define UART_ADVFEATURE_NO_INIT 0x00000000U /*!< No advanced feature initialization */ -#define UART_ADVFEATURE_TXINVERT_INIT 0x00000001U /*!< TX pin active level inversion */ -#define UART_ADVFEATURE_RXINVERT_INIT 0x00000002U /*!< RX pin active level inversion */ -#define UART_ADVFEATURE_DATAINVERT_INIT 0x00000004U /*!< Binary data inversion */ -#define UART_ADVFEATURE_SWAP_INIT 0x00000008U /*!< TX/RX pins swap */ -#define UART_ADVFEATURE_RXOVERRUNDISABLE_INIT 0x00000010U /*!< RX overrun disable */ -#define UART_ADVFEATURE_DMADISABLEONERROR_INIT 0x00000020U /*!< DMA disable on Reception Error */ -#define UART_ADVFEATURE_AUTOBAUDRATE_INIT 0x00000040U /*!< Auto Baud rate detection initialization */ -#define UART_ADVFEATURE_MSBFIRST_INIT 0x00000080U /*!< Most significant bit sent/received first */ -/** - * @} - */ - -/** @defgroup UART_Tx_Inv UART Advanced Feature TX Pin Active Level Inversion - * @{ - */ -#define UART_ADVFEATURE_TXINV_DISABLE 0x00000000U /*!< TX pin active level inversion disable */ -#define UART_ADVFEATURE_TXINV_ENABLE USART_CR2_TXINV /*!< TX pin active level inversion enable */ -/** - * @} - */ - -/** @defgroup UART_Rx_Inv UART Advanced Feature RX Pin Active Level Inversion - * @{ - */ -#define UART_ADVFEATURE_RXINV_DISABLE 0x00000000U /*!< RX pin active level inversion disable */ -#define UART_ADVFEATURE_RXINV_ENABLE USART_CR2_RXINV /*!< RX pin active level inversion enable */ -/** - * @} - */ - -/** @defgroup UART_Data_Inv UART Advanced Feature Binary Data Inversion - * @{ - */ -#define UART_ADVFEATURE_DATAINV_DISABLE 0x00000000U /*!< Binary data inversion disable */ -#define UART_ADVFEATURE_DATAINV_ENABLE USART_CR2_DATAINV /*!< Binary data inversion enable */ -/** - * @} - */ - -/** @defgroup UART_Rx_Tx_Swap UART Advanced Feature RX TX Pins Swap - * @{ - */ -#define UART_ADVFEATURE_SWAP_DISABLE 0x00000000U /*!< TX/RX pins swap disable */ -#define UART_ADVFEATURE_SWAP_ENABLE USART_CR2_SWAP /*!< TX/RX pins swap enable */ -/** - * @} - */ - -/** @defgroup UART_Overrun_Disable UART Advanced Feature Overrun Disable - * @{ - */ -#define UART_ADVFEATURE_OVERRUN_ENABLE 0x00000000U /*!< RX overrun enable */ -#define UART_ADVFEATURE_OVERRUN_DISABLE USART_CR3_OVRDIS /*!< RX overrun disable */ -/** - * @} - */ - -/** @defgroup UART_AutoBaudRate_Enable UART Advanced Feature Auto BaudRate Enable - * @{ - */ -#define UART_ADVFEATURE_AUTOBAUDRATE_DISABLE 0x00000000U /*!< RX Auto Baud rate detection enable */ -#define UART_ADVFEATURE_AUTOBAUDRATE_ENABLE USART_CR2_ABREN /*!< RX Auto Baud rate detection disable */ -/** - * @} - */ - -/** @defgroup UART_DMA_Disable_on_Rx_Error UART Advanced Feature DMA Disable On Rx Error - * @{ - */ -#define UART_ADVFEATURE_DMA_ENABLEONRXERROR 0x00000000U /*!< DMA enable on Reception Error */ -#define UART_ADVFEATURE_DMA_DISABLEONRXERROR USART_CR3_DDRE /*!< DMA disable on Reception Error */ -/** - * @} - */ - -/** @defgroup UART_MSB_First UART Advanced Feature MSB First - * @{ - */ -#define UART_ADVFEATURE_MSBFIRST_DISABLE 0x00000000U /*!< Most significant bit sent/received - first disable */ -#define UART_ADVFEATURE_MSBFIRST_ENABLE USART_CR2_MSBFIRST /*!< Most significant bit sent/received - first enable */ -/** - * @} - */ - -/** @defgroup UART_Stop_Mode_Enable UART Advanced Feature Stop Mode Enable - * @{ - */ -#define UART_ADVFEATURE_STOPMODE_DISABLE 0x00000000U /*!< UART stop mode disable */ -#define UART_ADVFEATURE_STOPMODE_ENABLE USART_CR1_UESM /*!< UART stop mode enable */ -/** - * @} - */ - -/** @defgroup UART_Mute_Mode UART Advanced Feature Mute Mode Enable - * @{ - */ -#define UART_ADVFEATURE_MUTEMODE_DISABLE 0x00000000U /*!< UART mute mode disable */ -#define UART_ADVFEATURE_MUTEMODE_ENABLE USART_CR1_MME /*!< UART mute mode enable */ -/** - * @} - */ - -/** @defgroup UART_CR2_ADDRESS_LSB_POS UART Address-matching LSB Position In CR2 Register - * @{ - */ -#define UART_CR2_ADDRESS_LSB_POS 24U /*!< UART address-matching LSB position in CR2 register */ -/** - * @} - */ - -/** @defgroup UART_WakeUp_from_Stop_Selection UART WakeUp From Stop Selection - * @{ - */ -#define UART_WAKEUP_ON_ADDRESS 0x00000000U /*!< UART wake-up on address */ -#define UART_WAKEUP_ON_STARTBIT USART_CR3_WUS_1 /*!< UART wake-up on start bit */ -#define UART_WAKEUP_ON_READDATA_NONEMPTY USART_CR3_WUS /*!< UART wake-up on receive data register - not empty or RXFIFO is not empty */ -/** - * @} - */ - -/** @defgroup UART_DriverEnable_Polarity UART DriverEnable Polarity - * @{ - */ -#define UART_DE_POLARITY_HIGH 0x00000000U /*!< Driver enable signal is active high */ -#define UART_DE_POLARITY_LOW USART_CR3_DEP /*!< Driver enable signal is active low */ -/** - * @} - */ - -/** @defgroup UART_CR1_DEAT_ADDRESS_LSB_POS UART Driver Enable Assertion Time LSB Position In CR1 Register - * @{ - */ -#define UART_CR1_DEAT_ADDRESS_LSB_POS 21U /*!< UART Driver Enable assertion time LSB - position in CR1 register */ -/** - * @} - */ - -/** @defgroup UART_CR1_DEDT_ADDRESS_LSB_POS UART Driver Enable DeAssertion Time LSB Position In CR1 Register - * @{ - */ -#define UART_CR1_DEDT_ADDRESS_LSB_POS 16U /*!< UART Driver Enable de-assertion time LSB - position in CR1 register */ -/** - * @} - */ - -/** @defgroup UART_Interruption_Mask UART Interruptions Flag Mask - * @{ - */ -#define UART_IT_MASK 0x001FU /*!< UART interruptions flags mask */ -/** - * @} - */ - -/** @defgroup UART_TimeOut_Value UART polling-based communications time-out value - * @{ - */ -#define HAL_UART_TIMEOUT_VALUE 0x1FFFFFFU /*!< UART polling-based communications time-out value */ -/** - * @} - */ - -/** @defgroup UART_Flags UART Status Flags - * Elements values convention: 0xXXXX - * - 0xXXXX : Flag mask in the ISR register - * @{ - */ -#if defined(USART_CR1_FIFOEN) -#define UART_FLAG_TXFT USART_ISR_TXFT /*!< UART TXFIFO threshold flag */ -#define UART_FLAG_RXFT USART_ISR_RXFT /*!< UART RXFIFO threshold flag */ -#define UART_FLAG_RXFF USART_ISR_RXFF /*!< UART RXFIFO Full flag */ -#define UART_FLAG_TXFE USART_ISR_TXFE /*!< UART TXFIFO Empty flag */ -#endif /* USART_CR1_FIFOEN */ -#define UART_FLAG_REACK USART_ISR_REACK /*!< UART receive enable acknowledge flag */ -#define UART_FLAG_TEACK USART_ISR_TEACK /*!< UART transmit enable acknowledge flag */ -#define UART_FLAG_WUF USART_ISR_WUF /*!< UART wake-up from stop mode flag */ -#define UART_FLAG_RWU USART_ISR_RWU /*!< UART receiver wake-up from mute mode flag */ -#define UART_FLAG_SBKF USART_ISR_SBKF /*!< UART send break flag */ -#define UART_FLAG_CMF USART_ISR_CMF /*!< UART character match flag */ -#define UART_FLAG_BUSY USART_ISR_BUSY /*!< UART busy flag */ -#define UART_FLAG_ABRF USART_ISR_ABRF /*!< UART auto Baud rate flag */ -#define UART_FLAG_ABRE USART_ISR_ABRE /*!< UART auto Baud rate error */ -#define UART_FLAG_RTOF USART_ISR_RTOF /*!< UART receiver timeout flag */ -#define UART_FLAG_CTS USART_ISR_CTS /*!< UART clear to send flag */ -#define UART_FLAG_CTSIF USART_ISR_CTSIF /*!< UART clear to send interrupt flag */ -#define UART_FLAG_LBDF USART_ISR_LBDF /*!< UART LIN break detection flag */ -#if defined(USART_CR1_FIFOEN) -#define UART_FLAG_TXE USART_ISR_TXE_TXFNF /*!< UART transmit data register empty */ -#define UART_FLAG_TXFNF USART_ISR_TXE_TXFNF /*!< UART TXFIFO not full */ -#else -#define UART_FLAG_TXE USART_ISR_TXE /*!< UART transmit data register empty */ -#endif /* USART_CR1_FIFOEN */ -#define UART_FLAG_TC USART_ISR_TC /*!< UART transmission complete */ -#if defined(USART_CR1_FIFOEN) -#define UART_FLAG_RXNE USART_ISR_RXNE_RXFNE /*!< UART read data register not empty */ -#define UART_FLAG_RXFNE USART_ISR_RXNE_RXFNE /*!< UART RXFIFO not empty */ -#else -#define UART_FLAG_RXNE USART_ISR_RXNE /*!< UART read data register not empty */ -#endif /* USART_CR1_FIFOEN */ -#define UART_FLAG_IDLE USART_ISR_IDLE /*!< UART idle flag */ -#define UART_FLAG_ORE USART_ISR_ORE /*!< UART overrun error */ -#define UART_FLAG_NE USART_ISR_NE /*!< UART noise error */ -#define UART_FLAG_FE USART_ISR_FE /*!< UART frame error */ -#define UART_FLAG_PE USART_ISR_PE /*!< UART parity error */ -/** - * @} - */ - -/** @defgroup UART_Interrupt_definition UART Interrupts Definition - * Elements values convention: 000ZZZZZ0XXYYYYYb - * - YYYYY : Interrupt source position in the XX register (5bits) - * - XX : Interrupt source register (2bits) - * - 01: CR1 register - * - 10: CR2 register - * - 11: CR3 register - * - ZZZZZ : Flag position in the ISR register(5bits) - * Elements values convention: 000000000XXYYYYYb - * - YYYYY : Interrupt source position in the XX register (5bits) - * - XX : Interrupt source register (2bits) - * - 01: CR1 register - * - 10: CR2 register - * - 11: CR3 register - * Elements values convention: 0000ZZZZ00000000b - * - ZZZZ : Flag position in the ISR register(4bits) - * @{ - */ -#define UART_IT_PE 0x0028U /*!< UART parity error interruption */ -#define UART_IT_TXE 0x0727U /*!< UART transmit data register empty interruption */ -#if defined(USART_CR1_FIFOEN) -#define UART_IT_TXFNF 0x0727U /*!< UART TX FIFO not full interruption */ -#endif /* USART_CR1_FIFOEN */ -#define UART_IT_TC 0x0626U /*!< UART transmission complete interruption */ -#define UART_IT_RXNE 0x0525U /*!< UART read data register not empty interruption */ -#if defined(USART_CR1_FIFOEN) -#define UART_IT_RXFNE 0x0525U /*!< UART RXFIFO not empty interruption */ -#endif /* USART_CR1_FIFOEN */ -#define UART_IT_IDLE 0x0424U /*!< UART idle interruption */ -#define UART_IT_LBD 0x0846U /*!< UART LIN break detection interruption */ -#define UART_IT_CTS 0x096AU /*!< UART CTS interruption */ -#define UART_IT_CM 0x112EU /*!< UART character match interruption */ -#define UART_IT_WUF 0x1476U /*!< UART wake-up from stop mode interruption */ -#if defined(USART_CR1_FIFOEN) -#define UART_IT_RXFF 0x183FU /*!< UART RXFIFO full interruption */ -#define UART_IT_TXFE 0x173EU /*!< UART TXFIFO empty interruption */ -#define UART_IT_RXFT 0x1A7CU /*!< UART RXFIFO threshold reached interruption */ -#define UART_IT_TXFT 0x1B77U /*!< UART TXFIFO threshold reached interruption */ -#endif /* USART_CR1_FIFOEN */ -#define UART_IT_RTO 0x0B3AU /*!< UART receiver timeout interruption */ - -#define UART_IT_ERR 0x0060U /*!< UART error interruption */ - -#define UART_IT_ORE 0x0300U /*!< UART overrun error interruption */ -#define UART_IT_NE 0x0200U /*!< UART noise error interruption */ -#define UART_IT_FE 0x0100U /*!< UART frame error interruption */ -/** - * @} - */ - -/** @defgroup UART_IT_CLEAR_Flags UART Interruption Clear Flags - * @{ - */ -#define UART_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ -#define UART_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ -#define UART_CLEAR_NEF USART_ICR_NECF /*!< Noise Error detected Clear Flag */ -#define UART_CLEAR_OREF USART_ICR_ORECF /*!< Overrun Error Clear Flag */ -#define UART_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ -#if defined(USART_CR1_FIFOEN) -#define UART_CLEAR_TXFECF USART_ICR_TXFECF /*!< TXFIFO empty clear flag */ -#endif /* USART_CR1_FIFOEN */ -#define UART_CLEAR_TCF USART_ICR_TCCF /*!< Transmission Complete Clear Flag */ -#define UART_CLEAR_LBDF USART_ICR_LBDCF /*!< LIN Break Detection Clear Flag */ -#define UART_CLEAR_CTSF USART_ICR_CTSCF /*!< CTS Interrupt Clear Flag */ -#define UART_CLEAR_CMF USART_ICR_CMCF /*!< Character Match Clear Flag */ -#define UART_CLEAR_WUF USART_ICR_WUCF /*!< Wake Up from stop mode Clear Flag */ -#define UART_CLEAR_RTOF USART_ICR_RTOCF /*!< UART receiver timeout clear flag */ -/** - * @} - */ - -/** @defgroup UART_RECEPTION_TYPE_Values UART Reception type values - * @{ - */ -#define HAL_UART_RECEPTION_STANDARD (0x00000000U) /*!< Standard reception */ -#define HAL_UART_RECEPTION_TOIDLE (0x00000001U) /*!< Reception till completion or IDLE event */ -#define HAL_UART_RECEPTION_TORTO (0x00000002U) /*!< Reception till completion or RTO event */ -#define HAL_UART_RECEPTION_TOCHARMATCH (0x00000003U) /*!< Reception till completion or CM event */ -/** - * @} - */ - -/** - * @} - */ - -/* Exported macros -----------------------------------------------------------*/ -/** @defgroup UART_Exported_Macros UART Exported Macros - * @{ - */ - -/** @brief Reset UART handle states. - * @param __HANDLE__ UART handle. - * @retval None - */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) -#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \ - (__HANDLE__)->gState = HAL_UART_STATE_RESET; \ - (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \ - (__HANDLE__)->MspInitCallback = NULL; \ - (__HANDLE__)->MspDeInitCallback = NULL; \ - } while(0U) -#else -#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \ - (__HANDLE__)->gState = HAL_UART_STATE_RESET; \ - (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \ - } while(0U) -#endif /*USE_HAL_UART_REGISTER_CALLBACKS */ - -/** @brief Flush the UART Data registers. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) \ - do{ \ - SET_BIT((__HANDLE__)->Instance->RQR, UART_RXDATA_FLUSH_REQUEST); \ - SET_BIT((__HANDLE__)->Instance->RQR, UART_TXDATA_FLUSH_REQUEST); \ - } while(0U) - -/** @brief Clear the specified UART pending flag. - * @param __HANDLE__ specifies the UART Handle. - * @param __FLAG__ specifies the flag to check. - * This parameter can be any combination of the following values: - * @arg @ref UART_CLEAR_PEF Parity Error Clear Flag - * @arg @ref UART_CLEAR_FEF Framing Error Clear Flag - * @arg @ref UART_CLEAR_NEF Noise detected Clear Flag - * @arg @ref UART_CLEAR_OREF Overrun Error Clear Flag - * @arg @ref UART_CLEAR_IDLEF IDLE line detected Clear Flag - * @arg @ref UART_CLEAR_TXFECF TXFIFO empty clear Flag - * @arg @ref UART_CLEAR_TCF Transmission Complete Clear Flag - * @arg @ref UART_CLEAR_RTOF Receiver Timeout clear flag - * @arg @ref UART_CLEAR_LBDF LIN Break Detection Clear Flag - * @arg @ref UART_CLEAR_CTSF CTS Interrupt Clear Flag - * @arg @ref UART_CLEAR_CMF Character Match Clear Flag - * @arg @ref UART_CLEAR_WUF Wake Up from stop mode Clear Flag - * @retval None - */ -#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) - -/** @brief Clear the UART PE pending flag. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_PEF) - -/** @brief Clear the UART FE pending flag. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_FEF) - -/** @brief Clear the UART NE pending flag. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_NEF) - -/** @brief Clear the UART ORE pending flag. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_OREF) - -/** @brief Clear the UART IDLE pending flag. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_IDLEF) - -#if defined(USART_CR1_FIFOEN) -/** @brief Clear the UART TX FIFO empty clear flag. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_CLEAR_TXFECF(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_TXFECF) -#endif /* USART_CR1_FIFOEN */ - -/** @brief Check whether the specified UART flag is set or not. - * @param __HANDLE__ specifies the UART Handle. - * @param __FLAG__ specifies the flag to check. - * This parameter can be one of the following values: - * @arg @ref UART_FLAG_TXFT TXFIFO threshold flag - * @arg @ref UART_FLAG_RXFT RXFIFO threshold flag - * @arg @ref UART_FLAG_RXFF RXFIFO Full flag - * @arg @ref UART_FLAG_TXFE TXFIFO Empty flag - * @arg @ref UART_FLAG_REACK Receive enable acknowledge flag - * @arg @ref UART_FLAG_TEACK Transmit enable acknowledge flag - * @arg @ref UART_FLAG_WUF Wake up from stop mode flag - * @arg @ref UART_FLAG_RWU Receiver wake up flag (if the UART in mute mode) - * @arg @ref UART_FLAG_SBKF Send Break flag - * @arg @ref UART_FLAG_CMF Character match flag - * @arg @ref UART_FLAG_BUSY Busy flag - * @arg @ref UART_FLAG_ABRF Auto Baud rate detection flag - * @arg @ref UART_FLAG_ABRE Auto Baud rate detection error flag - * @arg @ref UART_FLAG_CTS CTS Change flag - * @arg @ref UART_FLAG_LBDF LIN Break detection flag - * @arg @ref UART_FLAG_TXE Transmit data register empty flag - * @arg @ref UART_FLAG_TXFNF UART TXFIFO not full flag - * @arg @ref UART_FLAG_TC Transmission Complete flag - * @arg @ref UART_FLAG_RXNE Receive data register not empty flag - * @arg @ref UART_FLAG_RXFNE UART RXFIFO not empty flag - * @arg @ref UART_FLAG_RTOF Receiver Timeout flag - * @arg @ref UART_FLAG_IDLE Idle Line detection flag - * @arg @ref UART_FLAG_ORE Overrun Error flag - * @arg @ref UART_FLAG_NE Noise Error flag - * @arg @ref UART_FLAG_FE Framing Error flag - * @arg @ref UART_FLAG_PE Parity Error flag - * @retval The new state of __FLAG__ (TRUE or FALSE). - */ -#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) - -/** @brief Enable the specified UART interrupt. - * @param __HANDLE__ specifies the UART Handle. - * @param __INTERRUPT__ specifies the UART interrupt source to enable. - * This parameter can be one of the following values: - * @arg @ref UART_IT_RXFF RXFIFO Full interrupt - * @arg @ref UART_IT_TXFE TXFIFO Empty interrupt - * @arg @ref UART_IT_RXFT RXFIFO threshold interrupt - * @arg @ref UART_IT_TXFT TXFIFO threshold interrupt - * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt - * @arg @ref UART_IT_CM Character match interrupt - * @arg @ref UART_IT_CTS CTS change interrupt - * @arg @ref UART_IT_LBD LIN Break detection interrupt - * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt - * @arg @ref UART_IT_TXFNF TX FIFO not full interrupt - * @arg @ref UART_IT_TC Transmission complete interrupt - * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt - * @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt - * @arg @ref UART_IT_RTO Receive Timeout interrupt - * @arg @ref UART_IT_IDLE Idle line detection interrupt - * @arg @ref UART_IT_PE Parity Error interrupt - * @arg @ref UART_IT_ERR Error interrupt (frame error, noise error, overrun error) - * @retval None - */ -#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) (\ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)?\ - ((__HANDLE__)->Instance->CR1 |= (1U <<\ - ((__INTERRUPT__) & UART_IT_MASK))): \ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)?\ - ((__HANDLE__)->Instance->CR2 |= (1U <<\ - ((__INTERRUPT__) & UART_IT_MASK))): \ - ((__HANDLE__)->Instance->CR3 |= (1U <<\ - ((__INTERRUPT__) & UART_IT_MASK)))) - -/** @brief Disable the specified UART interrupt. - * @param __HANDLE__ specifies the UART Handle. - * @param __INTERRUPT__ specifies the UART interrupt source to disable. - * This parameter can be one of the following values: - * @arg @ref UART_IT_RXFF RXFIFO Full interrupt - * @arg @ref UART_IT_TXFE TXFIFO Empty interrupt - * @arg @ref UART_IT_RXFT RXFIFO threshold interrupt - * @arg @ref UART_IT_TXFT TXFIFO threshold interrupt - * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt - * @arg @ref UART_IT_CM Character match interrupt - * @arg @ref UART_IT_CTS CTS change interrupt - * @arg @ref UART_IT_LBD LIN Break detection interrupt - * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt - * @arg @ref UART_IT_TXFNF TX FIFO not full interrupt - * @arg @ref UART_IT_TC Transmission complete interrupt - * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt - * @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt - * @arg @ref UART_IT_RTO Receive Timeout interrupt - * @arg @ref UART_IT_IDLE Idle line detection interrupt - * @arg @ref UART_IT_PE Parity Error interrupt - * @arg @ref UART_IT_ERR Error interrupt (Frame error, noise error, overrun error) - * @retval None - */ -#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) (\ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)?\ - ((__HANDLE__)->Instance->CR1 &= ~ (1U <<\ - ((__INTERRUPT__) & UART_IT_MASK))): \ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)?\ - ((__HANDLE__)->Instance->CR2 &= ~ (1U <<\ - ((__INTERRUPT__) & UART_IT_MASK))): \ - ((__HANDLE__)->Instance->CR3 &= ~ (1U <<\ - ((__INTERRUPT__) & UART_IT_MASK)))) - -/** @brief Check whether the specified UART interrupt has occurred or not. - * @param __HANDLE__ specifies the UART Handle. - * @param __INTERRUPT__ specifies the UART interrupt to check. - * This parameter can be one of the following values: - * @arg @ref UART_IT_RXFF RXFIFO Full interrupt - * @arg @ref UART_IT_TXFE TXFIFO Empty interrupt - * @arg @ref UART_IT_RXFT RXFIFO threshold interrupt - * @arg @ref UART_IT_TXFT TXFIFO threshold interrupt - * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt - * @arg @ref UART_IT_CM Character match interrupt - * @arg @ref UART_IT_CTS CTS change interrupt - * @arg @ref UART_IT_LBD LIN Break detection interrupt - * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt - * @arg @ref UART_IT_TXFNF TX FIFO not full interrupt - * @arg @ref UART_IT_TC Transmission complete interrupt - * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt - * @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt - * @arg @ref UART_IT_RTO Receive Timeout interrupt - * @arg @ref UART_IT_IDLE Idle line detection interrupt - * @arg @ref UART_IT_PE Parity Error interrupt - * @arg @ref UART_IT_ERR Error interrupt (Frame error, noise error, overrun error) - * @retval The new state of __INTERRUPT__ (SET or RESET). - */ -#define __HAL_UART_GET_IT(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->ISR\ - & (1U << ((__INTERRUPT__)>> 8U))) != RESET) ? SET : RESET) - -/** @brief Check whether the specified UART interrupt source is enabled or not. - * @param __HANDLE__ specifies the UART Handle. - * @param __INTERRUPT__ specifies the UART interrupt source to check. - * This parameter can be one of the following values: - * @arg @ref UART_IT_RXFF RXFIFO Full interrupt - * @arg @ref UART_IT_TXFE TXFIFO Empty interrupt - * @arg @ref UART_IT_RXFT RXFIFO threshold interrupt - * @arg @ref UART_IT_TXFT TXFIFO threshold interrupt - * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt - * @arg @ref UART_IT_CM Character match interrupt - * @arg @ref UART_IT_CTS CTS change interrupt - * @arg @ref UART_IT_LBD LIN Break detection interrupt - * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt - * @arg @ref UART_IT_TXFNF TX FIFO not full interrupt - * @arg @ref UART_IT_TC Transmission complete interrupt - * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt - * @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt - * @arg @ref UART_IT_RTO Receive Timeout interrupt - * @arg @ref UART_IT_IDLE Idle line detection interrupt - * @arg @ref UART_IT_PE Parity Error interrupt - * @arg @ref UART_IT_ERR Error interrupt (Frame error, noise error, overrun error) - * @retval The new state of __INTERRUPT__ (SET or RESET). - */ -#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U) ?\ - (__HANDLE__)->Instance->CR1 : \ - (((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U) ?\ - (__HANDLE__)->Instance->CR2 : \ - (__HANDLE__)->Instance->CR3)) & (1U <<\ - (((uint16_t)(__INTERRUPT__)) &\ - UART_IT_MASK))) != RESET) ? SET : RESET) - -/** @brief Clear the specified UART ISR flag, in setting the proper ICR register flag. - * @param __HANDLE__ specifies the UART Handle. - * @param __IT_CLEAR__ specifies the interrupt clear register flag that needs to be set - * to clear the corresponding interrupt - * This parameter can be one of the following values: - * @arg @ref UART_CLEAR_PEF Parity Error Clear Flag - * @arg @ref UART_CLEAR_FEF Framing Error Clear Flag - * @arg @ref UART_CLEAR_NEF Noise detected Clear Flag - * @arg @ref UART_CLEAR_OREF Overrun Error Clear Flag - * @arg @ref UART_CLEAR_IDLEF IDLE line detected Clear Flag - * @arg @ref UART_CLEAR_RTOF Receiver timeout clear flag - * @arg @ref UART_CLEAR_TXFECF TXFIFO empty Clear Flag - * @arg @ref UART_CLEAR_TCF Transmission Complete Clear Flag - * @arg @ref UART_CLEAR_LBDF LIN Break Detection Clear Flag - * @arg @ref UART_CLEAR_CTSF CTS Interrupt Clear Flag - * @arg @ref UART_CLEAR_CMF Character Match Clear Flag - * @arg @ref UART_CLEAR_WUF Wake Up from stop mode Clear Flag - * @retval None - */ -#define __HAL_UART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) - -/** @brief Set a specific UART request flag. - * @param __HANDLE__ specifies the UART Handle. - * @param __REQ__ specifies the request flag to set - * This parameter can be one of the following values: - * @arg @ref UART_AUTOBAUD_REQUEST Auto-Baud Rate Request - * @arg @ref UART_SENDBREAK_REQUEST Send Break Request - * @arg @ref UART_MUTE_MODE_REQUEST Mute Mode Request - * @arg @ref UART_RXDATA_FLUSH_REQUEST Receive Data flush Request - * @arg @ref UART_TXDATA_FLUSH_REQUEST Transmit data flush Request - * @retval None - */ -#define __HAL_UART_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint16_t)(__REQ__)) - -/** @brief Enable the UART one bit sample method. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) - -/** @brief Disable the UART one bit sample method. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= ~USART_CR3_ONEBIT) - -/** @brief Enable UART. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) - -/** @brief Disable UART. - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) - -/** @brief Enable CTS flow control. - * @note This macro allows to enable CTS hardware flow control for a given UART instance, - * without need to call HAL_UART_Init() function. - * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. - * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need - * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : - * - UART instance should have already been initialised (through call of HAL_UART_Init() ) - * - macro could only be called when corresponding UART instance is disabled - * (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable - * macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__) \ - do{ \ - ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \ - (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE; \ - } while(0U) - -/** @brief Disable CTS flow control. - * @note This macro allows to disable CTS hardware flow control for a given UART instance, - * without need to call HAL_UART_Init() function. - * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. - * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need - * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : - * - UART instance should have already been initialised (through call of HAL_UART_Init() ) - * - macro could only be called when corresponding UART instance is disabled - * (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable - * macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__) \ - do{ \ - ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \ - (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE); \ - } while(0U) - -/** @brief Enable RTS flow control. - * @note This macro allows to enable RTS hardware flow control for a given UART instance, - * without need to call HAL_UART_Init() function. - * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. - * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need - * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : - * - UART instance should have already been initialised (through call of HAL_UART_Init() ) - * - macro could only be called when corresponding UART instance is disabled - * (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable - * macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__) \ - do{ \ - ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE); \ - (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE; \ - } while(0U) - -/** @brief Disable RTS flow control. - * @note This macro allows to disable RTS hardware flow control for a given UART instance, - * without need to call HAL_UART_Init() function. - * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. - * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need - * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : - * - UART instance should have already been initialised (through call of HAL_UART_Init() ) - * - macro could only be called when corresponding UART instance is disabled - * (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable - * macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). - * @param __HANDLE__ specifies the UART Handle. - * @retval None - */ -#define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__) \ - do{ \ - ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE);\ - (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_RTSE); \ - } while(0U) -/** - * @} - */ - -/* Private macros --------------------------------------------------------*/ -/** @defgroup UART_Private_Macros UART Private Macros - * @{ - */ -#if defined(USART_PRESC_PRESCALER) -/** @brief Get UART clok division factor from clock prescaler value. - * @param __CLOCKPRESCALER__ UART prescaler value. - * @retval UART clock division factor - */ -#define UART_GET_DIV_FACTOR(__CLOCKPRESCALER__) \ - (((__CLOCKPRESCALER__) == UART_PRESCALER_DIV1) ? 1U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV2) ? 2U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV4) ? 4U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV6) ? 6U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV8) ? 8U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV10) ? 10U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV12) ? 12U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV16) ? 16U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV32) ? 32U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV64) ? 64U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV128) ? 128U : \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV256) ? 256U : 1U) - -/** @brief BRR division operation to set BRR register with LPUART. - * @param __PCLK__ LPUART clock. - * @param __BAUD__ Baud rate set by the user. - * @param __CLOCKPRESCALER__ UART prescaler value. - * @retval Division result - */ -#define UART_DIV_LPUART(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ - ((uint32_t)((((((uint64_t)(__PCLK__))/(UARTPrescTable[(__CLOCKPRESCALER__)]))*256U)+ \ - (uint32_t)((__BAUD__)/2U)) / (__BAUD__)) \ - ) - -/** @brief BRR division operation to set BRR register in 8-bit oversampling mode. - * @param __PCLK__ UART clock. - * @param __BAUD__ Baud rate set by the user. - * @param __CLOCKPRESCALER__ UART prescaler value. - * @retval Division result - */ -#define UART_DIV_SAMPLING8(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ - (((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)])*2U) + ((__BAUD__)/2U)) / (__BAUD__)) - -/** @brief BRR division operation to set BRR register in 16-bit oversampling mode. - * @param __PCLK__ UART clock. - * @param __BAUD__ Baud rate set by the user. - * @param __CLOCKPRESCALER__ UART prescaler value. - * @retval Division result - */ -#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ - ((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)]) + ((__BAUD__)/2U)) / (__BAUD__)) -#else - -/** @brief BRR division operation to set BRR register with LPUART. - * @param __PCLK__ LPUART clock. - * @param __BAUD__ Baud rate set by the user. - * @retval Division result - */ -#define UART_DIV_LPUART(__PCLK__, __BAUD__) (((((uint64_t)(__PCLK__)*256U)) + ((__BAUD__)/2U)) / (__BAUD__)) - -/** @brief BRR division operation to set BRR register in 8-bit oversampling mode. - * @param __PCLK__ UART clock. - * @param __BAUD__ Baud rate set by the user. - * @retval Division result - */ -#define UART_DIV_SAMPLING8(__PCLK__, __BAUD__) ((((__PCLK__)*2U) + ((__BAUD__)/2U)) / (__BAUD__)) - -/** @brief BRR division operation to set BRR register in 16-bit oversampling mode. - * @param __PCLK__ UART clock. - * @param __BAUD__ Baud rate set by the user. - * @retval Division result - */ -#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__) (((__PCLK__) + ((__BAUD__)/2U)) / (__BAUD__)) -#endif /* USART_PRESC_PRESCALER */ - -/** @brief Check whether or not UART instance is Low Power UART. - * @param __HANDLE__ specifies the UART Handle. - * @retval SET (instance is LPUART) or RESET (instance isn't LPUART) - */ -#define UART_INSTANCE_LOWPOWER(__HANDLE__) (IS_LPUART_INSTANCE((__HANDLE__)->Instance)) - -/** @brief Check UART Baud rate. - * @param __BAUDRATE__ Baudrate specified by the user. - * The maximum Baud Rate is derived from the maximum clock on L4 - * divided by the smallest oversampling used on the USART (i.e. 8) - * (i.e. 120 MHz on STM32L4Rx/L4Sx, 80 Mhz otherwise) - * @retval SET (__BAUDRATE__ is valid) or RESET (__BAUDRATE__ is invalid) - */ -#if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) -#define IS_UART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 15000001U) -#else -#define IS_UART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 10000001U) -#endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ - -/** @brief Check UART assertion time. - * @param __TIME__ 5-bit value assertion time. - * @retval Test result (TRUE or FALSE). - */ -#define IS_UART_ASSERTIONTIME(__TIME__) ((__TIME__) <= 0x1FU) - -/** @brief Check UART deassertion time. - * @param __TIME__ 5-bit value deassertion time. - * @retval Test result (TRUE or FALSE). - */ -#define IS_UART_DEASSERTIONTIME(__TIME__) ((__TIME__) <= 0x1FU) - -/** - * @brief Ensure that UART frame number of stop bits is valid. - * @param __STOPBITS__ UART frame number of stop bits. - * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) - */ -#define IS_UART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == UART_STOPBITS_0_5) || \ - ((__STOPBITS__) == UART_STOPBITS_1) || \ - ((__STOPBITS__) == UART_STOPBITS_1_5) || \ - ((__STOPBITS__) == UART_STOPBITS_2)) - -/** - * @brief Ensure that LPUART frame number of stop bits is valid. - * @param __STOPBITS__ LPUART frame number of stop bits. - * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) - */ -#define IS_LPUART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == UART_STOPBITS_1) || \ - ((__STOPBITS__) == UART_STOPBITS_2)) - -/** - * @brief Ensure that UART frame parity is valid. - * @param __PARITY__ UART frame parity. - * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) - */ -#define IS_UART_PARITY(__PARITY__) (((__PARITY__) == UART_PARITY_NONE) || \ - ((__PARITY__) == UART_PARITY_EVEN) || \ - ((__PARITY__) == UART_PARITY_ODD)) - -/** - * @brief Ensure that UART hardware flow control is valid. - * @param __CONTROL__ UART hardware flow control. - * @retval SET (__CONTROL__ is valid) or RESET (__CONTROL__ is invalid) - */ -#define IS_UART_HARDWARE_FLOW_CONTROL(__CONTROL__)\ - (((__CONTROL__) == UART_HWCONTROL_NONE) || \ - ((__CONTROL__) == UART_HWCONTROL_RTS) || \ - ((__CONTROL__) == UART_HWCONTROL_CTS) || \ - ((__CONTROL__) == UART_HWCONTROL_RTS_CTS)) - -/** - * @brief Ensure that UART communication mode is valid. - * @param __MODE__ UART communication mode. - * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) - */ -#define IS_UART_MODE(__MODE__) ((((__MODE__) & (~((uint32_t)(UART_MODE_TX_RX)))) == 0x00U) && ((__MODE__) != 0x00U)) - -/** - * @brief Ensure that UART state is valid. - * @param __STATE__ UART state. - * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) - */ -#define IS_UART_STATE(__STATE__) (((__STATE__) == UART_STATE_DISABLE) || \ - ((__STATE__) == UART_STATE_ENABLE)) - -/** - * @brief Ensure that UART oversampling is valid. - * @param __SAMPLING__ UART oversampling. - * @retval SET (__SAMPLING__ is valid) or RESET (__SAMPLING__ is invalid) - */ -#define IS_UART_OVERSAMPLING(__SAMPLING__) (((__SAMPLING__) == UART_OVERSAMPLING_16) || \ - ((__SAMPLING__) == UART_OVERSAMPLING_8)) - -/** - * @brief Ensure that UART frame sampling is valid. - * @param __ONEBIT__ UART frame sampling. - * @retval SET (__ONEBIT__ is valid) or RESET (__ONEBIT__ is invalid) - */ -#define IS_UART_ONE_BIT_SAMPLE(__ONEBIT__) (((__ONEBIT__) == UART_ONE_BIT_SAMPLE_DISABLE) || \ - ((__ONEBIT__) == UART_ONE_BIT_SAMPLE_ENABLE)) - -/** - * @brief Ensure that UART auto Baud rate detection mode is valid. - * @param __MODE__ UART auto Baud rate detection mode. - * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) - */ -#define IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(__MODE__) (((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT) || \ - ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE) || \ - ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME) || \ - ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME)) - -/** - * @brief Ensure that UART receiver timeout setting is valid. - * @param __TIMEOUT__ UART receiver timeout setting. - * @retval SET (__TIMEOUT__ is valid) or RESET (__TIMEOUT__ is invalid) - */ -#define IS_UART_RECEIVER_TIMEOUT(__TIMEOUT__) (((__TIMEOUT__) == UART_RECEIVER_TIMEOUT_DISABLE) || \ - ((__TIMEOUT__) == UART_RECEIVER_TIMEOUT_ENABLE)) - -/** @brief Check the receiver timeout value. - * @note The maximum UART receiver timeout value is 0xFFFFFF. - * @param __TIMEOUTVALUE__ receiver timeout value. - * @retval Test result (TRUE or FALSE) - */ -#define IS_UART_RECEIVER_TIMEOUT_VALUE(__TIMEOUTVALUE__) ((__TIMEOUTVALUE__) <= 0xFFFFFFU) - -/** - * @brief Ensure that UART LIN state is valid. - * @param __LIN__ UART LIN state. - * @retval SET (__LIN__ is valid) or RESET (__LIN__ is invalid) - */ -#define IS_UART_LIN(__LIN__) (((__LIN__) == UART_LIN_DISABLE) || \ - ((__LIN__) == UART_LIN_ENABLE)) - -/** - * @brief Ensure that UART LIN break detection length is valid. - * @param __LENGTH__ UART LIN break detection length. - * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) - */ -#define IS_UART_LIN_BREAK_DETECT_LENGTH(__LENGTH__) (((__LENGTH__) == UART_LINBREAKDETECTLENGTH_10B) || \ - ((__LENGTH__) == UART_LINBREAKDETECTLENGTH_11B)) - -/** - * @brief Ensure that UART DMA TX state is valid. - * @param __DMATX__ UART DMA TX state. - * @retval SET (__DMATX__ is valid) or RESET (__DMATX__ is invalid) - */ -#define IS_UART_DMA_TX(__DMATX__) (((__DMATX__) == UART_DMA_TX_DISABLE) || \ - ((__DMATX__) == UART_DMA_TX_ENABLE)) - -/** - * @brief Ensure that UART DMA RX state is valid. - * @param __DMARX__ UART DMA RX state. - * @retval SET (__DMARX__ is valid) or RESET (__DMARX__ is invalid) - */ -#define IS_UART_DMA_RX(__DMARX__) (((__DMARX__) == UART_DMA_RX_DISABLE) || \ - ((__DMARX__) == UART_DMA_RX_ENABLE)) - -/** - * @brief Ensure that UART half-duplex state is valid. - * @param __HDSEL__ UART half-duplex state. - * @retval SET (__HDSEL__ is valid) or RESET (__HDSEL__ is invalid) - */ -#define IS_UART_HALF_DUPLEX(__HDSEL__) (((__HDSEL__) == UART_HALF_DUPLEX_DISABLE) || \ - ((__HDSEL__) == UART_HALF_DUPLEX_ENABLE)) - -/** - * @brief Ensure that UART wake-up method is valid. - * @param __WAKEUP__ UART wake-up method . - * @retval SET (__WAKEUP__ is valid) or RESET (__WAKEUP__ is invalid) - */ -#define IS_UART_WAKEUPMETHOD(__WAKEUP__) (((__WAKEUP__) == UART_WAKEUPMETHOD_IDLELINE) || \ - ((__WAKEUP__) == UART_WAKEUPMETHOD_ADDRESSMARK)) - -/** - * @brief Ensure that UART request parameter is valid. - * @param __PARAM__ UART request parameter. - * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid) - */ -#define IS_UART_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == UART_AUTOBAUD_REQUEST) || \ - ((__PARAM__) == UART_SENDBREAK_REQUEST) || \ - ((__PARAM__) == UART_MUTE_MODE_REQUEST) || \ - ((__PARAM__) == UART_RXDATA_FLUSH_REQUEST) || \ - ((__PARAM__) == UART_TXDATA_FLUSH_REQUEST)) - -/** - * @brief Ensure that UART advanced features initialization is valid. - * @param __INIT__ UART advanced features initialization. - * @retval SET (__INIT__ is valid) or RESET (__INIT__ is invalid) - */ -#define IS_UART_ADVFEATURE_INIT(__INIT__) ((__INIT__) <= (UART_ADVFEATURE_NO_INIT | \ - UART_ADVFEATURE_TXINVERT_INIT | \ - UART_ADVFEATURE_RXINVERT_INIT | \ - UART_ADVFEATURE_DATAINVERT_INIT | \ - UART_ADVFEATURE_SWAP_INIT | \ - UART_ADVFEATURE_RXOVERRUNDISABLE_INIT | \ - UART_ADVFEATURE_DMADISABLEONERROR_INIT | \ - UART_ADVFEATURE_AUTOBAUDRATE_INIT | \ - UART_ADVFEATURE_MSBFIRST_INIT)) - -/** - * @brief Ensure that UART frame TX inversion setting is valid. - * @param __TXINV__ UART frame TX inversion setting. - * @retval SET (__TXINV__ is valid) or RESET (__TXINV__ is invalid) - */ -#define IS_UART_ADVFEATURE_TXINV(__TXINV__) (((__TXINV__) == UART_ADVFEATURE_TXINV_DISABLE) || \ - ((__TXINV__) == UART_ADVFEATURE_TXINV_ENABLE)) - -/** - * @brief Ensure that UART frame RX inversion setting is valid. - * @param __RXINV__ UART frame RX inversion setting. - * @retval SET (__RXINV__ is valid) or RESET (__RXINV__ is invalid) - */ -#define IS_UART_ADVFEATURE_RXINV(__RXINV__) (((__RXINV__) == UART_ADVFEATURE_RXINV_DISABLE) || \ - ((__RXINV__) == UART_ADVFEATURE_RXINV_ENABLE)) - -/** - * @brief Ensure that UART frame data inversion setting is valid. - * @param __DATAINV__ UART frame data inversion setting. - * @retval SET (__DATAINV__ is valid) or RESET (__DATAINV__ is invalid) - */ -#define IS_UART_ADVFEATURE_DATAINV(__DATAINV__) (((__DATAINV__) == UART_ADVFEATURE_DATAINV_DISABLE) || \ - ((__DATAINV__) == UART_ADVFEATURE_DATAINV_ENABLE)) - -/** - * @brief Ensure that UART frame RX/TX pins swap setting is valid. - * @param __SWAP__ UART frame RX/TX pins swap setting. - * @retval SET (__SWAP__ is valid) or RESET (__SWAP__ is invalid) - */ -#define IS_UART_ADVFEATURE_SWAP(__SWAP__) (((__SWAP__) == UART_ADVFEATURE_SWAP_DISABLE) || \ - ((__SWAP__) == UART_ADVFEATURE_SWAP_ENABLE)) - -/** - * @brief Ensure that UART frame overrun setting is valid. - * @param __OVERRUN__ UART frame overrun setting. - * @retval SET (__OVERRUN__ is valid) or RESET (__OVERRUN__ is invalid) - */ -#define IS_UART_OVERRUN(__OVERRUN__) (((__OVERRUN__) == UART_ADVFEATURE_OVERRUN_ENABLE) || \ - ((__OVERRUN__) == UART_ADVFEATURE_OVERRUN_DISABLE)) - -/** - * @brief Ensure that UART auto Baud rate state is valid. - * @param __AUTOBAUDRATE__ UART auto Baud rate state. - * @retval SET (__AUTOBAUDRATE__ is valid) or RESET (__AUTOBAUDRATE__ is invalid) - */ -#define IS_UART_ADVFEATURE_AUTOBAUDRATE(__AUTOBAUDRATE__) (((__AUTOBAUDRATE__) == \ - UART_ADVFEATURE_AUTOBAUDRATE_DISABLE) || \ - ((__AUTOBAUDRATE__) == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)) - -/** - * @brief Ensure that UART DMA enabling or disabling on error setting is valid. - * @param __DMA__ UART DMA enabling or disabling on error setting. - * @retval SET (__DMA__ is valid) or RESET (__DMA__ is invalid) - */ -#define IS_UART_ADVFEATURE_DMAONRXERROR(__DMA__) (((__DMA__) == UART_ADVFEATURE_DMA_ENABLEONRXERROR) || \ - ((__DMA__) == UART_ADVFEATURE_DMA_DISABLEONRXERROR)) - -/** - * @brief Ensure that UART frame MSB first setting is valid. - * @param __MSBFIRST__ UART frame MSB first setting. - * @retval SET (__MSBFIRST__ is valid) or RESET (__MSBFIRST__ is invalid) - */ -#define IS_UART_ADVFEATURE_MSBFIRST(__MSBFIRST__) (((__MSBFIRST__) == UART_ADVFEATURE_MSBFIRST_DISABLE) || \ - ((__MSBFIRST__) == UART_ADVFEATURE_MSBFIRST_ENABLE)) - -/** - * @brief Ensure that UART stop mode state is valid. - * @param __STOPMODE__ UART stop mode state. - * @retval SET (__STOPMODE__ is valid) or RESET (__STOPMODE__ is invalid) - */ -#define IS_UART_ADVFEATURE_STOPMODE(__STOPMODE__) (((__STOPMODE__) == UART_ADVFEATURE_STOPMODE_DISABLE) || \ - ((__STOPMODE__) == UART_ADVFEATURE_STOPMODE_ENABLE)) - -/** - * @brief Ensure that UART mute mode state is valid. - * @param __MUTE__ UART mute mode state. - * @retval SET (__MUTE__ is valid) or RESET (__MUTE__ is invalid) - */ -#define IS_UART_MUTE_MODE(__MUTE__) (((__MUTE__) == UART_ADVFEATURE_MUTEMODE_DISABLE) || \ - ((__MUTE__) == UART_ADVFEATURE_MUTEMODE_ENABLE)) - -/** - * @brief Ensure that UART wake-up selection is valid. - * @param __WAKE__ UART wake-up selection. - * @retval SET (__WAKE__ is valid) or RESET (__WAKE__ is invalid) - */ -#define IS_UART_WAKEUP_SELECTION(__WAKE__) (((__WAKE__) == UART_WAKEUP_ON_ADDRESS) || \ - ((__WAKE__) == UART_WAKEUP_ON_STARTBIT) || \ - ((__WAKE__) == UART_WAKEUP_ON_READDATA_NONEMPTY)) - -/** - * @brief Ensure that UART driver enable polarity is valid. - * @param __POLARITY__ UART driver enable polarity. - * @retval SET (__POLARITY__ is valid) or RESET (__POLARITY__ is invalid) - */ -#define IS_UART_DE_POLARITY(__POLARITY__) (((__POLARITY__) == UART_DE_POLARITY_HIGH) || \ - ((__POLARITY__) == UART_DE_POLARITY_LOW)) - -#if defined(USART_PRESC_PRESCALER) -/** - * @brief Ensure that UART Prescaler is valid. - * @param __CLOCKPRESCALER__ UART Prescaler value. - * @retval SET (__CLOCKPRESCALER__ is valid) or RESET (__CLOCKPRESCALER__ is invalid) - */ -#define IS_UART_PRESCALER(__CLOCKPRESCALER__) (((__CLOCKPRESCALER__) == UART_PRESCALER_DIV1) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV2) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV4) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV6) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV8) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV10) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV12) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV16) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV32) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV64) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV128) || \ - ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV256)) -#endif /* USART_PRESC_PRESCALER */ - -/** - * @} - */ - -/* Include UART HAL Extended module */ -#include "stm32l4xx_hal_uart_ex.h" - -/* Exported functions --------------------------------------------------------*/ -/** @addtogroup UART_Exported_Functions UART Exported Functions - * @{ - */ - -/** @addtogroup UART_Exported_Functions_Group1 Initialization and de-initialization functions - * @{ - */ - -/* Initialization and de-initialization functions ****************************/ -HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength); -HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod); -HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart); -void HAL_UART_MspInit(UART_HandleTypeDef *huart); -void HAL_UART_MspDeInit(UART_HandleTypeDef *huart); - -/* Callbacks Register/UnRegister functions ***********************************/ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) -HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID, - pUART_CallbackTypeDef pCallback); -HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID); - -HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback); -HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - -/** - * @} - */ - -/** @addtogroup UART_Exported_Functions_Group2 IO operation functions - * @{ - */ - -/* IO operation functions *****************************************************/ -HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart); -/* Transfer Abort functions */ -HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart); - -void HAL_UART_IRQHandler(UART_HandleTypeDef *huart); -void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); -void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); -void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart); -void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); -void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart); -void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart); -void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart); -void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart); - -void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size); - -/** - * @} - */ - -/** @addtogroup UART_Exported_Functions_Group3 Peripheral Control functions - * @{ - */ - -/* Peripheral Control functions ************************************************/ -void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue); -HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart); - -HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart); -void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart); - -/** - * @} - */ - -/** @addtogroup UART_Exported_Functions_Group4 Peripheral State and Error functions - * @{ - */ - -/* Peripheral State and Errors functions **************************************************/ -HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart); -uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart); - -/** - * @} - */ - -/** - * @} - */ - -/* Private functions -----------------------------------------------------------*/ -/** @addtogroup UART_Private_Functions UART Private Functions - * @{ - */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) -void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ -HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart); -HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart); -HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, - uint32_t Tickstart, uint32_t Timeout); -void UART_AdvFeatureConfig(UART_HandleTypeDef *huart); -HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); - -/** - * @} - */ - -/* Private variables -----------------------------------------------------------*/ -#if defined(USART_PRESC_PRESCALER) -/** @defgroup UART_Private_variables UART Private variables - * @{ - */ -/* Prescaler Table used in BRR computation macros. - Declared as extern here to allow use of private UART macros, outside of HAL UART functions */ -extern const uint16_t UARTPrescTable[12]; -/** - * @} - */ - -#endif /* USART_PRESC_PRESCALER */ -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* STM32L4xx_HAL_UART_H */ - diff --git a/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h b/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h deleted file mode 100644 index 426b319..0000000 --- a/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h +++ /dev/null @@ -1,743 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l4xx_hal_uart_ex.h - * @author MCD Application Team - * @brief Header file of UART HAL Extended module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef STM32L4xx_HAL_UART_EX_H -#define STM32L4xx_HAL_UART_EX_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l4xx_hal_def.h" - -/** @addtogroup STM32L4xx_HAL_Driver - * @{ - */ - -/** @addtogroup UARTEx - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/** @defgroup UARTEx_Exported_Types UARTEx Exported Types - * @{ - */ - -/** - * @brief UART wake up from stop mode parameters - */ -typedef struct -{ - uint32_t WakeUpEvent; /*!< Specifies which event will activate the Wakeup from Stop mode flag (WUF). - This parameter can be a value of @ref UART_WakeUp_from_Stop_Selection. - If set to UART_WAKEUP_ON_ADDRESS, the two other fields below must - be filled up. */ - - uint16_t AddressLength; /*!< Specifies whether the address is 4 or 7-bit long. - This parameter can be a value of @ref UARTEx_WakeUp_Address_Length. */ - - uint8_t Address; /*!< UART/USART node address (7-bit long max). */ -} UART_WakeUpTypeDef; - -/** - * @} - */ - -/* Exported constants --------------------------------------------------------*/ -/** @defgroup UARTEx_Exported_Constants UARTEx Exported Constants - * @{ - */ - -/** @defgroup UARTEx_Word_Length UARTEx Word Length - * @{ - */ -#define UART_WORDLENGTH_7B USART_CR1_M1 /*!< 7-bit long UART frame */ -#define UART_WORDLENGTH_8B 0x00000000U /*!< 8-bit long UART frame */ -#define UART_WORDLENGTH_9B USART_CR1_M0 /*!< 9-bit long UART frame */ -/** - * @} - */ - -/** @defgroup UARTEx_WakeUp_Address_Length UARTEx WakeUp Address Length - * @{ - */ -#define UART_ADDRESS_DETECT_4B 0x00000000U /*!< 4-bit long wake-up address */ -#define UART_ADDRESS_DETECT_7B USART_CR2_ADDM7 /*!< 7-bit long wake-up address */ -/** - * @} - */ - -#if defined(USART_CR1_FIFOEN) -/** @defgroup UARTEx_FIFO_mode UARTEx FIFO mode - * @brief UART FIFO mode - * @{ - */ -#define UART_FIFOMODE_DISABLE 0x00000000U /*!< FIFO mode disable */ -#define UART_FIFOMODE_ENABLE USART_CR1_FIFOEN /*!< FIFO mode enable */ -/** - * @} - */ - -/** @defgroup UARTEx_TXFIFO_threshold_level UARTEx TXFIFO threshold level - * @brief UART TXFIFO threshold level - * @{ - */ -#define UART_TXFIFO_THRESHOLD_1_8 0x00000000U /*!< TX FIFO reaches 1/8 of its depth */ -#define UART_TXFIFO_THRESHOLD_1_4 USART_CR3_TXFTCFG_0 /*!< TX FIFO reaches 1/4 of its depth */ -#define UART_TXFIFO_THRESHOLD_1_2 USART_CR3_TXFTCFG_1 /*!< TX FIFO reaches 1/2 of its depth */ -#define UART_TXFIFO_THRESHOLD_3_4 (USART_CR3_TXFTCFG_0|USART_CR3_TXFTCFG_1) /*!< TX FIFO reaches 3/4 of its depth */ -#define UART_TXFIFO_THRESHOLD_7_8 USART_CR3_TXFTCFG_2 /*!< TX FIFO reaches 7/8 of its depth */ -#define UART_TXFIFO_THRESHOLD_8_8 (USART_CR3_TXFTCFG_2|USART_CR3_TXFTCFG_0) /*!< TX FIFO becomes empty */ -/** - * @} - */ - -/** @defgroup UARTEx_RXFIFO_threshold_level UARTEx RXFIFO threshold level - * @brief UART RXFIFO threshold level - * @{ - */ -#define UART_RXFIFO_THRESHOLD_1_8 0x00000000U /*!< RX FIFO reaches 1/8 of its depth */ -#define UART_RXFIFO_THRESHOLD_1_4 USART_CR3_RXFTCFG_0 /*!< RX FIFO reaches 1/4 of its depth */ -#define UART_RXFIFO_THRESHOLD_1_2 USART_CR3_RXFTCFG_1 /*!< RX FIFO reaches 1/2 of its depth */ -#define UART_RXFIFO_THRESHOLD_3_4 (USART_CR3_RXFTCFG_0|USART_CR3_RXFTCFG_1) /*!< RX FIFO reaches 3/4 of its depth */ -#define UART_RXFIFO_THRESHOLD_7_8 USART_CR3_RXFTCFG_2 /*!< RX FIFO reaches 7/8 of its depth */ -#define UART_RXFIFO_THRESHOLD_8_8 (USART_CR3_RXFTCFG_2|USART_CR3_RXFTCFG_0) /*!< RX FIFO becomes full */ -/** - * @} - */ - -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ - -/* Exported macros -----------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ -/** @addtogroup UARTEx_Exported_Functions - * @{ - */ - -/** @addtogroup UARTEx_Exported_Functions_Group1 - * @{ - */ - -/* Initialization and de-initialization functions ****************************/ -HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, - uint32_t DeassertionTime); - -/** - * @} - */ - -/** @addtogroup UARTEx_Exported_Functions_Group2 - * @{ - */ - -void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart); - -#if defined(USART_CR1_FIFOEN) -void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart); -void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart); - -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ - -/** @addtogroup UARTEx_Exported_Functions_Group3 - * @{ - */ - -/* Peripheral Control functions **********************************************/ -HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection); -HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart); - -#if defined(USART_CR3_UCESM) -HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart); - -#endif /* USART_CR3_UCESM */ -HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength); - -#if defined(USART_CR1_FIFOEN) -HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold); -HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold); -#endif /* USART_CR1_FIFOEN */ - -HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, - uint32_t Timeout); -HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); - - -/** - * @} - */ - -/** - * @} - */ - -/* Private macros ------------------------------------------------------------*/ -/** @defgroup UARTEx_Private_Macros UARTEx Private Macros - * @{ - */ - -/** @brief Report the UART clock source. - * @param __HANDLE__ specifies the UART Handle. - * @param __CLOCKSOURCE__ output variable. - * @retval UART clocking source, written in __CLOCKSOURCE__. - */ -#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) \ - || defined (STM32L496xx) || defined (STM32L4A6xx) \ - || defined (STM32L4P5xx) || defined (STM32L4Q5xx) \ - || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx) -#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ - do { \ - if((__HANDLE__)->Instance == USART1) \ - { \ - switch(__HAL_RCC_GET_USART1_SOURCE()) \ - { \ - case RCC_USART1CLKSOURCE_PCLK2: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2; \ - break; \ - case RCC_USART1CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART1CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART1CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == USART2) \ - { \ - switch(__HAL_RCC_GET_USART2_SOURCE()) \ - { \ - case RCC_USART2CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_USART2CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART2CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART2CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == USART3) \ - { \ - switch(__HAL_RCC_GET_USART3_SOURCE()) \ - { \ - case RCC_USART3CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_USART3CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART3CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART3CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == UART4) \ - { \ - switch(__HAL_RCC_GET_UART4_SOURCE()) \ - { \ - case RCC_UART4CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_UART4CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_UART4CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_UART4CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == UART5) \ - { \ - switch(__HAL_RCC_GET_UART5_SOURCE()) \ - { \ - case RCC_UART5CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_UART5CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_UART5CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_UART5CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == LPUART1) \ - { \ - switch(__HAL_RCC_GET_LPUART1_SOURCE()) \ - { \ - case RCC_LPUART1CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_LPUART1CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_LPUART1CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_LPUART1CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else \ - { \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - } \ - } while(0U) -#elif defined (STM32L412xx) || defined (STM32L422xx) \ - || defined (STM32L431xx) || defined (STM32L433xx) || defined (STM32L443xx) -#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ - do { \ - if((__HANDLE__)->Instance == USART1) \ - { \ - switch(__HAL_RCC_GET_USART1_SOURCE()) \ - { \ - case RCC_USART1CLKSOURCE_PCLK2: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2; \ - break; \ - case RCC_USART1CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART1CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART1CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == USART2) \ - { \ - switch(__HAL_RCC_GET_USART2_SOURCE()) \ - { \ - case RCC_USART2CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_USART2CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART2CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART2CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == USART3) \ - { \ - switch(__HAL_RCC_GET_USART3_SOURCE()) \ - { \ - case RCC_USART3CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_USART3CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART3CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART3CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == LPUART1) \ - { \ - switch(__HAL_RCC_GET_LPUART1_SOURCE()) \ - { \ - case RCC_LPUART1CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_LPUART1CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_LPUART1CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_LPUART1CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else \ - { \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - } \ - } while(0U) -#elif defined (STM32L432xx) || defined (STM32L442xx) -#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ - do { \ - if((__HANDLE__)->Instance == USART1) \ - { \ - switch(__HAL_RCC_GET_USART1_SOURCE()) \ - { \ - case RCC_USART1CLKSOURCE_PCLK2: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2; \ - break; \ - case RCC_USART1CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART1CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART1CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == USART2) \ - { \ - switch(__HAL_RCC_GET_USART2_SOURCE()) \ - { \ - case RCC_USART2CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_USART2CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART2CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART2CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == LPUART1) \ - { \ - switch(__HAL_RCC_GET_LPUART1_SOURCE()) \ - { \ - case RCC_LPUART1CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_LPUART1CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_LPUART1CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_LPUART1CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else \ - { \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - } \ - } while(0U) -#elif defined (STM32L451xx) || defined (STM32L452xx) || defined (STM32L462xx) -#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ - do { \ - if((__HANDLE__)->Instance == USART1) \ - { \ - switch(__HAL_RCC_GET_USART1_SOURCE()) \ - { \ - case RCC_USART1CLKSOURCE_PCLK2: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2; \ - break; \ - case RCC_USART1CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART1CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART1CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == USART2) \ - { \ - switch(__HAL_RCC_GET_USART2_SOURCE()) \ - { \ - case RCC_USART2CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_USART2CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART2CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART2CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == USART3) \ - { \ - switch(__HAL_RCC_GET_USART3_SOURCE()) \ - { \ - case RCC_USART3CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_USART3CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART3CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART3CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == UART4) \ - { \ - switch(__HAL_RCC_GET_UART4_SOURCE()) \ - { \ - case RCC_UART4CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_UART4CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_UART4CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_UART4CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == LPUART1) \ - { \ - switch(__HAL_RCC_GET_LPUART1_SOURCE()) \ - { \ - case RCC_LPUART1CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_LPUART1CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_LPUART1CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_LPUART1CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - break; \ - } \ - } \ - else \ - { \ - (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ - } \ - } while(0U) -#endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx || - * STM32L496xx || STM32L4A6xx || - * STM32L4P5xx || STM32L4Q5xx || - * STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx - */ - -/** @brief Report the UART mask to apply to retrieve the received data - * according to the word length and to the parity bits activation. - * @note If PCE = 1, the parity bit is not included in the data extracted - * by the reception API(). - * This masking operation is not carried out in the case of - * DMA transfers. - * @param __HANDLE__ specifies the UART Handle. - * @retval None, the mask to apply to UART RDR register is stored in (__HANDLE__)->Mask field. - */ -#define UART_MASK_COMPUTATION(__HANDLE__) \ - do { \ - if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_9B) \ - { \ - if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE) \ - { \ - (__HANDLE__)->Mask = 0x01FFU ; \ - } \ - else \ - { \ - (__HANDLE__)->Mask = 0x00FFU ; \ - } \ - } \ - else if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_8B) \ - { \ - if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE) \ - { \ - (__HANDLE__)->Mask = 0x00FFU ; \ - } \ - else \ - { \ - (__HANDLE__)->Mask = 0x007FU ; \ - } \ - } \ - else if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_7B) \ - { \ - if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE) \ - { \ - (__HANDLE__)->Mask = 0x007FU ; \ - } \ - else \ - { \ - (__HANDLE__)->Mask = 0x003FU ; \ - } \ - } \ - else \ - { \ - (__HANDLE__)->Mask = 0x0000U; \ - } \ - } while(0U) - -/** - * @brief Ensure that UART frame length is valid. - * @param __LENGTH__ UART frame length. - * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) - */ -#define IS_UART_WORD_LENGTH(__LENGTH__) (((__LENGTH__) == UART_WORDLENGTH_7B) || \ - ((__LENGTH__) == UART_WORDLENGTH_8B) || \ - ((__LENGTH__) == UART_WORDLENGTH_9B)) - -/** - * @brief Ensure that UART wake-up address length is valid. - * @param __ADDRESS__ UART wake-up address length. - * @retval SET (__ADDRESS__ is valid) or RESET (__ADDRESS__ is invalid) - */ -#define IS_UART_ADDRESSLENGTH_DETECT(__ADDRESS__) (((__ADDRESS__) == UART_ADDRESS_DETECT_4B) || \ - ((__ADDRESS__) == UART_ADDRESS_DETECT_7B)) - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Ensure that UART TXFIFO threshold level is valid. - * @param __THRESHOLD__ UART TXFIFO threshold level. - * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid) - */ -#define IS_UART_TXFIFO_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1_8) || \ - ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1_4) || \ - ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1_2) || \ - ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_3_4) || \ - ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_7_8) || \ - ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_8_8)) - -/** - * @brief Ensure that UART RXFIFO threshold level is valid. - * @param __THRESHOLD__ UART RXFIFO threshold level. - * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid) - */ -#define IS_UART_RXFIFO_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1_8) || \ - ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1_4) || \ - ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1_2) || \ - ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_3_4) || \ - ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_7_8) || \ - ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_8_8)) - -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ - -/* Private functions ---------------------------------------------------------*/ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* STM32L4xx_HAL_UART_EX_H */ - diff --git a/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_lpuart.h b/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_lpuart.h deleted file mode 100644 index c2bcee1..0000000 --- a/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_lpuart.h +++ /dev/null @@ -1,2881 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l4xx_ll_lpuart.h - * @author MCD Application Team - * @brief Header file of LPUART LL module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef STM32L4xx_LL_LPUART_H -#define STM32L4xx_LL_LPUART_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l4xx.h" - -/** @addtogroup STM32L4xx_LL_Driver - * @{ - */ - -#if defined (LPUART1) - -/** @defgroup LPUART_LL LPUART - * @{ - */ - -/* Private types -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -#if defined(USART_PRESC_PRESCALER) -/** @defgroup LPUART_LL_Private_Variables LPUART Private Variables - * @{ - */ -/* Array used to get the LPUART prescaler division decimal values versus @ref LPUART_LL_EC_PRESCALER values */ -static const uint16_t LPUART_PRESCALER_TAB[] = -{ - (uint16_t)1, - (uint16_t)2, - (uint16_t)4, - (uint16_t)6, - (uint16_t)8, - (uint16_t)10, - (uint16_t)12, - (uint16_t)16, - (uint16_t)32, - (uint16_t)64, - (uint16_t)128, - (uint16_t)256 -}; -/** - * @} - */ -#endif /* USART_PRESC_PRESCALER */ - -/* Private constants ---------------------------------------------------------*/ -/** @defgroup LPUART_LL_Private_Constants LPUART Private Constants - * @{ - */ -/* Defines used in Baud Rate related macros and corresponding register setting computation */ -#define LPUART_LPUARTDIV_FREQ_MUL 256U -#define LPUART_BRR_MASK 0x000FFFFFU -#define LPUART_BRR_MIN_VALUE 0x00000300U -/** - * @} - */ - - -/* Private macros ------------------------------------------------------------*/ -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup LPUART_LL_Private_Macros LPUART Private Macros - * @{ - */ -/** - * @} - */ -#endif /*USE_FULL_LL_DRIVER*/ - -/* Exported types ------------------------------------------------------------*/ -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup LPUART_LL_ES_INIT LPUART Exported Init structures - * @{ - */ - -/** - * @brief LL LPUART Init Structure definition - */ -typedef struct -{ -#if defined(USART_PRESC_PRESCALER) - uint32_t PrescalerValue; /*!< Specifies the Prescaler to compute the communication baud rate. - This parameter can be a value of @ref LPUART_LL_EC_PRESCALER. - - This feature can be modified afterwards using unitary - function @ref LL_LPUART_SetPrescaler().*/ - -#endif /* USART_PRESC_PRESCALER */ - uint32_t BaudRate; /*!< This field defines expected LPUART communication baud rate. - - This feature can be modified afterwards using unitary - function @ref LL_LPUART_SetBaudRate().*/ - - uint32_t DataWidth; /*!< Specifies the number of data bits transmitted or received in a frame. - This parameter can be a value of @ref LPUART_LL_EC_DATAWIDTH. - - This feature can be modified afterwards using unitary - function @ref LL_LPUART_SetDataWidth().*/ - - uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. - This parameter can be a value of @ref LPUART_LL_EC_STOPBITS. - - This feature can be modified afterwards using unitary - function @ref LL_LPUART_SetStopBitsLength().*/ - - uint32_t Parity; /*!< Specifies the parity mode. - This parameter can be a value of @ref LPUART_LL_EC_PARITY. - - This feature can be modified afterwards using unitary - function @ref LL_LPUART_SetParity().*/ - - uint32_t TransferDirection; /*!< Specifies whether the Receive and/or Transmit mode is enabled or disabled. - This parameter can be a value of @ref LPUART_LL_EC_DIRECTION. - - This feature can be modified afterwards using unitary - function @ref LL_LPUART_SetTransferDirection().*/ - - uint32_t HardwareFlowControl; /*!< Specifies whether the hardware flow control mode is enabled or disabled. - This parameter can be a value of @ref LPUART_LL_EC_HWCONTROL. - - This feature can be modified afterwards using unitary - function @ref LL_LPUART_SetHWFlowCtrl().*/ - -} LL_LPUART_InitTypeDef; - -/** - * @} - */ -#endif /* USE_FULL_LL_DRIVER */ - -/* Exported constants --------------------------------------------------------*/ -/** @defgroup LPUART_LL_Exported_Constants LPUART Exported Constants - * @{ - */ - -/** @defgroup LPUART_LL_EC_CLEAR_FLAG Clear Flags Defines - * @brief Flags defines which can be used with LL_LPUART_WriteReg function - * @{ - */ -#define LL_LPUART_ICR_PECF USART_ICR_PECF /*!< Parity error clear flag */ -#define LL_LPUART_ICR_FECF USART_ICR_FECF /*!< Framing error clear flag */ -#define LL_LPUART_ICR_NCF USART_ICR_NECF /*!< Noise error detected clear flag */ -#define LL_LPUART_ICR_ORECF USART_ICR_ORECF /*!< Overrun error clear flag */ -#define LL_LPUART_ICR_IDLECF USART_ICR_IDLECF /*!< Idle line detected clear flag */ -#define LL_LPUART_ICR_TCCF USART_ICR_TCCF /*!< Transmission complete clear flag */ -#define LL_LPUART_ICR_CTSCF USART_ICR_CTSCF /*!< CTS clear flag */ -#define LL_LPUART_ICR_CMCF USART_ICR_CMCF /*!< Character match clear flag */ -#define LL_LPUART_ICR_WUCF USART_ICR_WUCF /*!< Wakeup from Stop mode clear flag */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_GET_FLAG Get Flags Defines - * @brief Flags defines which can be used with LL_LPUART_ReadReg function - * @{ - */ -#define LL_LPUART_ISR_PE USART_ISR_PE /*!< Parity error flag */ -#define LL_LPUART_ISR_FE USART_ISR_FE /*!< Framing error flag */ -#define LL_LPUART_ISR_NE USART_ISR_NE /*!< Noise detected flag */ -#define LL_LPUART_ISR_ORE USART_ISR_ORE /*!< Overrun error flag */ -#define LL_LPUART_ISR_IDLE USART_ISR_IDLE /*!< Idle line detected flag */ -#if defined(USART_CR1_FIFOEN) -#define LL_LPUART_ISR_RXNE_RXFNE USART_ISR_RXNE_RXFNE /*!< Read data register or RX FIFO not empty flag */ -#else -#define LL_LPUART_ISR_RXNE USART_ISR_RXNE /*!< Read data register not empty flag */ -#endif /* USART_CR1_FIFOEN */ -#define LL_LPUART_ISR_TC USART_ISR_TC /*!< Transmission complete flag */ -#if defined(USART_CR1_FIFOEN) -#define LL_LPUART_ISR_TXE_TXFNF USART_ISR_TXE_TXFNF /*!< Transmit data register empty or TX FIFO Not Full flag*/ -#else -#define LL_LPUART_ISR_TXE USART_ISR_TXE /*!< Transmit data register empty flag */ -#endif /* USART_CR1_FIFOEN */ -#define LL_LPUART_ISR_CTSIF USART_ISR_CTSIF /*!< CTS interrupt flag */ -#define LL_LPUART_ISR_CTS USART_ISR_CTS /*!< CTS flag */ -#define LL_LPUART_ISR_BUSY USART_ISR_BUSY /*!< Busy flag */ -#define LL_LPUART_ISR_CMF USART_ISR_CMF /*!< Character match flag */ -#define LL_LPUART_ISR_SBKF USART_ISR_SBKF /*!< Send break flag */ -#define LL_LPUART_ISR_RWU USART_ISR_RWU /*!< Receiver wakeup from Mute mode flag */ -#define LL_LPUART_ISR_WUF USART_ISR_WUF /*!< Wakeup from Stop mode flag */ -#define LL_LPUART_ISR_TEACK USART_ISR_TEACK /*!< Transmit enable acknowledge flag */ -#define LL_LPUART_ISR_REACK USART_ISR_REACK /*!< Receive enable acknowledge flag */ -#if defined(USART_CR1_FIFOEN) -#define LL_LPUART_ISR_TXFE USART_ISR_TXFE /*!< TX FIFO empty flag */ -#define LL_LPUART_ISR_RXFF USART_ISR_RXFF /*!< RX FIFO full flag */ -#define LL_LPUART_ISR_RXFT USART_ISR_RXFT /*!< RX FIFO threshold flag */ -#define LL_LPUART_ISR_TXFT USART_ISR_TXFT /*!< TX FIFO threshold flag */ -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_IT IT Defines - * @brief IT defines which can be used with LL_LPUART_ReadReg and LL_LPUART_WriteReg functions - * @{ - */ -#define LL_LPUART_CR1_IDLEIE USART_CR1_IDLEIE /*!< IDLE interrupt enable */ -#if defined(USART_CR1_FIFOEN) -#define LL_LPUART_CR1_RXNEIE_RXFNEIE USART_CR1_RXNEIE_RXFNEIE /*!< Read data register and RXFIFO not empty - interrupt enable */ -#else -#define LL_LPUART_CR1_RXNEIE USART_CR1_RXNEIE /*!< Read data register not empty interrupt enable */ -#endif /* USART_CR1_FIFOEN */ -#define LL_LPUART_CR1_TCIE USART_CR1_TCIE /*!< Transmission complete interrupt enable */ -#if defined(USART_CR1_FIFOEN) -#define LL_LPUART_CR1_TXEIE_TXFNFIE USART_CR1_TXEIE_TXFNFIE /*!< Transmit data register empty and TX FIFO - not full interrupt enable */ -#else -#define LL_LPUART_CR1_TXEIE USART_CR1_TXEIE /*!< Transmit data register empty interrupt enable */ -#endif /* USART_CR1_FIFOEN */ -#define LL_LPUART_CR1_PEIE USART_CR1_PEIE /*!< Parity error */ -#define LL_LPUART_CR1_CMIE USART_CR1_CMIE /*!< Character match interrupt enable */ -#if defined(USART_CR1_FIFOEN) -#define LL_LPUART_CR1_TXFEIE USART_CR1_TXFEIE /*!< TX FIFO empty interrupt enable */ -#define LL_LPUART_CR1_RXFFIE USART_CR1_RXFFIE /*!< RX FIFO full interrupt enable */ -#endif /* USART_CR1_FIFOEN */ -#define LL_LPUART_CR3_EIE USART_CR3_EIE /*!< Error interrupt enable */ -#define LL_LPUART_CR3_CTSIE USART_CR3_CTSIE /*!< CTS interrupt enable */ -#define LL_LPUART_CR3_WUFIE USART_CR3_WUFIE /*!< Wakeup from Stop mode interrupt enable */ -#if defined(USART_CR1_FIFOEN) -#define LL_LPUART_CR3_TXFTIE USART_CR3_TXFTIE /*!< TX FIFO threshold interrupt enable */ -#define LL_LPUART_CR3_RXFTIE USART_CR3_RXFTIE /*!< RX FIFO threshold interrupt enable */ -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ -#if defined(USART_CR1_FIFOEN) - -/** @defgroup LPUART_LL_EC_FIFOTHRESHOLD FIFO Threshold - * @{ - */ -#define LL_LPUART_FIFOTHRESHOLD_1_8 0x00000000U /*!< FIFO reaches 1/8 of its depth */ -#define LL_LPUART_FIFOTHRESHOLD_1_4 0x00000001U /*!< FIFO reaches 1/4 of its depth */ -#define LL_LPUART_FIFOTHRESHOLD_1_2 0x00000002U /*!< FIFO reaches 1/2 of its depth */ -#define LL_LPUART_FIFOTHRESHOLD_3_4 0x00000003U /*!< FIFO reaches 3/4 of its depth */ -#define LL_LPUART_FIFOTHRESHOLD_7_8 0x00000004U /*!< FIFO reaches 7/8 of its depth */ -#define LL_LPUART_FIFOTHRESHOLD_8_8 0x00000005U /*!< FIFO becomes empty for TX and full for RX */ -/** - * @} - */ -#endif /* USART_CR1_FIFOEN */ - -/** @defgroup LPUART_LL_EC_DIRECTION Direction - * @{ - */ -#define LL_LPUART_DIRECTION_NONE 0x00000000U /*!< Transmitter and Receiver are disabled */ -#define LL_LPUART_DIRECTION_RX USART_CR1_RE /*!< Transmitter is disabled and Receiver is enabled */ -#define LL_LPUART_DIRECTION_TX USART_CR1_TE /*!< Transmitter is enabled and Receiver is disabled */ -#define LL_LPUART_DIRECTION_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< Transmitter and Receiver are enabled */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_PARITY Parity Control - * @{ - */ -#define LL_LPUART_PARITY_NONE 0x00000000U /*!< Parity control disabled */ -#define LL_LPUART_PARITY_EVEN USART_CR1_PCE /*!< Parity control enabled and Even Parity is selected */ -#define LL_LPUART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Parity control enabled and Odd Parity is selected */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_WAKEUP Wakeup - * @{ - */ -#define LL_LPUART_WAKEUP_IDLELINE 0x00000000U /*!< LPUART wake up from Mute mode on Idle Line */ -#define LL_LPUART_WAKEUP_ADDRESSMARK USART_CR1_WAKE /*!< LPUART wake up from Mute mode on Address Mark */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_DATAWIDTH Datawidth - * @{ - */ -#define LL_LPUART_DATAWIDTH_7B USART_CR1_M1 /*!< 7 bits word length : Start bit, 7 data bits, n stop bits */ -#define LL_LPUART_DATAWIDTH_8B 0x00000000U /*!< 8 bits word length : Start bit, 8 data bits, n stop bits */ -#define LL_LPUART_DATAWIDTH_9B USART_CR1_M0 /*!< 9 bits word length : Start bit, 9 data bits, n stop bits */ -/** - * @} - */ -#if defined(USART_PRESC_PRESCALER) - -/** @defgroup LPUART_LL_EC_PRESCALER Clock Source Prescaler - * @{ - */ -#define LL_LPUART_PRESCALER_DIV1 0x00000000U /*!< Input clock not divided */ -#define LL_LPUART_PRESCALER_DIV2 (USART_PRESC_PRESCALER_0) /*!< Input clock divided by 2 */ -#define LL_LPUART_PRESCALER_DIV4 (USART_PRESC_PRESCALER_1) /*!< Input clock divided by 4 */ -#define LL_LPUART_PRESCALER_DIV6 (USART_PRESC_PRESCALER_1 |\ - USART_PRESC_PRESCALER_0) /*!< Input clock divided by 6 */ -#define LL_LPUART_PRESCALER_DIV8 (USART_PRESC_PRESCALER_2) /*!< Input clock divided by 8 */ -#define LL_LPUART_PRESCALER_DIV10 (USART_PRESC_PRESCALER_2 |\ - USART_PRESC_PRESCALER_0) /*!< Input clock divided by 10 */ -#define LL_LPUART_PRESCALER_DIV12 (USART_PRESC_PRESCALER_2 |\ - USART_PRESC_PRESCALER_1) /*!< Input clock divided by 12 */ -#define LL_LPUART_PRESCALER_DIV16 (USART_PRESC_PRESCALER_2 |\ - USART_PRESC_PRESCALER_1 |\ - USART_PRESC_PRESCALER_0) /*!< Input clock divided by 16 */ -#define LL_LPUART_PRESCALER_DIV32 (USART_PRESC_PRESCALER_3) /*!< Input clock divided by 32 */ -#define LL_LPUART_PRESCALER_DIV64 (USART_PRESC_PRESCALER_3 |\ - USART_PRESC_PRESCALER_0) /*!< Input clock divided by 64 */ -#define LL_LPUART_PRESCALER_DIV128 (USART_PRESC_PRESCALER_3 |\ - USART_PRESC_PRESCALER_1) /*!< Input clock divided by 128 */ -#define LL_LPUART_PRESCALER_DIV256 (USART_PRESC_PRESCALER_3 |\ - USART_PRESC_PRESCALER_1 |\ - USART_PRESC_PRESCALER_0) /*!< Input clock divided by 256 */ -/** - * @} - */ -#endif /* USART_PRESC_PRESCALER */ - -/** @defgroup LPUART_LL_EC_STOPBITS Stop Bits - * @{ - */ -#define LL_LPUART_STOPBITS_1 0x00000000U /*!< 1 stop bit */ -#define LL_LPUART_STOPBITS_2 USART_CR2_STOP_1 /*!< 2 stop bits */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_TXRX TX RX Pins Swap - * @{ - */ -#define LL_LPUART_TXRX_STANDARD 0x00000000U /*!< TX/RX pins are used as defined in standard pinout */ -#define LL_LPUART_TXRX_SWAPPED (USART_CR2_SWAP) /*!< TX and RX pins functions are swapped. */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_RXPIN_LEVEL RX Pin Active Level Inversion - * @{ - */ -#define LL_LPUART_RXPIN_LEVEL_STANDARD 0x00000000U /*!< RX pin signal works using the standard logic levels */ -#define LL_LPUART_RXPIN_LEVEL_INVERTED (USART_CR2_RXINV) /*!< RX pin signal values are inverted. */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_TXPIN_LEVEL TX Pin Active Level Inversion - * @{ - */ -#define LL_LPUART_TXPIN_LEVEL_STANDARD 0x00000000U /*!< TX pin signal works using the standard logic levels */ -#define LL_LPUART_TXPIN_LEVEL_INVERTED (USART_CR2_TXINV) /*!< TX pin signal values are inverted. */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_BINARY_LOGIC Binary Data Inversion - * @{ - */ -#define LL_LPUART_BINARY_LOGIC_POSITIVE 0x00000000U /*!< Logical data from the data register are send/received - in positive/direct logic. (1=H, 0=L) */ -#define LL_LPUART_BINARY_LOGIC_NEGATIVE USART_CR2_DATAINV /*!< Logical data from the data register are send/received - in negative/inverse logic. (1=L, 0=H). - The parity bit is also inverted. */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_BITORDER Bit Order - * @{ - */ -#define LL_LPUART_BITORDER_LSBFIRST 0x00000000U /*!< data is transmitted/received with data bit 0 first, - following the start bit */ -#define LL_LPUART_BITORDER_MSBFIRST USART_CR2_MSBFIRST /*!< data is transmitted/received with the MSB first, - following the start bit */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_ADDRESS_DETECT Address Length Detection - * @{ - */ -#define LL_LPUART_ADDRESS_DETECT_4B 0x00000000U /*!< 4-bit address detection method selected */ -#define LL_LPUART_ADDRESS_DETECT_7B USART_CR2_ADDM7 /*!< 7-bit address detection (in 8-bit data mode) method selected */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_HWCONTROL Hardware Control - * @{ - */ -#define LL_LPUART_HWCONTROL_NONE 0x00000000U /*!< CTS and RTS hardware flow control disabled */ -#define LL_LPUART_HWCONTROL_RTS USART_CR3_RTSE /*!< RTS output enabled, data is only requested - when there is space in the receive buffer */ -#define LL_LPUART_HWCONTROL_CTS USART_CR3_CTSE /*!< CTS mode enabled, data is only transmitted - when the nCTS input is asserted (tied to 0)*/ -#define LL_LPUART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) /*!< CTS and RTS hardware flow control enabled */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_WAKEUP_ON Wakeup Activation - * @{ - */ -#define LL_LPUART_WAKEUP_ON_ADDRESS 0x00000000U /*!< Wake up active on address match */ -#define LL_LPUART_WAKEUP_ON_STARTBIT USART_CR3_WUS_1 /*!< Wake up active on Start bit detection */ -#define LL_LPUART_WAKEUP_ON_RXNE (USART_CR3_WUS_0 | USART_CR3_WUS_1) /*!< Wake up active on RXNE */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_DE_POLARITY Driver Enable Polarity - * @{ - */ -#define LL_LPUART_DE_POLARITY_HIGH 0x00000000U /*!< DE signal is active high */ -#define LL_LPUART_DE_POLARITY_LOW USART_CR3_DEP /*!< DE signal is active low */ -/** - * @} - */ - -/** @defgroup LPUART_LL_EC_DMA_REG_DATA DMA Register Data - * @{ - */ -#define LL_LPUART_DMA_REG_DATA_TRANSMIT 0x00000000U /*!< Get address of data register used for transmission */ -#define LL_LPUART_DMA_REG_DATA_RECEIVE 0x00000001U /*!< Get address of data register used for reception */ -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/** @defgroup LPUART_LL_Exported_Macros LPUART Exported Macros - * @{ - */ - -/** @defgroup LPUART_LL_EM_WRITE_READ Common Write and read registers Macros - * @{ - */ - -/** - * @brief Write a value in LPUART register - * @param __INSTANCE__ LPUART Instance - * @param __REG__ Register to be written - * @param __VALUE__ Value to be written in the register - * @retval None - */ -#define LL_LPUART_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) - -/** - * @brief Read a value in LPUART register - * @param __INSTANCE__ LPUART Instance - * @param __REG__ Register to be read - * @retval Register value - */ -#define LL_LPUART_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) -/** - * @} - */ - -/** @defgroup LPUART_LL_EM_Exported_Macros_Helper Helper Macros - * @{ - */ - -/** - * @brief Compute LPUARTDIV value according to Peripheral Clock and - * expected Baud Rate (20-bit value of LPUARTDIV is returned) - * @param __PERIPHCLK__ Peripheral Clock frequency used for LPUART Instance - @if USART_PRESC_PRESCALER - * @param __PRESCALER__ This parameter can be one of the following values: - * @arg @ref LL_LPUART_PRESCALER_DIV1 - * @arg @ref LL_LPUART_PRESCALER_DIV2 - * @arg @ref LL_LPUART_PRESCALER_DIV4 - * @arg @ref LL_LPUART_PRESCALER_DIV6 - * @arg @ref LL_LPUART_PRESCALER_DIV8 - * @arg @ref LL_LPUART_PRESCALER_DIV10 - * @arg @ref LL_LPUART_PRESCALER_DIV12 - * @arg @ref LL_LPUART_PRESCALER_DIV16 - * @arg @ref LL_LPUART_PRESCALER_DIV32 - * @arg @ref LL_LPUART_PRESCALER_DIV64 - * @arg @ref LL_LPUART_PRESCALER_DIV128 - * @arg @ref LL_LPUART_PRESCALER_DIV256 - @endif - * @param __BAUDRATE__ Baud Rate value to achieve - * @retval LPUARTDIV value to be used for BRR register filling - */ -#if defined(USART_PRESC_PRESCALER) -#define __LL_LPUART_DIV(__PERIPHCLK__, __PRESCALER__, __BAUDRATE__) (uint32_t)\ - ((((((uint64_t)(__PERIPHCLK__)/(uint64_t)(LPUART_PRESCALER_TAB[(uint16_t)(__PRESCALER__)]))\ - * LPUART_LPUARTDIV_FREQ_MUL) + (uint32_t)((__BAUDRATE__)/2U))/(__BAUDRATE__)) & LPUART_BRR_MASK) -#else -#define __LL_LPUART_DIV(__PERIPHCLK__, __BAUDRATE__) (uint32_t)(((((uint64_t)(__PERIPHCLK__)*LPUART_LPUARTDIV_FREQ_MUL) + (uint32_t)((__BAUDRATE__)/2U))/(__BAUDRATE__))\ - & LPUART_BRR_MASK) -#endif /* USART_PRESC_PRESCALER */ - -/** - * @} - */ - -/** - * @} - */ - -/* Exported functions --------------------------------------------------------*/ -/** @defgroup LPUART_LL_Exported_Functions LPUART Exported Functions - * @{ - */ - -/** @defgroup LPUART_LL_EF_Configuration Configuration functions - * @{ - */ - -/** - * @brief LPUART Enable - * @rmtoll CR1 UE LL_LPUART_Enable - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_Enable(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->CR1, USART_CR1_UE); -} - -/** - * @brief LPUART Disable - * @note When LPUART is disabled, LPUART prescalers and outputs are stopped immediately, - * and current operations are discarded. The configuration of the LPUART is kept, but all the status - * flags, in the LPUARTx_ISR are set to their default values. - * @note In order to go into low-power mode without generating errors on the line, - * the TE bit must be reset before and the software must wait - * for the TC bit in the LPUART_ISR to be set before resetting the UE bit. - * The DMA requests are also reset when UE = 0 so the DMA channel must - * be disabled before resetting the UE bit. - * @rmtoll CR1 UE LL_LPUART_Disable - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_Disable(USART_TypeDef *LPUARTx) -{ - CLEAR_BIT(LPUARTx->CR1, USART_CR1_UE); -} - -/** - * @brief Indicate if LPUART is enabled - * @rmtoll CR1 UE LL_LPUART_IsEnabled - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabled(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_UE) == (USART_CR1_UE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief FIFO Mode Enable - * @rmtoll CR1 FIFOEN LL_LPUART_EnableFIFO - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableFIFO(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->CR1, USART_CR1_FIFOEN); -} - -/** - * @brief FIFO Mode Disable - * @rmtoll CR1 FIFOEN LL_LPUART_DisableFIFO - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableFIFO(USART_TypeDef *LPUARTx) -{ - CLEAR_BIT(LPUARTx->CR1, USART_CR1_FIFOEN); -} - -/** - * @brief Indicate if FIFO Mode is enabled - * @rmtoll CR1 FIFOEN LL_LPUART_IsEnabledFIFO - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledFIFO(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_FIFOEN) == (USART_CR1_FIFOEN)) ? 1UL : 0UL); -} - -/** - * @brief Configure TX FIFO Threshold - * @rmtoll CR3 TXFTCFG LL_LPUART_SetTXFIFOThreshold - * @param LPUARTx LPUART Instance - * @param Threshold This parameter can be one of the following values: - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetTXFIFOThreshold(USART_TypeDef *LPUARTx, uint32_t Threshold) -{ - ATOMIC_MODIFY_REG(LPUARTx->CR3, USART_CR3_TXFTCFG, Threshold << USART_CR3_TXFTCFG_Pos); -} - -/** - * @brief Return TX FIFO Threshold Configuration - * @rmtoll CR3 TXFTCFG LL_LPUART_GetTXFIFOThreshold - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 - */ -__STATIC_INLINE uint32_t LL_LPUART_GetTXFIFOThreshold(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos); -} - -/** - * @brief Configure RX FIFO Threshold - * @rmtoll CR3 RXFTCFG LL_LPUART_SetRXFIFOThreshold - * @param LPUARTx LPUART Instance - * @param Threshold This parameter can be one of the following values: - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetRXFIFOThreshold(USART_TypeDef *LPUARTx, uint32_t Threshold) -{ - ATOMIC_MODIFY_REG(LPUARTx->CR3, USART_CR3_RXFTCFG, Threshold << USART_CR3_RXFTCFG_Pos); -} - -/** - * @brief Return RX FIFO Threshold Configuration - * @rmtoll CR3 RXFTCFG LL_LPUART_GetRXFIFOThreshold - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 - */ -__STATIC_INLINE uint32_t LL_LPUART_GetRXFIFOThreshold(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos); -} - -/** - * @brief Configure TX and RX FIFOs Threshold - * @rmtoll CR3 TXFTCFG LL_LPUART_ConfigFIFOsThreshold\n - * CR3 RXFTCFG LL_LPUART_ConfigFIFOsThreshold - * @param LPUARTx LPUART Instance - * @param TXThreshold This parameter can be one of the following values: - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 - * @param RXThreshold This parameter can be one of the following values: - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ConfigFIFOsThreshold(USART_TypeDef *LPUARTx, uint32_t TXThreshold, uint32_t RXThreshold) -{ - ATOMIC_MODIFY_REG(LPUARTx->CR3, USART_CR3_TXFTCFG | USART_CR3_RXFTCFG, (TXThreshold << USART_CR3_TXFTCFG_Pos) | \ - (RXThreshold << USART_CR3_RXFTCFG_Pos)); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief LPUART enabled in STOP Mode - * @note When this function is enabled, LPUART is able to wake up the MCU from Stop mode, provided that - * LPUART clock selection is HSI or LSE in RCC. - * @rmtoll CR1 UESM LL_LPUART_EnableInStopMode - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableInStopMode(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_UESM); -} - -/** - * @brief LPUART disabled in STOP Mode - * @note When this function is disabled, LPUART is not able to wake up the MCU from Stop mode - * @rmtoll CR1 UESM LL_LPUART_DisableInStopMode - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableInStopMode(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_UESM); -} - -/** - * @brief Indicate if LPUART is enabled in STOP Mode - * (able to wake up MCU from Stop mode or not) - * @rmtoll CR1 UESM LL_LPUART_IsEnabledInStopMode - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledInStopMode(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_UESM) == (USART_CR1_UESM)) ? 1UL : 0UL); -} - -#if defined(USART_CR3_UCESM) -/** - * @brief LPUART Clock enabled in STOP Mode - * @note When this function is called, LPUART Clock is enabled while in STOP mode - * @rmtoll CR3 UCESM LL_LPUART_EnableClockInStopMode - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableClockInStopMode(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_UCESM); -} - -/** - * @brief LPUART clock disabled in STOP Mode - * @note When this function is called, LPUART Clock is disabled while in STOP mode - * @rmtoll CR3 UCESM LL_LPUART_DisableClockInStopMode - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableClockInStopMode(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_UCESM); -} - -/** - * @brief Indicate if LPUART clock is enabled in STOP Mode - * @rmtoll CR3 UCESM LL_LPUART_IsClockEnabledInStopMode - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsClockEnabledInStopMode(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_UCESM) == (USART_CR3_UCESM)) ? 1UL : 0UL); -} - -#endif /* USART_CR3_UCESM */ -/** - * @brief Receiver Enable (Receiver is enabled and begins searching for a start bit) - * @rmtoll CR1 RE LL_LPUART_EnableDirectionRx - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableDirectionRx(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_RE); -} - -/** - * @brief Receiver Disable - * @rmtoll CR1 RE LL_LPUART_DisableDirectionRx - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableDirectionRx(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_RE); -} - -/** - * @brief Transmitter Enable - * @rmtoll CR1 TE LL_LPUART_EnableDirectionTx - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableDirectionTx(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_TE); -} - -/** - * @brief Transmitter Disable - * @rmtoll CR1 TE LL_LPUART_DisableDirectionTx - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableDirectionTx(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_TE); -} - -/** - * @brief Configure simultaneously enabled/disabled states - * of Transmitter and Receiver - * @rmtoll CR1 RE LL_LPUART_SetTransferDirection\n - * CR1 TE LL_LPUART_SetTransferDirection - * @param LPUARTx LPUART Instance - * @param TransferDirection This parameter can be one of the following values: - * @arg @ref LL_LPUART_DIRECTION_NONE - * @arg @ref LL_LPUART_DIRECTION_RX - * @arg @ref LL_LPUART_DIRECTION_TX - * @arg @ref LL_LPUART_DIRECTION_TX_RX - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetTransferDirection(USART_TypeDef *LPUARTx, uint32_t TransferDirection) -{ - ATOMIC_MODIFY_REG(LPUARTx->CR1, USART_CR1_RE | USART_CR1_TE, TransferDirection); -} - -/** - * @brief Return enabled/disabled states of Transmitter and Receiver - * @rmtoll CR1 RE LL_LPUART_GetTransferDirection\n - * CR1 TE LL_LPUART_GetTransferDirection - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_DIRECTION_NONE - * @arg @ref LL_LPUART_DIRECTION_RX - * @arg @ref LL_LPUART_DIRECTION_TX - * @arg @ref LL_LPUART_DIRECTION_TX_RX - */ -__STATIC_INLINE uint32_t LL_LPUART_GetTransferDirection(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_RE | USART_CR1_TE)); -} - -/** - * @brief Configure Parity (enabled/disabled and parity mode if enabled) - * @note This function selects if hardware parity control (generation and detection) is enabled or disabled. - * When the parity control is enabled (Odd or Even), computed parity bit is inserted at the MSB position - * (depending on data width) and parity is checked on the received data. - * @rmtoll CR1 PS LL_LPUART_SetParity\n - * CR1 PCE LL_LPUART_SetParity - * @param LPUARTx LPUART Instance - * @param Parity This parameter can be one of the following values: - * @arg @ref LL_LPUART_PARITY_NONE - * @arg @ref LL_LPUART_PARITY_EVEN - * @arg @ref LL_LPUART_PARITY_ODD - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetParity(USART_TypeDef *LPUARTx, uint32_t Parity) -{ - MODIFY_REG(LPUARTx->CR1, USART_CR1_PS | USART_CR1_PCE, Parity); -} - -/** - * @brief Return Parity configuration (enabled/disabled and parity mode if enabled) - * @rmtoll CR1 PS LL_LPUART_GetParity\n - * CR1 PCE LL_LPUART_GetParity - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_PARITY_NONE - * @arg @ref LL_LPUART_PARITY_EVEN - * @arg @ref LL_LPUART_PARITY_ODD - */ -__STATIC_INLINE uint32_t LL_LPUART_GetParity(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_PS | USART_CR1_PCE)); -} - -/** - * @brief Set Receiver Wake Up method from Mute mode. - * @rmtoll CR1 WAKE LL_LPUART_SetWakeUpMethod - * @param LPUARTx LPUART Instance - * @param Method This parameter can be one of the following values: - * @arg @ref LL_LPUART_WAKEUP_IDLELINE - * @arg @ref LL_LPUART_WAKEUP_ADDRESSMARK - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetWakeUpMethod(USART_TypeDef *LPUARTx, uint32_t Method) -{ - MODIFY_REG(LPUARTx->CR1, USART_CR1_WAKE, Method); -} - -/** - * @brief Return Receiver Wake Up method from Mute mode - * @rmtoll CR1 WAKE LL_LPUART_GetWakeUpMethod - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_WAKEUP_IDLELINE - * @arg @ref LL_LPUART_WAKEUP_ADDRESSMARK - */ -__STATIC_INLINE uint32_t LL_LPUART_GetWakeUpMethod(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_WAKE)); -} - -/** - * @brief Set Word length (nb of data bits, excluding start and stop bits) - * @rmtoll CR1 M LL_LPUART_SetDataWidth - * @param LPUARTx LPUART Instance - * @param DataWidth This parameter can be one of the following values: - * @arg @ref LL_LPUART_DATAWIDTH_7B - * @arg @ref LL_LPUART_DATAWIDTH_8B - * @arg @ref LL_LPUART_DATAWIDTH_9B - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetDataWidth(USART_TypeDef *LPUARTx, uint32_t DataWidth) -{ - MODIFY_REG(LPUARTx->CR1, USART_CR1_M, DataWidth); -} - -/** - * @brief Return Word length (i.e. nb of data bits, excluding start and stop bits) - * @rmtoll CR1 M LL_LPUART_GetDataWidth - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_DATAWIDTH_7B - * @arg @ref LL_LPUART_DATAWIDTH_8B - * @arg @ref LL_LPUART_DATAWIDTH_9B - */ -__STATIC_INLINE uint32_t LL_LPUART_GetDataWidth(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_M)); -} - -/** - * @brief Allow switch between Mute Mode and Active mode - * @rmtoll CR1 MME LL_LPUART_EnableMuteMode - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableMuteMode(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_MME); -} - -/** - * @brief Prevent Mute Mode use. Set Receiver in active mode permanently. - * @rmtoll CR1 MME LL_LPUART_DisableMuteMode - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableMuteMode(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_MME); -} - -/** - * @brief Indicate if switch between Mute Mode and Active mode is allowed - * @rmtoll CR1 MME LL_LPUART_IsEnabledMuteMode - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledMuteMode(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_MME) == (USART_CR1_MME)) ? 1UL : 0UL); -} - -#if defined(USART_PRESC_PRESCALER) -/** - * @brief Configure Clock source prescaler for baudrate generator and oversampling - * @rmtoll PRESC PRESCALER LL_LPUART_SetPrescaler - * @param LPUARTx LPUART Instance - * @param PrescalerValue This parameter can be one of the following values: - * @arg @ref LL_LPUART_PRESCALER_DIV1 - * @arg @ref LL_LPUART_PRESCALER_DIV2 - * @arg @ref LL_LPUART_PRESCALER_DIV4 - * @arg @ref LL_LPUART_PRESCALER_DIV6 - * @arg @ref LL_LPUART_PRESCALER_DIV8 - * @arg @ref LL_LPUART_PRESCALER_DIV10 - * @arg @ref LL_LPUART_PRESCALER_DIV12 - * @arg @ref LL_LPUART_PRESCALER_DIV16 - * @arg @ref LL_LPUART_PRESCALER_DIV32 - * @arg @ref LL_LPUART_PRESCALER_DIV64 - * @arg @ref LL_LPUART_PRESCALER_DIV128 - * @arg @ref LL_LPUART_PRESCALER_DIV256 - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetPrescaler(USART_TypeDef *LPUARTx, uint32_t PrescalerValue) -{ - MODIFY_REG(LPUARTx->PRESC, USART_PRESC_PRESCALER, (uint16_t)PrescalerValue); -} - -/** - * @brief Retrieve the Clock source prescaler for baudrate generator and oversampling - * @rmtoll PRESC PRESCALER LL_LPUART_GetPrescaler - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_PRESCALER_DIV1 - * @arg @ref LL_LPUART_PRESCALER_DIV2 - * @arg @ref LL_LPUART_PRESCALER_DIV4 - * @arg @ref LL_LPUART_PRESCALER_DIV6 - * @arg @ref LL_LPUART_PRESCALER_DIV8 - * @arg @ref LL_LPUART_PRESCALER_DIV10 - * @arg @ref LL_LPUART_PRESCALER_DIV12 - * @arg @ref LL_LPUART_PRESCALER_DIV16 - * @arg @ref LL_LPUART_PRESCALER_DIV32 - * @arg @ref LL_LPUART_PRESCALER_DIV64 - * @arg @ref LL_LPUART_PRESCALER_DIV128 - * @arg @ref LL_LPUART_PRESCALER_DIV256 - */ -__STATIC_INLINE uint32_t LL_LPUART_GetPrescaler(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->PRESC, USART_PRESC_PRESCALER)); -} -#endif /* USART_PRESC_PRESCALER */ - -/** - * @brief Set the length of the stop bits - * @rmtoll CR2 STOP LL_LPUART_SetStopBitsLength - * @param LPUARTx LPUART Instance - * @param StopBits This parameter can be one of the following values: - * @arg @ref LL_LPUART_STOPBITS_1 - * @arg @ref LL_LPUART_STOPBITS_2 - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetStopBitsLength(USART_TypeDef *LPUARTx, uint32_t StopBits) -{ - MODIFY_REG(LPUARTx->CR2, USART_CR2_STOP, StopBits); -} - -/** - * @brief Retrieve the length of the stop bits - * @rmtoll CR2 STOP LL_LPUART_GetStopBitsLength - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_STOPBITS_1 - * @arg @ref LL_LPUART_STOPBITS_2 - */ -__STATIC_INLINE uint32_t LL_LPUART_GetStopBitsLength(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_STOP)); -} - -/** - * @brief Configure Character frame format (Datawidth, Parity control, Stop Bits) - * @note Call of this function is equivalent to following function call sequence : - * - Data Width configuration using @ref LL_LPUART_SetDataWidth() function - * - Parity Control and mode configuration using @ref LL_LPUART_SetParity() function - * - Stop bits configuration using @ref LL_LPUART_SetStopBitsLength() function - * @rmtoll CR1 PS LL_LPUART_ConfigCharacter\n - * CR1 PCE LL_LPUART_ConfigCharacter\n - * CR1 M LL_LPUART_ConfigCharacter\n - * CR2 STOP LL_LPUART_ConfigCharacter - * @param LPUARTx LPUART Instance - * @param DataWidth This parameter can be one of the following values: - * @arg @ref LL_LPUART_DATAWIDTH_7B - * @arg @ref LL_LPUART_DATAWIDTH_8B - * @arg @ref LL_LPUART_DATAWIDTH_9B - * @param Parity This parameter can be one of the following values: - * @arg @ref LL_LPUART_PARITY_NONE - * @arg @ref LL_LPUART_PARITY_EVEN - * @arg @ref LL_LPUART_PARITY_ODD - * @param StopBits This parameter can be one of the following values: - * @arg @ref LL_LPUART_STOPBITS_1 - * @arg @ref LL_LPUART_STOPBITS_2 - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ConfigCharacter(USART_TypeDef *LPUARTx, uint32_t DataWidth, uint32_t Parity, - uint32_t StopBits) -{ - MODIFY_REG(LPUARTx->CR1, USART_CR1_PS | USART_CR1_PCE | USART_CR1_M, Parity | DataWidth); - MODIFY_REG(LPUARTx->CR2, USART_CR2_STOP, StopBits); -} - -/** - * @brief Configure TX/RX pins swapping setting. - * @rmtoll CR2 SWAP LL_LPUART_SetTXRXSwap - * @param LPUARTx LPUART Instance - * @param SwapConfig This parameter can be one of the following values: - * @arg @ref LL_LPUART_TXRX_STANDARD - * @arg @ref LL_LPUART_TXRX_SWAPPED - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetTXRXSwap(USART_TypeDef *LPUARTx, uint32_t SwapConfig) -{ - MODIFY_REG(LPUARTx->CR2, USART_CR2_SWAP, SwapConfig); -} - -/** - * @brief Retrieve TX/RX pins swapping configuration. - * @rmtoll CR2 SWAP LL_LPUART_GetTXRXSwap - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_TXRX_STANDARD - * @arg @ref LL_LPUART_TXRX_SWAPPED - */ -__STATIC_INLINE uint32_t LL_LPUART_GetTXRXSwap(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_SWAP)); -} - -/** - * @brief Configure RX pin active level logic - * @rmtoll CR2 RXINV LL_LPUART_SetRXPinLevel - * @param LPUARTx LPUART Instance - * @param PinInvMethod This parameter can be one of the following values: - * @arg @ref LL_LPUART_RXPIN_LEVEL_STANDARD - * @arg @ref LL_LPUART_RXPIN_LEVEL_INVERTED - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetRXPinLevel(USART_TypeDef *LPUARTx, uint32_t PinInvMethod) -{ - MODIFY_REG(LPUARTx->CR2, USART_CR2_RXINV, PinInvMethod); -} - -/** - * @brief Retrieve RX pin active level logic configuration - * @rmtoll CR2 RXINV LL_LPUART_GetRXPinLevel - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_RXPIN_LEVEL_STANDARD - * @arg @ref LL_LPUART_RXPIN_LEVEL_INVERTED - */ -__STATIC_INLINE uint32_t LL_LPUART_GetRXPinLevel(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_RXINV)); -} - -/** - * @brief Configure TX pin active level logic - * @rmtoll CR2 TXINV LL_LPUART_SetTXPinLevel - * @param LPUARTx LPUART Instance - * @param PinInvMethod This parameter can be one of the following values: - * @arg @ref LL_LPUART_TXPIN_LEVEL_STANDARD - * @arg @ref LL_LPUART_TXPIN_LEVEL_INVERTED - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetTXPinLevel(USART_TypeDef *LPUARTx, uint32_t PinInvMethod) -{ - MODIFY_REG(LPUARTx->CR2, USART_CR2_TXINV, PinInvMethod); -} - -/** - * @brief Retrieve TX pin active level logic configuration - * @rmtoll CR2 TXINV LL_LPUART_GetTXPinLevel - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_TXPIN_LEVEL_STANDARD - * @arg @ref LL_LPUART_TXPIN_LEVEL_INVERTED - */ -__STATIC_INLINE uint32_t LL_LPUART_GetTXPinLevel(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_TXINV)); -} - -/** - * @brief Configure Binary data logic. - * - * @note Allow to define how Logical data from the data register are send/received : - * either in positive/direct logic (1=H, 0=L) or in negative/inverse logic (1=L, 0=H) - * @rmtoll CR2 DATAINV LL_LPUART_SetBinaryDataLogic - * @param LPUARTx LPUART Instance - * @param DataLogic This parameter can be one of the following values: - * @arg @ref LL_LPUART_BINARY_LOGIC_POSITIVE - * @arg @ref LL_LPUART_BINARY_LOGIC_NEGATIVE - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetBinaryDataLogic(USART_TypeDef *LPUARTx, uint32_t DataLogic) -{ - MODIFY_REG(LPUARTx->CR2, USART_CR2_DATAINV, DataLogic); -} - -/** - * @brief Retrieve Binary data configuration - * @rmtoll CR2 DATAINV LL_LPUART_GetBinaryDataLogic - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_BINARY_LOGIC_POSITIVE - * @arg @ref LL_LPUART_BINARY_LOGIC_NEGATIVE - */ -__STATIC_INLINE uint32_t LL_LPUART_GetBinaryDataLogic(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_DATAINV)); -} - -/** - * @brief Configure transfer bit order (either Less or Most Significant Bit First) - * @note MSB First means data is transmitted/received with the MSB first, following the start bit. - * LSB First means data is transmitted/received with data bit 0 first, following the start bit. - * @rmtoll CR2 MSBFIRST LL_LPUART_SetTransferBitOrder - * @param LPUARTx LPUART Instance - * @param BitOrder This parameter can be one of the following values: - * @arg @ref LL_LPUART_BITORDER_LSBFIRST - * @arg @ref LL_LPUART_BITORDER_MSBFIRST - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetTransferBitOrder(USART_TypeDef *LPUARTx, uint32_t BitOrder) -{ - MODIFY_REG(LPUARTx->CR2, USART_CR2_MSBFIRST, BitOrder); -} - -/** - * @brief Return transfer bit order (either Less or Most Significant Bit First) - * @note MSB First means data is transmitted/received with the MSB first, following the start bit. - * LSB First means data is transmitted/received with data bit 0 first, following the start bit. - * @rmtoll CR2 MSBFIRST LL_LPUART_GetTransferBitOrder - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_BITORDER_LSBFIRST - * @arg @ref LL_LPUART_BITORDER_MSBFIRST - */ -__STATIC_INLINE uint32_t LL_LPUART_GetTransferBitOrder(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_MSBFIRST)); -} - -/** - * @brief Set Address of the LPUART node. - * @note This is used in multiprocessor communication during Mute mode or Stop mode, - * for wake up with address mark detection. - * @note 4bits address node is used when 4-bit Address Detection is selected in ADDM7. - * (b7-b4 should be set to 0) - * 8bits address node is used when 7-bit Address Detection is selected in ADDM7. - * (This is used in multiprocessor communication during Mute mode or Stop mode, - * for wake up with 7-bit address mark detection. - * The MSB of the character sent by the transmitter should be equal to 1. - * It may also be used for character detection during normal reception, - * Mute mode inactive (for example, end of block detection in ModBus protocol). - * In this case, the whole received character (8-bit) is compared to the ADD[7:0] - * value and CMF flag is set on match) - * @rmtoll CR2 ADD LL_LPUART_ConfigNodeAddress\n - * CR2 ADDM7 LL_LPUART_ConfigNodeAddress - * @param LPUARTx LPUART Instance - * @param AddressLen This parameter can be one of the following values: - * @arg @ref LL_LPUART_ADDRESS_DETECT_4B - * @arg @ref LL_LPUART_ADDRESS_DETECT_7B - * @param NodeAddress 4 or 7 bit Address of the LPUART node. - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ConfigNodeAddress(USART_TypeDef *LPUARTx, uint32_t AddressLen, uint32_t NodeAddress) -{ - MODIFY_REG(LPUARTx->CR2, USART_CR2_ADD | USART_CR2_ADDM7, - (uint32_t)(AddressLen | (NodeAddress << USART_CR2_ADD_Pos))); -} - -/** - * @brief Return 8 bit Address of the LPUART node as set in ADD field of CR2. - * @note If 4-bit Address Detection is selected in ADDM7, - * only 4bits (b3-b0) of returned value are relevant (b31-b4 are not relevant) - * If 7-bit Address Detection is selected in ADDM7, - * only 8bits (b7-b0) of returned value are relevant (b31-b8 are not relevant) - * @rmtoll CR2 ADD LL_LPUART_GetNodeAddress - * @param LPUARTx LPUART Instance - * @retval Address of the LPUART node (Value between Min_Data=0 and Max_Data=255) - */ -__STATIC_INLINE uint32_t LL_LPUART_GetNodeAddress(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_ADD) >> USART_CR2_ADD_Pos); -} - -/** - * @brief Return Length of Node Address used in Address Detection mode (7-bit or 4-bit) - * @rmtoll CR2 ADDM7 LL_LPUART_GetNodeAddressLen - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_ADDRESS_DETECT_4B - * @arg @ref LL_LPUART_ADDRESS_DETECT_7B - */ -__STATIC_INLINE uint32_t LL_LPUART_GetNodeAddressLen(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_ADDM7)); -} - -/** - * @brief Enable RTS HW Flow Control - * @rmtoll CR3 RTSE LL_LPUART_EnableRTSHWFlowCtrl - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableRTSHWFlowCtrl(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->CR3, USART_CR3_RTSE); -} - -/** - * @brief Disable RTS HW Flow Control - * @rmtoll CR3 RTSE LL_LPUART_DisableRTSHWFlowCtrl - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableRTSHWFlowCtrl(USART_TypeDef *LPUARTx) -{ - CLEAR_BIT(LPUARTx->CR3, USART_CR3_RTSE); -} - -/** - * @brief Enable CTS HW Flow Control - * @rmtoll CR3 CTSE LL_LPUART_EnableCTSHWFlowCtrl - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableCTSHWFlowCtrl(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->CR3, USART_CR3_CTSE); -} - -/** - * @brief Disable CTS HW Flow Control - * @rmtoll CR3 CTSE LL_LPUART_DisableCTSHWFlowCtrl - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableCTSHWFlowCtrl(USART_TypeDef *LPUARTx) -{ - CLEAR_BIT(LPUARTx->CR3, USART_CR3_CTSE); -} - -/** - * @brief Configure HW Flow Control mode (both CTS and RTS) - * @rmtoll CR3 RTSE LL_LPUART_SetHWFlowCtrl\n - * CR3 CTSE LL_LPUART_SetHWFlowCtrl - * @param LPUARTx LPUART Instance - * @param HardwareFlowControl This parameter can be one of the following values: - * @arg @ref LL_LPUART_HWCONTROL_NONE - * @arg @ref LL_LPUART_HWCONTROL_RTS - * @arg @ref LL_LPUART_HWCONTROL_CTS - * @arg @ref LL_LPUART_HWCONTROL_RTS_CTS - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetHWFlowCtrl(USART_TypeDef *LPUARTx, uint32_t HardwareFlowControl) -{ - MODIFY_REG(LPUARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE, HardwareFlowControl); -} - -/** - * @brief Return HW Flow Control configuration (both CTS and RTS) - * @rmtoll CR3 RTSE LL_LPUART_GetHWFlowCtrl\n - * CR3 CTSE LL_LPUART_GetHWFlowCtrl - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_HWCONTROL_NONE - * @arg @ref LL_LPUART_HWCONTROL_RTS - * @arg @ref LL_LPUART_HWCONTROL_CTS - * @arg @ref LL_LPUART_HWCONTROL_RTS_CTS - */ -__STATIC_INLINE uint32_t LL_LPUART_GetHWFlowCtrl(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE)); -} - -/** - * @brief Enable Overrun detection - * @rmtoll CR3 OVRDIS LL_LPUART_EnableOverrunDetect - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableOverrunDetect(USART_TypeDef *LPUARTx) -{ - CLEAR_BIT(LPUARTx->CR3, USART_CR3_OVRDIS); -} - -/** - * @brief Disable Overrun detection - * @rmtoll CR3 OVRDIS LL_LPUART_DisableOverrunDetect - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableOverrunDetect(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->CR3, USART_CR3_OVRDIS); -} - -/** - * @brief Indicate if Overrun detection is enabled - * @rmtoll CR3 OVRDIS LL_LPUART_IsEnabledOverrunDetect - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledOverrunDetect(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_OVRDIS) != USART_CR3_OVRDIS) ? 1UL : 0UL); -} - -/** - * @brief Select event type for Wake UP Interrupt Flag (WUS[1:0] bits) - * @rmtoll CR3 WUS LL_LPUART_SetWKUPType - * @param LPUARTx LPUART Instance - * @param Type This parameter can be one of the following values: - * @arg @ref LL_LPUART_WAKEUP_ON_ADDRESS - * @arg @ref LL_LPUART_WAKEUP_ON_STARTBIT - * @arg @ref LL_LPUART_WAKEUP_ON_RXNE - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetWKUPType(USART_TypeDef *LPUARTx, uint32_t Type) -{ - MODIFY_REG(LPUARTx->CR3, USART_CR3_WUS, Type); -} - -/** - * @brief Return event type for Wake UP Interrupt Flag (WUS[1:0] bits) - * @rmtoll CR3 WUS LL_LPUART_GetWKUPType - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_WAKEUP_ON_ADDRESS - * @arg @ref LL_LPUART_WAKEUP_ON_STARTBIT - * @arg @ref LL_LPUART_WAKEUP_ON_RXNE - */ -__STATIC_INLINE uint32_t LL_LPUART_GetWKUPType(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR3, USART_CR3_WUS)); -} - -/** - * @brief Configure LPUART BRR register for achieving expected Baud Rate value. - * - * @note Compute and set LPUARTDIV value in BRR Register (full BRR content) - * according to used Peripheral Clock and expected Baud Rate values - * @note Peripheral clock and Baud Rate values provided as function parameters should be valid - * (Baud rate value != 0). - * @note Provided that LPUARTx_BRR must be > = 0x300 and LPUART_BRR is 20-bit, - * a care should be taken when generating high baud rates using high PeriphClk - * values. PeriphClk must be in the range [3 x BaudRate, 4096 x BaudRate]. - * @rmtoll BRR BRR LL_LPUART_SetBaudRate - * @param LPUARTx LPUART Instance - * @param PeriphClk Peripheral Clock - @if USART_PRESC_PRESCALER - * @param PrescalerValue This parameter can be one of the following values: - * @arg @ref LL_LPUART_PRESCALER_DIV1 - * @arg @ref LL_LPUART_PRESCALER_DIV2 - * @arg @ref LL_LPUART_PRESCALER_DIV4 - * @arg @ref LL_LPUART_PRESCALER_DIV6 - * @arg @ref LL_LPUART_PRESCALER_DIV8 - * @arg @ref LL_LPUART_PRESCALER_DIV10 - * @arg @ref LL_LPUART_PRESCALER_DIV12 - * @arg @ref LL_LPUART_PRESCALER_DIV16 - * @arg @ref LL_LPUART_PRESCALER_DIV32 - * @arg @ref LL_LPUART_PRESCALER_DIV64 - * @arg @ref LL_LPUART_PRESCALER_DIV128 - * @arg @ref LL_LPUART_PRESCALER_DIV256 - @endif - * @param BaudRate Baud Rate - * @retval None - */ -#if defined(USART_PRESC_PRESCALER) -__STATIC_INLINE void LL_LPUART_SetBaudRate(USART_TypeDef *LPUARTx, uint32_t PeriphClk, uint32_t PrescalerValue, - uint32_t BaudRate) -#else -__STATIC_INLINE void LL_LPUART_SetBaudRate(USART_TypeDef *LPUARTx, uint32_t PeriphClk, uint32_t BaudRate) -#endif /* USART_PRESC_PRESCALER */ -{ -#if defined(USART_PRESC_PRESCALER) - if (BaudRate != 0U) - { - LPUARTx->BRR = __LL_LPUART_DIV(PeriphClk, PrescalerValue, BaudRate); - } -#else - if (BaudRate != 0U) - { - LPUARTx->BRR = __LL_LPUART_DIV(PeriphClk, BaudRate); - } -#endif /* USART_PRESC_PRESCALER */ -} - -/** - * @brief Return current Baud Rate value, according to LPUARTDIV present in BRR register - * (full BRR content), and to used Peripheral Clock values - * @note In case of non-initialized or invalid value stored in BRR register, value 0 will be returned. - * @rmtoll BRR BRR LL_LPUART_GetBaudRate - * @param LPUARTx LPUART Instance - * @param PeriphClk Peripheral Clock - @if USART_PRESC_PRESCALER - * @param PrescalerValue This parameter can be one of the following values: - * @arg @ref LL_LPUART_PRESCALER_DIV1 - * @arg @ref LL_LPUART_PRESCALER_DIV2 - * @arg @ref LL_LPUART_PRESCALER_DIV4 - * @arg @ref LL_LPUART_PRESCALER_DIV6 - * @arg @ref LL_LPUART_PRESCALER_DIV8 - * @arg @ref LL_LPUART_PRESCALER_DIV10 - * @arg @ref LL_LPUART_PRESCALER_DIV12 - * @arg @ref LL_LPUART_PRESCALER_DIV16 - * @arg @ref LL_LPUART_PRESCALER_DIV32 - * @arg @ref LL_LPUART_PRESCALER_DIV64 - * @arg @ref LL_LPUART_PRESCALER_DIV128 - * @arg @ref LL_LPUART_PRESCALER_DIV256 - @endif - * @retval Baud Rate - */ -#if defined(USART_PRESC_PRESCALER) -__STATIC_INLINE uint32_t LL_LPUART_GetBaudRate(const USART_TypeDef *LPUARTx, uint32_t PeriphClk, uint32_t PrescalerValue) -#else -__STATIC_INLINE uint32_t LL_LPUART_GetBaudRate(const USART_TypeDef *LPUARTx, uint32_t PeriphClk) -#endif /* USART_PRESC_PRESCALER */ -{ - uint32_t lpuartdiv; - uint32_t brrresult; -#if defined(USART_PRESC_PRESCALER) - uint32_t periphclkpresc = (uint32_t)(PeriphClk / (LPUART_PRESCALER_TAB[(uint16_t)PrescalerValue])); -#endif /* USART_PRESC_PRESCALER */ - - lpuartdiv = LPUARTx->BRR & LPUART_BRR_MASK; - - if (lpuartdiv >= LPUART_BRR_MIN_VALUE) - { -#if defined(USART_PRESC_PRESCALER) - brrresult = (uint32_t)(((uint64_t)(periphclkpresc) * LPUART_LPUARTDIV_FREQ_MUL) / lpuartdiv); -#else - brrresult = (uint32_t)(((uint64_t)(PeriphClk) * LPUART_LPUARTDIV_FREQ_MUL) / lpuartdiv); -#endif /* USART_PRESC_PRESCALER */ - } - else - { - brrresult = 0x0UL; - } - - return (brrresult); -} - -/** - * @} - */ - -/** @defgroup LPUART_LL_EF_Configuration_HalfDuplex Configuration functions related to Half Duplex feature - * @{ - */ - -/** - * @brief Enable Single Wire Half-Duplex mode - * @rmtoll CR3 HDSEL LL_LPUART_EnableHalfDuplex - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableHalfDuplex(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->CR3, USART_CR3_HDSEL); -} - -/** - * @brief Disable Single Wire Half-Duplex mode - * @rmtoll CR3 HDSEL LL_LPUART_DisableHalfDuplex - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableHalfDuplex(USART_TypeDef *LPUARTx) -{ - CLEAR_BIT(LPUARTx->CR3, USART_CR3_HDSEL); -} - -/** - * @brief Indicate if Single Wire Half-Duplex mode is enabled - * @rmtoll CR3 HDSEL LL_LPUART_IsEnabledHalfDuplex - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledHalfDuplex(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_HDSEL) == (USART_CR3_HDSEL)) ? 1UL : 0UL); -} - -/** - * @} - */ - -/** @defgroup LPUART_LL_EF_Configuration_DE Configuration functions related to Driver Enable feature - * @{ - */ - -/** - * @brief Set DEDT (Driver Enable De-Assertion Time), Time value expressed on 5 bits ([4:0] bits). - * @rmtoll CR1 DEDT LL_LPUART_SetDEDeassertionTime - * @param LPUARTx LPUART Instance - * @param Time Value between Min_Data=0 and Max_Data=31 - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetDEDeassertionTime(USART_TypeDef *LPUARTx, uint32_t Time) -{ - MODIFY_REG(LPUARTx->CR1, USART_CR1_DEDT, Time << USART_CR1_DEDT_Pos); -} - -/** - * @brief Return DEDT (Driver Enable De-Assertion Time) - * @rmtoll CR1 DEDT LL_LPUART_GetDEDeassertionTime - * @param LPUARTx LPUART Instance - * @retval Time value expressed on 5 bits ([4:0] bits) : c - */ -__STATIC_INLINE uint32_t LL_LPUART_GetDEDeassertionTime(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_DEDT) >> USART_CR1_DEDT_Pos); -} - -/** - * @brief Set DEAT (Driver Enable Assertion Time), Time value expressed on 5 bits ([4:0] bits). - * @rmtoll CR1 DEAT LL_LPUART_SetDEAssertionTime - * @param LPUARTx LPUART Instance - * @param Time Value between Min_Data=0 and Max_Data=31 - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetDEAssertionTime(USART_TypeDef *LPUARTx, uint32_t Time) -{ - MODIFY_REG(LPUARTx->CR1, USART_CR1_DEAT, Time << USART_CR1_DEAT_Pos); -} - -/** - * @brief Return DEAT (Driver Enable Assertion Time) - * @rmtoll CR1 DEAT LL_LPUART_GetDEAssertionTime - * @param LPUARTx LPUART Instance - * @retval Time value expressed on 5 bits ([4:0] bits) : Time Value between Min_Data=0 and Max_Data=31 - */ -__STATIC_INLINE uint32_t LL_LPUART_GetDEAssertionTime(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_DEAT) >> USART_CR1_DEAT_Pos); -} - -/** - * @brief Enable Driver Enable (DE) Mode - * @rmtoll CR3 DEM LL_LPUART_EnableDEMode - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableDEMode(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->CR3, USART_CR3_DEM); -} - -/** - * @brief Disable Driver Enable (DE) Mode - * @rmtoll CR3 DEM LL_LPUART_DisableDEMode - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableDEMode(USART_TypeDef *LPUARTx) -{ - CLEAR_BIT(LPUARTx->CR3, USART_CR3_DEM); -} - -/** - * @brief Indicate if Driver Enable (DE) Mode is enabled - * @rmtoll CR3 DEM LL_LPUART_IsEnabledDEMode - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledDEMode(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_DEM) == (USART_CR3_DEM)) ? 1UL : 0UL); -} - -/** - * @brief Select Driver Enable Polarity - * @rmtoll CR3 DEP LL_LPUART_SetDESignalPolarity - * @param LPUARTx LPUART Instance - * @param Polarity This parameter can be one of the following values: - * @arg @ref LL_LPUART_DE_POLARITY_HIGH - * @arg @ref LL_LPUART_DE_POLARITY_LOW - * @retval None - */ -__STATIC_INLINE void LL_LPUART_SetDESignalPolarity(USART_TypeDef *LPUARTx, uint32_t Polarity) -{ - MODIFY_REG(LPUARTx->CR3, USART_CR3_DEP, Polarity); -} - -/** - * @brief Return Driver Enable Polarity - * @rmtoll CR3 DEP LL_LPUART_GetDESignalPolarity - * @param LPUARTx LPUART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_LPUART_DE_POLARITY_HIGH - * @arg @ref LL_LPUART_DE_POLARITY_LOW - */ -__STATIC_INLINE uint32_t LL_LPUART_GetDESignalPolarity(const USART_TypeDef *LPUARTx) -{ - return (uint32_t)(READ_BIT(LPUARTx->CR3, USART_CR3_DEP)); -} - -/** - * @} - */ - -/** @defgroup LPUART_LL_EF_FLAG_Management FLAG_Management - * @{ - */ - -/** - * @brief Check if the LPUART Parity Error Flag is set or not - * @rmtoll ISR PE LL_LPUART_IsActiveFlag_PE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_PE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_PE) == (USART_ISR_PE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Framing Error Flag is set or not - * @rmtoll ISR FE LL_LPUART_IsActiveFlag_FE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_FE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_FE) == (USART_ISR_FE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Noise error detected Flag is set or not - * @rmtoll ISR NE LL_LPUART_IsActiveFlag_NE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_NE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_NE) == (USART_ISR_NE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART OverRun Error Flag is set or not - * @rmtoll ISR ORE LL_LPUART_IsActiveFlag_ORE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_ORE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_ORE) == (USART_ISR_ORE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART IDLE line detected Flag is set or not - * @rmtoll ISR IDLE LL_LPUART_IsActiveFlag_IDLE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_IDLE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_IDLE) == (USART_ISR_IDLE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_LPUART_IsActiveFlag_RXNE LL_LPUART_IsActiveFlag_RXNE_RXFNE - -/** - * @brief Check if the LPUART Read Data Register or LPUART RX FIFO Not Empty Flag is set or not - * @rmtoll ISR RXNE_RXFNE LL_LPUART_IsActiveFlag_RXNE_RXFNE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_RXNE_RXFNE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_RXNE_RXFNE) == (USART_ISR_RXNE_RXFNE)) ? 1UL : 0UL); -} -#else -/** - * @brief Check if the LPUART Read Data Register Not Empty Flag is set or not - * @rmtoll ISR RXNE LL_LPUART_IsActiveFlag_RXNE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_RXNE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_RXNE) == (USART_ISR_RXNE)) ? 1UL : 0UL); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Check if the LPUART Transmission Complete Flag is set or not - * @rmtoll ISR TC LL_LPUART_IsActiveFlag_TC - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TC(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_TC) == (USART_ISR_TC)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_LPUART_IsActiveFlag_TXE LL_LPUART_IsActiveFlag_TXE_TXFNF - -/** - * @brief Check if the LPUART Transmit Data Register Empty or LPUART TX FIFO Not Full Flag is set or not - * @rmtoll ISR TXE_TXFNF LL_LPUART_IsActiveFlag_TXE_TXFNF - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TXE_TXFNF(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_TXE_TXFNF) == (USART_ISR_TXE_TXFNF)) ? 1UL : 0UL); -} -#else -/** - * @brief Check if the LPUART Transmit Data Register Empty Flag is set or not - * @rmtoll ISR TXE LL_LPUART_IsActiveFlag_TXE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TXE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_TXE) == (USART_ISR_TXE)) ? 1UL : 0UL); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Check if the LPUART CTS interrupt Flag is set or not - * @rmtoll ISR CTSIF LL_LPUART_IsActiveFlag_nCTS - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_nCTS(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_CTSIF) == (USART_ISR_CTSIF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART CTS Flag is set or not - * @rmtoll ISR CTS LL_LPUART_IsActiveFlag_CTS - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_CTS(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_CTS) == (USART_ISR_CTS)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Busy Flag is set or not - * @rmtoll ISR BUSY LL_LPUART_IsActiveFlag_BUSY - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_BUSY(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_BUSY) == (USART_ISR_BUSY)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Character Match Flag is set or not - * @rmtoll ISR CMF LL_LPUART_IsActiveFlag_CM - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_CM(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_CMF) == (USART_ISR_CMF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Send Break Flag is set or not - * @rmtoll ISR SBKF LL_LPUART_IsActiveFlag_SBK - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_SBK(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_SBKF) == (USART_ISR_SBKF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Receive Wake Up from mute mode Flag is set or not - * @rmtoll ISR RWU LL_LPUART_IsActiveFlag_RWU - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_RWU(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_RWU) == (USART_ISR_RWU)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Wake Up from stop mode Flag is set or not - * @rmtoll ISR WUF LL_LPUART_IsActiveFlag_WKUP - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_WKUP(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_WUF) == (USART_ISR_WUF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Transmit Enable Acknowledge Flag is set or not - * @rmtoll ISR TEACK LL_LPUART_IsActiveFlag_TEACK - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TEACK(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_TEACK) == (USART_ISR_TEACK)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Receive Enable Acknowledge Flag is set or not - * @rmtoll ISR REACK LL_LPUART_IsActiveFlag_REACK - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_REACK(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_REACK) == (USART_ISR_REACK)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Check if the LPUART TX FIFO Empty Flag is set or not - * @rmtoll ISR TXFE LL_LPUART_IsActiveFlag_TXFE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TXFE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_TXFE) == (USART_ISR_TXFE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART RX FIFO Full Flag is set or not - * @rmtoll ISR RXFF LL_LPUART_IsActiveFlag_RXFF - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_RXFF(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_RXFF) == (USART_ISR_RXFF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART TX FIFO Threshold Flag is set or not - * @rmtoll ISR TXFT LL_LPUART_IsActiveFlag_TXFT - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TXFT(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_TXFT) == (USART_ISR_TXFT)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART RX FIFO Threshold Flag is set or not - * @rmtoll ISR RXFT LL_LPUART_IsActiveFlag_RXFT - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_RXFT(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->ISR, USART_ISR_RXFT) == (USART_ISR_RXFT)) ? 1UL : 0UL); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Clear Parity Error Flag - * @rmtoll ICR PECF LL_LPUART_ClearFlag_PE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ClearFlag_PE(USART_TypeDef *LPUARTx) -{ - WRITE_REG(LPUARTx->ICR, USART_ICR_PECF); -} - -/** - * @brief Clear Framing Error Flag - * @rmtoll ICR FECF LL_LPUART_ClearFlag_FE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ClearFlag_FE(USART_TypeDef *LPUARTx) -{ - WRITE_REG(LPUARTx->ICR, USART_ICR_FECF); -} - -/** - * @brief Clear Noise detected Flag - * @rmtoll ICR NECF LL_LPUART_ClearFlag_NE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ClearFlag_NE(USART_TypeDef *LPUARTx) -{ - WRITE_REG(LPUARTx->ICR, USART_ICR_NECF); -} - -/** - * @brief Clear OverRun Error Flag - * @rmtoll ICR ORECF LL_LPUART_ClearFlag_ORE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ClearFlag_ORE(USART_TypeDef *LPUARTx) -{ - WRITE_REG(LPUARTx->ICR, USART_ICR_ORECF); -} - -/** - * @brief Clear IDLE line detected Flag - * @rmtoll ICR IDLECF LL_LPUART_ClearFlag_IDLE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ClearFlag_IDLE(USART_TypeDef *LPUARTx) -{ - WRITE_REG(LPUARTx->ICR, USART_ICR_IDLECF); -} - -/** - * @brief Clear Transmission Complete Flag - * @rmtoll ICR TCCF LL_LPUART_ClearFlag_TC - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ClearFlag_TC(USART_TypeDef *LPUARTx) -{ - WRITE_REG(LPUARTx->ICR, USART_ICR_TCCF); -} - -/** - * @brief Clear CTS Interrupt Flag - * @rmtoll ICR CTSCF LL_LPUART_ClearFlag_nCTS - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ClearFlag_nCTS(USART_TypeDef *LPUARTx) -{ - WRITE_REG(LPUARTx->ICR, USART_ICR_CTSCF); -} - -/** - * @brief Clear Character Match Flag - * @rmtoll ICR CMCF LL_LPUART_ClearFlag_CM - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ClearFlag_CM(USART_TypeDef *LPUARTx) -{ - WRITE_REG(LPUARTx->ICR, USART_ICR_CMCF); -} - -/** - * @brief Clear Wake Up from stop mode Flag - * @rmtoll ICR WUCF LL_LPUART_ClearFlag_WKUP - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_ClearFlag_WKUP(USART_TypeDef *LPUARTx) -{ - WRITE_REG(LPUARTx->ICR, USART_ICR_WUCF); -} - -/** - * @} - */ - -/** @defgroup LPUART_LL_EF_IT_Management IT_Management - * @{ - */ - -/** - * @brief Enable IDLE Interrupt - * @rmtoll CR1 IDLEIE LL_LPUART_EnableIT_IDLE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_IDLE(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_IDLEIE); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_LPUART_EnableIT_RXNE LL_LPUART_EnableIT_RXNE_RXFNE - -/** - * @brief Enable RX Not Empty and RX FIFO Not Empty Interrupt - * @rmtoll CR1 RXNEIE_RXFNEIE LL_LPUART_EnableIT_RXNE_RXFNE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_RXNE_RXFNE(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_RXNEIE_RXFNEIE); -} -#else - -/** - * @brief Enable RX Not Empty Interrupt - * @rmtoll CR1 RXNEIE LL_LPUART_EnableIT_RXNE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_RXNE(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_RXNEIE); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Enable Transmission Complete Interrupt - * @rmtoll CR1 TCIE LL_LPUART_EnableIT_TC - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_TC(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_TCIE); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_LPUART_EnableIT_TXE LL_LPUART_EnableIT_TXE_TXFNF - -/** - * @brief Enable TX Empty and TX FIFO Not Full Interrupt - * @rmtoll CR1 TXEIE_TXFNFIE LL_LPUART_EnableIT_TXE_TXFNF - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_TXE_TXFNF(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_TXEIE_TXFNFIE); -} -#else - -/** - * @brief Enable TX Empty Interrupt - * @rmtoll CR1 TXEIE LL_LPUART_EnableIT_TXE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_TXE(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_TXEIE); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Enable Parity Error Interrupt - * @rmtoll CR1 PEIE LL_LPUART_EnableIT_PE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_PE(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_PEIE); -} - -/** - * @brief Enable Character Match Interrupt - * @rmtoll CR1 CMIE LL_LPUART_EnableIT_CM - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_CM(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_CMIE); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Enable TX FIFO Empty Interrupt - * @rmtoll CR1 TXFEIE LL_LPUART_EnableIT_TXFE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_TXFE(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_TXFEIE); -} - -/** - * @brief Enable RX FIFO Full Interrupt - * @rmtoll CR1 RXFFIE LL_LPUART_EnableIT_RXFF - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_RXFF(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_RXFFIE); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Enable Error Interrupt - * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing - * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the LPUARTx_ISR register). - * - 0: Interrupt is inhibited - * - 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the LPUARTx_ISR register. - * @rmtoll CR3 EIE LL_LPUART_EnableIT_ERROR - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_ERROR(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_EIE); -} - -/** - * @brief Enable CTS Interrupt - * @rmtoll CR3 CTSIE LL_LPUART_EnableIT_CTS - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_CTS(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_CTSIE); -} - -/** - * @brief Enable Wake Up from Stop Mode Interrupt - * @rmtoll CR3 WUFIE LL_LPUART_EnableIT_WKUP - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_WKUP(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_WUFIE); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Enable TX FIFO Threshold Interrupt - * @rmtoll CR3 TXFTIE LL_LPUART_EnableIT_TXFT - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_TXFT(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_TXFTIE); -} - -/** - * @brief Enable RX FIFO Threshold Interrupt - * @rmtoll CR3 RXFTIE LL_LPUART_EnableIT_RXFT - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableIT_RXFT(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_RXFTIE); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Disable IDLE Interrupt - * @rmtoll CR1 IDLEIE LL_LPUART_DisableIT_IDLE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_IDLE(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_IDLEIE); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_LPUART_DisableIT_RXNE LL_LPUART_DisableIT_RXNE_RXFNE - -/** - * @brief Disable RX Not Empty and RX FIFO Not Empty Interrupt - * @rmtoll CR1 RXNEIE_RXFNEIE LL_LPUART_DisableIT_RXNE_RXFNE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_RXNE_RXFNE(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_RXNEIE_RXFNEIE); -} -#else - -/** - * @brief Disable RX Not Empty Interrupt - * @rmtoll CR1 RXNEIE LL_LPUART_DisableIT_RXNE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_RXNE(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_RXNEIE); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Disable Transmission Complete Interrupt - * @rmtoll CR1 TCIE LL_LPUART_DisableIT_TC - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_TC(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_TCIE); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_LPUART_DisableIT_TXE LL_LPUART_DisableIT_TXE_TXFNF - -/** - * @brief Disable TX Empty and TX FIFO Not Full Interrupt - * @rmtoll CR1 TXEIE_TXFNFIE LL_LPUART_DisableIT_TXE_TXFNF - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_TXE_TXFNF(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_TXEIE_TXFNFIE); -} -#else - -/** - * @brief Disable TX Empty Interrupt - * @rmtoll CR1 TXEIE LL_LPUART_DisableIT_TXE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_TXE(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_TXEIE); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Disable Parity Error Interrupt - * @rmtoll CR1 PEIE LL_LPUART_DisableIT_PE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_PE(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_PEIE); -} - -/** - * @brief Disable Character Match Interrupt - * @rmtoll CR1 CMIE LL_LPUART_DisableIT_CM - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_CM(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_CMIE); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Disable TX FIFO Empty Interrupt - * @rmtoll CR1 TXFEIE LL_LPUART_DisableIT_TXFE - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_TXFE(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_TXFEIE); -} - -/** - * @brief Disable RX FIFO Full Interrupt - * @rmtoll CR1 RXFFIE LL_LPUART_DisableIT_RXFF - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_RXFF(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_RXFFIE); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Disable Error Interrupt - * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing - * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the LPUARTx_ISR register). - * - 0: Interrupt is inhibited - * - 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the LPUARTx_ISR register. - * @rmtoll CR3 EIE LL_LPUART_DisableIT_ERROR - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_ERROR(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_EIE); -} - -/** - * @brief Disable CTS Interrupt - * @rmtoll CR3 CTSIE LL_LPUART_DisableIT_CTS - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_CTS(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_CTSIE); -} - -/** - * @brief Disable Wake Up from Stop Mode Interrupt - * @rmtoll CR3 WUFIE LL_LPUART_DisableIT_WKUP - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_WKUP(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_WUFIE); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Disable TX FIFO Threshold Interrupt - * @rmtoll CR3 TXFTIE LL_LPUART_DisableIT_TXFT - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_TXFT(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_TXFTIE); -} - -/** - * @brief Disable RX FIFO Threshold Interrupt - * @rmtoll CR3 RXFTIE LL_LPUART_DisableIT_RXFT - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableIT_RXFT(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_RXFTIE); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Check if the LPUART IDLE Interrupt source is enabled or disabled. - * @rmtoll CR1 IDLEIE LL_LPUART_IsEnabledIT_IDLE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_IDLE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_IDLEIE) == (USART_CR1_IDLEIE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_LPUART_IsEnabledIT_RXNE LL_LPUART_IsEnabledIT_RXNE_RXFNE - -/** - * @brief Check if the LPUART RX Not Empty and LPUART RX FIFO Not Empty Interrupt is enabled or disabled. - * @rmtoll CR1 RXNEIE_RXFNEIE LL_LPUART_IsEnabledIT_RXNE_RXFNE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_RXNE_RXFNE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_RXNEIE_RXFNEIE) == (USART_CR1_RXNEIE_RXFNEIE)) ? 1UL : 0UL); -} -#else - -/** - * @brief Check if the LPUART RX Not Empty Interrupt is enabled or disabled. - * @rmtoll CR1 RXNEIE LL_LPUART_IsEnabledIT_RXNE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_RXNE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_RXNEIE) == (USART_CR1_RXNEIE)) ? 1UL : 0UL); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Check if the LPUART Transmission Complete Interrupt is enabled or disabled. - * @rmtoll CR1 TCIE LL_LPUART_IsEnabledIT_TC - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_TC(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_TCIE) == (USART_CR1_TCIE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_LPUART_IsEnabledIT_TXE LL_LPUART_IsEnabledIT_TXE_TXFNF - -/** - * @brief Check if the LPUART TX Empty and LPUART TX FIFO Not Full Interrupt is enabled or disabled - * @rmtoll CR1 TXEIE_TXFNFIE LL_LPUART_IsEnabledIT_TXE_TXFNF - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_TXE_TXFNF(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_TXEIE_TXFNFIE) == (USART_CR1_TXEIE_TXFNFIE)) ? 1UL : 0UL); -} -#else - -/** - * @brief Check if the LPUART TX Empty Interrupt is enabled or disabled. - * @rmtoll CR1 TXEIE LL_LPUART_IsEnabledIT_TXE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_TXE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_TXEIE) == (USART_CR1_TXEIE)) ? 1UL : 0UL); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Check if the LPUART Parity Error Interrupt is enabled or disabled. - * @rmtoll CR1 PEIE LL_LPUART_IsEnabledIT_PE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_PE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_PEIE) == (USART_CR1_PEIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Character Match Interrupt is enabled or disabled. - * @rmtoll CR1 CMIE LL_LPUART_IsEnabledIT_CM - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_CM(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_CMIE) == (USART_CR1_CMIE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Check if the LPUART TX FIFO Empty Interrupt is enabled or disabled - * @rmtoll CR1 TXFEIE LL_LPUART_IsEnabledIT_TXFE - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_TXFE(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_TXFEIE) == (USART_CR1_TXFEIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART RX FIFO Full Interrupt is enabled or disabled - * @rmtoll CR1 RXFFIE LL_LPUART_IsEnabledIT_RXFF - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_RXFF(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR1, USART_CR1_RXFFIE) == (USART_CR1_RXFFIE)) ? 1UL : 0UL); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Check if the LPUART Error Interrupt is enabled or disabled. - * @rmtoll CR3 EIE LL_LPUART_IsEnabledIT_ERROR - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_ERROR(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_EIE) == (USART_CR3_EIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART CTS Interrupt is enabled or disabled. - * @rmtoll CR3 CTSIE LL_LPUART_IsEnabledIT_CTS - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_CTS(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_CTSIE) == (USART_CR3_CTSIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the LPUART Wake Up from Stop Mode Interrupt is enabled or disabled. - * @rmtoll CR3 WUFIE LL_LPUART_IsEnabledIT_WKUP - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_WKUP(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_WUFIE) == (USART_CR3_WUFIE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Check if LPUART TX FIFO Threshold Interrupt is enabled or disabled - * @rmtoll CR3 TXFTIE LL_LPUART_IsEnabledIT_TXFT - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_TXFT(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_TXFTIE) == (USART_CR3_TXFTIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if LPUART RX FIFO Threshold Interrupt is enabled or disabled - * @rmtoll CR3 RXFTIE LL_LPUART_IsEnabledIT_RXFT - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_RXFT(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_RXFTIE) == (USART_CR3_RXFTIE)) ? 1UL : 0UL); -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @} - */ - -/** @defgroup LPUART_LL_EF_DMA_Management DMA_Management - * @{ - */ - -/** - * @brief Enable DMA Mode for reception - * @rmtoll CR3 DMAR LL_LPUART_EnableDMAReq_RX - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableDMAReq_RX(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_DMAR); -} - -/** - * @brief Disable DMA Mode for reception - * @rmtoll CR3 DMAR LL_LPUART_DisableDMAReq_RX - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableDMAReq_RX(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_DMAR); -} - -/** - * @brief Check if DMA Mode is enabled for reception - * @rmtoll CR3 DMAR LL_LPUART_IsEnabledDMAReq_RX - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledDMAReq_RX(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_DMAR) == (USART_CR3_DMAR)) ? 1UL : 0UL); -} - -/** - * @brief Enable DMA Mode for transmission - * @rmtoll CR3 DMAT LL_LPUART_EnableDMAReq_TX - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableDMAReq_TX(USART_TypeDef *LPUARTx) -{ - ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_DMAT); -} - -/** - * @brief Disable DMA Mode for transmission - * @rmtoll CR3 DMAT LL_LPUART_DisableDMAReq_TX - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableDMAReq_TX(USART_TypeDef *LPUARTx) -{ - ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_DMAT); -} - -/** - * @brief Check if DMA Mode is enabled for transmission - * @rmtoll CR3 DMAT LL_LPUART_IsEnabledDMAReq_TX - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledDMAReq_TX(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_DMAT) == (USART_CR3_DMAT)) ? 1UL : 0UL); -} - -/** - * @brief Enable DMA Disabling on Reception Error - * @rmtoll CR3 DDRE LL_LPUART_EnableDMADeactOnRxErr - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_EnableDMADeactOnRxErr(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->CR3, USART_CR3_DDRE); -} - -/** - * @brief Disable DMA Disabling on Reception Error - * @rmtoll CR3 DDRE LL_LPUART_DisableDMADeactOnRxErr - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_DisableDMADeactOnRxErr(USART_TypeDef *LPUARTx) -{ - CLEAR_BIT(LPUARTx->CR3, USART_CR3_DDRE); -} - -/** - * @brief Indicate if DMA Disabling on Reception Error is disabled - * @rmtoll CR3 DDRE LL_LPUART_IsEnabledDMADeactOnRxErr - * @param LPUARTx LPUART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_LPUART_IsEnabledDMADeactOnRxErr(const USART_TypeDef *LPUARTx) -{ - return ((READ_BIT(LPUARTx->CR3, USART_CR3_DDRE) == (USART_CR3_DDRE)) ? 1UL : 0UL); -} - -/** - * @brief Get the LPUART data register address used for DMA transfer - * @rmtoll RDR RDR LL_LPUART_DMA_GetRegAddr\n - * @rmtoll TDR TDR LL_LPUART_DMA_GetRegAddr - * @param LPUARTx LPUART Instance - * @param Direction This parameter can be one of the following values: - * @arg @ref LL_LPUART_DMA_REG_DATA_TRANSMIT - * @arg @ref LL_LPUART_DMA_REG_DATA_RECEIVE - * @retval Address of data register - */ -__STATIC_INLINE uint32_t LL_LPUART_DMA_GetRegAddr(const USART_TypeDef *LPUARTx, uint32_t Direction) -{ - uint32_t data_reg_addr; - - if (Direction == LL_LPUART_DMA_REG_DATA_TRANSMIT) - { - /* return address of TDR register */ - data_reg_addr = (uint32_t) &(LPUARTx->TDR); - } - else - { - /* return address of RDR register */ - data_reg_addr = (uint32_t) &(LPUARTx->RDR); - } - - return data_reg_addr; -} - -/** - * @} - */ - -/** @defgroup LPUART_LL_EF_Data_Management Data_Management - * @{ - */ - -/** - * @brief Read Receiver Data register (Receive Data value, 8 bits) - * @rmtoll RDR RDR LL_LPUART_ReceiveData8 - * @param LPUARTx LPUART Instance - * @retval Time Value between Min_Data=0x00 and Max_Data=0xFF - */ -__STATIC_INLINE uint8_t LL_LPUART_ReceiveData8(const USART_TypeDef *LPUARTx) -{ - return (uint8_t)(READ_BIT(LPUARTx->RDR, USART_RDR_RDR) & 0xFFU); -} - -/** - * @brief Read Receiver Data register (Receive Data value, 9 bits) - * @rmtoll RDR RDR LL_LPUART_ReceiveData9 - * @param LPUARTx LPUART Instance - * @retval Time Value between Min_Data=0x00 and Max_Data=0x1FF - */ -__STATIC_INLINE uint16_t LL_LPUART_ReceiveData9(const USART_TypeDef *LPUARTx) -{ - return (uint16_t)(READ_BIT(LPUARTx->RDR, USART_RDR_RDR)); -} - -/** - * @brief Write in Transmitter Data Register (Transmit Data value, 8 bits) - * @rmtoll TDR TDR LL_LPUART_TransmitData8 - * @param LPUARTx LPUART Instance - * @param Value between Min_Data=0x00 and Max_Data=0xFF - * @retval None - */ -__STATIC_INLINE void LL_LPUART_TransmitData8(USART_TypeDef *LPUARTx, uint8_t Value) -{ - LPUARTx->TDR = Value; -} - -/** - * @brief Write in Transmitter Data Register (Transmit Data value, 9 bits) - * @rmtoll TDR TDR LL_LPUART_TransmitData9 - * @param LPUARTx LPUART Instance - * @param Value between Min_Data=0x00 and Max_Data=0x1FF - * @retval None - */ -__STATIC_INLINE void LL_LPUART_TransmitData9(USART_TypeDef *LPUARTx, uint16_t Value) -{ - LPUARTx->TDR = Value & 0x1FFUL; -} - -/** - * @} - */ - -/** @defgroup LPUART_LL_EF_Execution Execution - * @{ - */ - -/** - * @brief Request Break sending - * @rmtoll RQR SBKRQ LL_LPUART_RequestBreakSending - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_RequestBreakSending(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->RQR, (uint16_t)USART_RQR_SBKRQ); -} - -/** - * @brief Put LPUART in mute mode and set the RWU flag - * @rmtoll RQR MMRQ LL_LPUART_RequestEnterMuteMode - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_RequestEnterMuteMode(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->RQR, (uint16_t)USART_RQR_MMRQ); -} - -/** - @if USART_CR1_FIFOEN - * @brief Request a Receive Data and FIFO flush - * @note Allows to discard the received data without reading them, and avoid an overrun - * condition. - @else - * @brief Request a Receive Data flush - @endif - * @rmtoll RQR RXFRQ LL_LPUART_RequestRxDataFlush - * @param LPUARTx LPUART Instance - * @retval None - */ -__STATIC_INLINE void LL_LPUART_RequestRxDataFlush(USART_TypeDef *LPUARTx) -{ - SET_BIT(LPUARTx->RQR, (uint16_t)USART_RQR_RXFRQ); -} - -/** - * @} - */ - -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup LPUART_LL_EF_Init Initialization and de-initialization functions - * @{ - */ -ErrorStatus LL_LPUART_DeInit(const USART_TypeDef *LPUARTx); -ErrorStatus LL_LPUART_Init(USART_TypeDef *LPUARTx, const LL_LPUART_InitTypeDef *LPUART_InitStruct); -void LL_LPUART_StructInit(LL_LPUART_InitTypeDef *LPUART_InitStruct); -/** - * @} - */ -#endif /* USE_FULL_LL_DRIVER */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /* LPUART1 */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* STM32L4xx_LL_LPUART_H */ - diff --git a/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_tim.h b/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_tim.h new file mode 100644 index 0000000..868c26e --- /dev/null +++ b/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_tim.h @@ -0,0 +1,5092 @@ +/** + ****************************************************************************** + * @file stm32l4xx_ll_tim.h + * @author MCD Application Team + * @brief Header file of TIM LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L4xx_LL_TIM_H +#define __STM32L4xx_LL_TIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx.h" + +/** @addtogroup STM32L4xx_LL_Driver + * @{ + */ + +#if defined (TIM1) || defined (TIM8) || defined (TIM2) || defined (TIM3) || defined (TIM4) || defined (TIM5) || defined (TIM15) || defined (TIM16) || defined (TIM17) || 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: TIMx_CH1N */ + 0x00U, /* 2: TIMx_CH2 */ + 0x00U, /* 3: TIMx_CH2N */ + 0x04U, /* 4: TIMx_CH3 */ + 0x04U, /* 5: TIMx_CH3N */ + 0x04U, /* 6: TIMx_CH4 */ + 0x3CU, /* 7: TIMx_CH5 */ + 0x3CU /* 8: TIMx_CH6 */ +}; + +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 */ + 0U, /* 7: OC5M, OC5FE, OC5PE */ + 8U /* 8: OC6M, OC6FE, OC6PE */ +}; + +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 */ + 0U, /* 7: - NA */ + 0U /* 8: - NA */ +}; + +static const uint8_t SHIFT_TAB_CCxP[] = +{ + 0U, /* 0: CC1P */ + 2U, /* 1: CC1NP */ + 4U, /* 2: CC2P */ + 6U, /* 3: CC2NP */ + 8U, /* 4: CC3P */ + 10U, /* 5: CC3NP */ + 12U, /* 6: CC4P */ + 16U, /* 7: CC5P */ + 20U /* 8: CC6P */ +}; + +static const uint8_t SHIFT_TAB_OISx[] = +{ + 0U, /* 0: OIS1 */ + 1U, /* 1: OIS1N */ + 2U, /* 2: OIS2 */ + 3U, /* 3: OIS2N */ + 4U, /* 4: OIS3 */ + 5U, /* 5: OIS3N */ + 6U, /* 6: OIS4 */ + 8U, /* 7: OIS5 */ + 10U /* 8: OIS6 */ +}; +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Constants TIM Private Constants + * @{ + */ + +/* Defines used for the bit position in the register and perform offsets */ +#define TIM_POSITION_BRK_SOURCE (POSITION_VAL(Source) & 0x1FUL) + +/* Generic bit definitions for TIMx_OR2 register */ +#define TIMx_OR2_BKINP TIM1_OR2_BKINP /*!< BRK BKIN input polarity */ +#define TIMx_OR2_ETRSEL TIM1_OR2_ETRSEL /*!< TIMx ETR source selection */ + +/* Remap mask definitions */ +#define TIMx_OR1_RMP_SHIFT 16U +#define TIMx_OR1_RMP_MASK 0x0000FFFFU +#if defined(ADC3) +#define TIM1_OR1_RMP_MASK ((TIM1_OR1_ETR_ADC1_RMP | TIM1_OR1_ETR_ADC3_RMP | TIM1_OR1_TI1_RMP) << TIMx_OR1_RMP_SHIFT) +#else +#define TIM1_OR1_RMP_MASK ((TIM1_OR1_ETR_ADC1_RMP | TIM1_OR1_TI1_RMP) << TIMx_OR1_RMP_SHIFT) +#endif /* ADC3 */ +#define TIM2_OR1_RMP_MASK ((TIM2_OR1_TI4_RMP | TIM2_OR1_ETR1_RMP | TIM2_OR1_ITR1_RMP) << TIMx_OR1_RMP_SHIFT) +#define TIM3_OR1_RMP_MASK (TIM3_OR1_TI1_RMP << TIMx_OR1_RMP_SHIFT) +#if defined(ADC2) && defined(ADC3) +#define TIM8_OR1_RMP_MASK ((TIM8_OR1_ETR_ADC2_RMP | TIM8_OR1_ETR_ADC3_RMP | TIM8_OR1_TI1_RMP) << TIMx_OR1_RMP_SHIFT) +#else +#define TIM8_OR1_RMP_MASK (TIM8_OR1_TI1_RMP << TIMx_OR1_RMP_SHIFT) +#endif /* ADC2 & ADC3 */ +#define TIM15_OR1_RMP_MASK (TIM15_OR1_TI1_RMP << TIMx_OR1_RMP_SHIFT) +#define TIM16_OR1_RMP_MASK (TIM16_OR1_TI1_RMP << TIMx_OR1_RMP_SHIFT) +#define TIM17_OR1_RMP_MASK (TIM17_OR1_TI1_RMP << TIMx_OR1_RMP_SHIFT) + +/* Mask used to set the TDG[x:0] of the DTG bits of the TIMx_BDTR register */ +#define DT_DELAY_1 ((uint8_t)0x7F) +#define DT_DELAY_2 ((uint8_t)0x3F) +#define DT_DELAY_3 ((uint8_t)0x1F) +#define DT_DELAY_4 ((uint8_t)0x1F) + +/* Mask used to set the DTG[7:5] bits of the DTG bits of the TIMx_BDTR register */ +#define DT_RANGE_1 ((uint8_t)0x00) +#define DT_RANGE_2 ((uint8_t)0x80) +#define DT_RANGE_3 ((uint8_t)0xC0) +#define DT_RANGE_4 ((uint8_t)0xE0) + +/** Legacy definitions for compatibility purpose +@cond 0 + */ +#if defined(DFSDM1_Channel0) +#define TIMx_OR2_BKDFBK0E TIMx_OR2_BKDF1BK0E +#define TIMx_OR3_BK2DFBK1E TIMx_OR3_BK2DF1BK1E +#endif /* DFSDM1_Channel0 */ +/** +@endcond + */ + +/** + * @} + */ + +/* 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_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval none + */ +#define TIM_GET_CHANNEL_INDEX( __CHANNEL__) \ + (((__CHANNEL__) == LL_TIM_CHANNEL_CH1) ? 0U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH1N) ? 1U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH2) ? 2U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH2N) ? 3U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH3) ? 4U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH3N) ? 5U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH4) ? 6U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH5) ? 7U : 8U) + +/** @brief Calculate the deadtime sampling period(in ps). + * @param __TIMCLK__ timer input clock frequency (in Hz). + * @param __CKD__ 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 + */ +#define TIM_CALC_DTS(__TIMCLK__, __CKD__) \ + (((__CKD__) == LL_TIM_CLOCKDIVISION_DIV1) ? ((uint64_t)1000000000000U/(__TIMCLK__)) : \ + ((__CKD__) == LL_TIM_CLOCKDIVISION_DIV2) ? ((uint64_t)1000000000000U/((__TIMCLK__) >> 1U)) : \ + ((uint64_t)1000000000000U/((__TIMCLK__) >> 2U))) +/** + * @} + */ + + +/* 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().*/ + + uint32_t RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter + reaches zero, an update event is generated and counting restarts + from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned mode + GP timers: this parameter must be a number between Min_Data = 0x00 and + Max_Data = 0xFF. + Advanced timers: this parameter must be a number between Min_Data = 0x0000 and + Max_Data = 0xFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetRepetitionCounter().*/ +} 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 OCNState; /*!< Specifies the TIM complementary 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().*/ + + uint32_t OCNPolarity; /*!< Specifies the complementary 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().*/ + + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_LL_EC_OCIDLESTATE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetIdleState().*/ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_LL_EC_OCIDLESTATE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetIdleState().*/ +} 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; + +/** + * @brief TIM Hall sensor interface configuration structure definition. + */ +typedef struct +{ + + 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 IC1Prescaler; /*!< Specifies the TI1 input prescaler value. + Prescaler must be set to get a maximum counter period longer than the + time interval between 2 consecutive changes on the Hall inputs. + 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 CommutationDelay; /*!< Specifies the compare value to be loaded into the Capture Compare Register. + A positive pulse (TRGO event) is generated with a programmable delay every time + a change occurs on the Hall inputs. + 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_OC_SetCompareCH2().*/ +} LL_TIM_HALLSENSOR_InitTypeDef; + +/** + * @brief BDTR (Break and Dead Time) structure definition + */ +typedef struct +{ + uint32_t OSSRState; /*!< Specifies the Off-State selection used in Run mode. + This parameter can be a value of @ref TIM_LL_EC_OSSR + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetOffStates() + + @note This bit-field cannot be modified as long as LOCK level 2 has been + programmed. */ + + uint32_t OSSIState; /*!< Specifies the Off-State used in Idle state. + This parameter can be a value of @ref TIM_LL_EC_OSSI + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetOffStates() + + @note This bit-field cannot be modified as long as LOCK level 2 has been + programmed. */ + + uint32_t LockLevel; /*!< Specifies the LOCK level parameters. + This parameter can be a value of @ref TIM_LL_EC_LOCKLEVEL + + @note The LOCK bits can be written only once after the reset. Once the TIMx_BDTR + register has been written, their content is frozen until the next reset.*/ + + uint8_t DeadTime; /*!< Specifies the delay time between the switching-off and the + switching-on of the outputs. + This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetDeadTime() + + @note This bit-field can not be modified as long as LOCK level 1, 2 or 3 has been + programmed. */ + + uint16_t BreakState; /*!< Specifies whether the TIM Break input is enabled or not. + This parameter can be a value of @ref TIM_LL_EC_BREAK_ENABLE + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_EnableBRK() or @ref LL_TIM_DisableBRK() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. + This parameter can be a value of @ref TIM_LL_EC_BREAK_POLARITY + + This feature can be modified afterwards using unitary function + @ref LL_TIM_ConfigBRK() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t BreakFilter; /*!< Specifies the TIM Break Filter. + This parameter can be a value of @ref TIM_LL_EC_BREAK_FILTER + + This feature can be modified afterwards using unitary function + @ref LL_TIM_ConfigBRK() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t Break2State; /*!< Specifies whether the TIM Break2 input is enabled or not. + This parameter can be a value of @ref TIM_LL_EC_BREAK2_ENABLE + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_EnableBRK2() or @ref LL_TIM_DisableBRK2() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t Break2Polarity; /*!< Specifies the TIM Break2 Input pin polarity. + This parameter can be a value of @ref TIM_LL_EC_BREAK2_POLARITY + + This feature can be modified afterwards using unitary function + @ref LL_TIM_ConfigBRK2() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t Break2Filter; /*!< Specifies the TIM Break2 Filter. + This parameter can be a value of @ref TIM_LL_EC_BREAK2_FILTER + + This feature can be modified afterwards using unitary function + @ref LL_TIM_ConfigBRK2() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. + This parameter can be a value of @ref TIM_LL_EC_AUTOMATICOUTPUT_ENABLE + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_EnableAutomaticOutput() or @ref LL_TIM_DisableAutomaticOutput() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ +} LL_TIM_BDTR_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_CC5IF TIM_SR_CC5IF /*!< Capture/compare 5 interrupt flag */ +#define LL_TIM_SR_CC6IF TIM_SR_CC6IF /*!< Capture/compare 6 interrupt flag */ +#define LL_TIM_SR_COMIF TIM_SR_COMIF /*!< COM interrupt flag */ +#define LL_TIM_SR_TIF TIM_SR_TIF /*!< Trigger interrupt flag */ +#define LL_TIM_SR_BIF TIM_SR_BIF /*!< Break interrupt flag */ +#define LL_TIM_SR_B2IF TIM_SR_B2IF /*!< Second break 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 */ +#define LL_TIM_SR_SBIF TIM_SR_SBIF /*!< System Break interrupt flag */ +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_EC_BREAK_ENABLE Break Enable + * @{ + */ +#define LL_TIM_BREAK_DISABLE 0x00000000U /*!< Break function disabled */ +#define LL_TIM_BREAK_ENABLE TIM_BDTR_BKE /*!< Break function enabled */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_BREAK2_ENABLE Break2 Enable + * @{ + */ +#define LL_TIM_BREAK2_DISABLE 0x00000000U /*!< Break2 function disabled */ +#define LL_TIM_BREAK2_ENABLE TIM_BDTR_BK2E /*!< Break2 function enabled */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_AUTOMATICOUTPUT_ENABLE Automatic output enable + * @{ + */ +#define LL_TIM_AUTOMATICOUTPUT_DISABLE 0x00000000U /*!< MOE can be set only by software */ +#define LL_TIM_AUTOMATICOUTPUT_ENABLE TIM_BDTR_AOE /*!< MOE can be set by software or automatically at the next update event */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** @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_COMIE TIM_DIER_COMIE /*!< COM interrupt enable */ +#define LL_TIM_DIER_TIE TIM_DIER_TIE /*!< Trigger interrupt enable */ +#define LL_TIM_DIER_BIE TIM_DIER_BIE /*!< Break 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 stops counting at the next update event */ +#define LL_TIM_ONEPULSEMODE_REPETITIVE 0x00000000U /*!< Counter is not stopped at 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*/ +#define LL_TIM_OCMODE_RETRIG_OPM1 TIM_CCMR1_OC1M_3 /*!__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 retrieving the UIFCPY flag from the counter value. + * @note ex: @ref __LL_TIM_GETFLAG_UIFCPY (@ref LL_TIM_GetCounter ()); + * @note Relevant only if UIF flag remapping has been enabled (UIF status bit is copied + * to TIMx_CNT register bit 31) + * @param __CNT__ Counter value + * @retval UIF status bit + */ +#define __LL_TIM_GETFLAG_UIFCPY(__CNT__) \ + (READ_BIT((__CNT__), TIM_CNT_UIFCPY) >> TIM_CNT_UIFCPY_Pos) + +/** + * @brief HELPER macro calculating DTG[0:7] in the TIMx_BDTR register to achieve the requested dead time duration. + * @note ex: @ref __LL_TIM_CALC_DEADTIME (80000000, @ref LL_TIM_GetClockDivision (), 120); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __CKD__ 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 + * @param __DT__ deadtime duration (in ns) + * @retval DTG[0:7] + */ +#define __LL_TIM_CALC_DEADTIME(__TIMCLK__, __CKD__, __DT__) \ + ( (((uint64_t)((__DT__)*1000U)) < ((DT_DELAY_1+1U) * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(((uint64_t)((__DT__)*1000U) / TIM_CALC_DTS((__TIMCLK__), (__CKD__))) & DT_DELAY_1) : \ + (((uint64_t)((__DT__)*1000U)) < ((64U + (DT_DELAY_2+1U)) * 2U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(DT_RANGE_2 | ((uint8_t)((uint8_t)((((uint64_t)((__DT__)*1000U))/ TIM_CALC_DTS((__TIMCLK__), \ + (__CKD__))) >> 1U) - (uint8_t) 64) & DT_DELAY_2)) :\ + (((uint64_t)((__DT__)*1000U)) < ((32U + (DT_DELAY_3+1U)) * 8U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(DT_RANGE_3 | ((uint8_t)((uint8_t)(((((uint64_t)(__DT__)*1000U))/ TIM_CALC_DTS((__TIMCLK__), \ + (__CKD__))) >> 3U) - (uint8_t) 32) & DT_DELAY_3)) :\ + (((uint64_t)((__DT__)*1000U)) < ((32U + (DT_DELAY_4+1U)) * 16U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(DT_RANGE_4 | ((uint8_t)((uint8_t)(((((uint64_t)(__DT__)*1000U))/ TIM_CALC_DTS((__TIMCLK__), \ + (__CKD__))) >> 4U) - (uint8_t) 32) & DT_DELAY_4)) :\ + 0U) + +/** + * @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__)/2U)/(__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(const 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(const 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(const 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(const 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(const 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(const 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(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_CKD)); +} + +/** + * @brief Set the counter value. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @rmtoll CNT CNT LL_TIM_SetCounter + * @param TIMx Timer instance + * @param Counter Counter value (between Min_Data=0 and Max_Data=0xFFFF or 0xFFFFFFFF) + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetCounter(TIM_TypeDef *TIMx, uint32_t Counter) +{ + WRITE_REG(TIMx->CNT, Counter); +} + +/** + * @brief Get the counter value. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @rmtoll CNT CNT LL_TIM_GetCounter + * @param TIMx Timer instance + * @retval Counter value (between Min_Data=0 and Max_Data=0xFFFF or 0xFFFFFFFF) + */ +__STATIC_INLINE uint32_t LL_TIM_GetCounter(const 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(const 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(const 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 Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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 + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @param TIMx Timer instance + * @retval Auto-reload value + */ +__STATIC_INLINE uint32_t LL_TIM_GetAutoReload(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->ARR)); +} + +/** + * @brief Set the repetition counter value. + * @note For advanced timer instances RepetitionCounter can be up to 65535. + * @note Macro IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a repetition counter. + * @rmtoll RCR REP LL_TIM_SetRepetitionCounter + * @param TIMx Timer instance + * @param RepetitionCounter between Min_Data=0 and Max_Data=255 or 65535 for advanced timer. + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetRepetitionCounter(TIM_TypeDef *TIMx, uint32_t RepetitionCounter) +{ + WRITE_REG(TIMx->RCR, RepetitionCounter); +} + +/** + * @brief Get the repetition counter value. + * @note Macro IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a repetition counter. + * @rmtoll RCR REP LL_TIM_GetRepetitionCounter + * @param TIMx Timer instance + * @retval Repetition counter value + */ +__STATIC_INLINE uint32_t LL_TIM_GetRepetitionCounter(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->RCR)); +} + +/** + * @brief Force a continuous copy of the update interrupt flag (UIF) into the timer counter register (bit 31). + * @note This allows both the counter value and a potential roll-over condition signalled by the UIFCPY flag to be read + * in an atomic way. + * @rmtoll CR1 UIFREMAP LL_TIM_EnableUIFRemap + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableUIFRemap(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_UIFREMAP); +} + +/** + * @brief Disable update interrupt flag (UIF) remapping. + * @rmtoll CR1 UIFREMAP LL_TIM_DisableUIFRemap + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableUIFRemap(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_UIFREMAP); +} + +/** + * @brief Indicate whether update interrupt flag (UIF) copy is set. + * @param Counter Counter value + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveUIFCPY(const uint32_t Counter) +{ + return (((Counter & TIM_CNT_UIFCPY) == (TIM_CNT_UIFCPY)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Capture_Compare Capture Compare configuration + * @{ + */ +/** + * @brief Enable the capture/compare control bits (CCxE, CCxNE and OCxM) preload. + * @note CCxE, CCxNE and OCxM bits are preloaded, after having been written, + * they are updated only when a commutation event (COM) occurs. + * @note Only on channels that have a complementary output. + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCPC LL_TIM_CC_EnablePreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_EnablePreload(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR2, TIM_CR2_CCPC); +} + +/** + * @brief Disable the capture/compare control bits (CCxE, CCxNE and OCxM) preload. + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCPC LL_TIM_CC_DisablePreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_DisablePreload(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR2, TIM_CR2_CCPC); +} + +/** + * @brief Set the updated source of the capture/compare control bits (CCxE, CCxNE and OCxM). + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCUS LL_TIM_CC_SetUpdate + * @param TIMx Timer instance + * @param CCUpdateSource This parameter can be one of the following values: + * @arg @ref LL_TIM_CCUPDATESOURCE_COMG_ONLY + * @arg @ref LL_TIM_CCUPDATESOURCE_COMG_AND_TRGI + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_SetUpdate(TIM_TypeDef *TIMx, uint32_t CCUpdateSource) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_CCUS, CCUpdateSource); +} + +/** + * @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(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR2, TIM_CR2_CCDS)); +} + +/** + * @brief Set the lock level to freeze the + * configuration of several capture/compare parameters. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * the lock mechanism is supported by a timer instance. + * @rmtoll BDTR LOCK LL_TIM_CC_SetLockLevel + * @param TIMx Timer instance + * @param LockLevel This parameter can be one of the following values: + * @arg @ref LL_TIM_LOCKLEVEL_OFF + * @arg @ref LL_TIM_LOCKLEVEL_1 + * @arg @ref LL_TIM_LOCKLEVEL_2 + * @arg @ref LL_TIM_LOCKLEVEL_3 + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_SetLockLevel(TIM_TypeDef *TIMx, uint32_t LockLevel) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_LOCK, LockLevel); +} + +/** + * @brief Enable capture/compare channels. + * @rmtoll CCER CC1E LL_TIM_CC_EnableChannel\n + * CCER CC1NE LL_TIM_CC_EnableChannel\n + * CCER CC2E LL_TIM_CC_EnableChannel\n + * CCER CC2NE LL_TIM_CC_EnableChannel\n + * CCER CC3E LL_TIM_CC_EnableChannel\n + * CCER CC3NE LL_TIM_CC_EnableChannel\n + * CCER CC4E LL_TIM_CC_EnableChannel\n + * CCER CC5E LL_TIM_CC_EnableChannel\n + * CCER CC6E 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_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 CC1NE LL_TIM_CC_DisableChannel\n + * CCER CC2E LL_TIM_CC_DisableChannel\n + * CCER CC2NE LL_TIM_CC_DisableChannel\n + * CCER CC3E LL_TIM_CC_DisableChannel\n + * CCER CC3NE LL_TIM_CC_DisableChannel\n + * CCER CC4E LL_TIM_CC_DisableChannel\n + * CCER CC5E LL_TIM_CC_DisableChannel\n + * CCER CC6E 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_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 CC1NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC2E LL_TIM_CC_IsEnabledChannel\n + * CCER CC2NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC3E LL_TIM_CC_IsEnabledChannel\n + * CCER CC3NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC4E LL_TIM_CC_IsEnabledChannel\n + * CCER CC5E LL_TIM_CC_IsEnabledChannel\n + * CCER CC6E 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_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 + * CCMR3 CC5S LL_TIM_OC_ConfigOutput\n + * CCMR3 CC6S 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 + * CCER CC5P LL_TIM_OC_ConfigOutput\n + * CCER CC6P LL_TIM_OC_ConfigOutput\n + * CR2 OIS1 LL_TIM_OC_ConfigOutput\n + * CR2 OIS2 LL_TIM_OC_ConfigOutput\n + * CR2 OIS3 LL_TIM_OC_ConfigOutput\n + * CR2 OIS4 LL_TIM_OC_ConfigOutput\n + * CR2 OIS5 LL_TIM_OC_ConfigOutput\n + * CR2 OIS6 LL_TIM_OC_ConfigOutput + * @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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 + * @arg @ref LL_TIM_OCIDLESTATE_LOW or @ref LL_TIM_OCIDLESTATE_HIGH + * @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]); + MODIFY_REG(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel]), + (Configuration & TIM_CR2_OIS1) << SHIFT_TAB_OISx[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\n + * CCMR3 OC5M LL_TIM_OC_SetMode\n + * CCMR3 OC6M 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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 + * @arg @ref LL_TIM_OCMODE_RETRIG_OPM1 + * @arg @ref LL_TIM_OCMODE_RETRIG_OPM2 + * @arg @ref LL_TIM_OCMODE_COMBINED_PWM1 + * @arg @ref LL_TIM_OCMODE_COMBINED_PWM2 + * @arg @ref LL_TIM_OCMODE_ASSYMETRIC_PWM1 + * @arg @ref LL_TIM_OCMODE_ASSYMETRIC_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\n + * CCMR3 OC5M LL_TIM_OC_GetMode\n + * CCMR3 OC6M 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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 + * @arg @ref LL_TIM_OCMODE_RETRIG_OPM1 + * @arg @ref LL_TIM_OCMODE_RETRIG_OPM2 + * @arg @ref LL_TIM_OCMODE_COMBINED_PWM1 + * @arg @ref LL_TIM_OCMODE_COMBINED_PWM2 + * @arg @ref LL_TIM_OCMODE_ASSYMETRIC_PWM1 + * @arg @ref LL_TIM_OCMODE_ASSYMETRIC_PWM2 + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetMode(const 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 CC1NP LL_TIM_OC_SetPolarity\n + * CCER CC2P LL_TIM_OC_SetPolarity\n + * CCER CC2NP LL_TIM_OC_SetPolarity\n + * CCER CC3P LL_TIM_OC_SetPolarity\n + * CCER CC3NP LL_TIM_OC_SetPolarity\n + * CCER CC4P LL_TIM_OC_SetPolarity\n + * CCER CC5P LL_TIM_OC_SetPolarity\n + * CCER CC6P 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_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 CC1NP LL_TIM_OC_GetPolarity\n + * CCER CC2P LL_TIM_OC_GetPolarity\n + * CCER CC2NP LL_TIM_OC_GetPolarity\n + * CCER CC3P LL_TIM_OC_GetPolarity\n + * CCER CC3NP LL_TIM_OC_GetPolarity\n + * CCER CC4P LL_TIM_OC_GetPolarity\n + * CCER CC5P LL_TIM_OC_GetPolarity\n + * CCER CC6P 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_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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(const 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 Set the IDLE state of an output channel + * @note This function is significant only for the timer instances + * supporting the break feature. Macro IS_TIM_BREAK_INSTANCE(TIMx) + * can be used to check whether or not a timer instance provides + * a break input. + * @rmtoll CR2 OIS1 LL_TIM_OC_SetIdleState\n + * CR2 OIS2N LL_TIM_OC_SetIdleState\n + * CR2 OIS2 LL_TIM_OC_SetIdleState\n + * CR2 OIS2N LL_TIM_OC_SetIdleState\n + * CR2 OIS3 LL_TIM_OC_SetIdleState\n + * CR2 OIS3N LL_TIM_OC_SetIdleState\n + * CR2 OIS4 LL_TIM_OC_SetIdleState\n + * CR2 OIS5 LL_TIM_OC_SetIdleState\n + * CR2 OIS6 LL_TIM_OC_SetIdleState + * @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_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @param IdleState This parameter can be one of the following values: + * @arg @ref LL_TIM_OCIDLESTATE_LOW + * @arg @ref LL_TIM_OCIDLESTATE_HIGH + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetIdleState(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t IdleState) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel]), IdleState << SHIFT_TAB_OISx[iChannel]); +} + +/** + * @brief Get the IDLE state of an output channel + * @rmtoll CR2 OIS1 LL_TIM_OC_GetIdleState\n + * CR2 OIS2N LL_TIM_OC_GetIdleState\n + * CR2 OIS2 LL_TIM_OC_GetIdleState\n + * CR2 OIS2N LL_TIM_OC_GetIdleState\n + * CR2 OIS3 LL_TIM_OC_GetIdleState\n + * CR2 OIS3N LL_TIM_OC_GetIdleState\n + * CR2 OIS4 LL_TIM_OC_GetIdleState\n + * CR2 OIS5 LL_TIM_OC_GetIdleState\n + * CR2 OIS6 LL_TIM_OC_GetIdleState + * @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_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCIDLESTATE_LOW + * @arg @ref LL_TIM_OCIDLESTATE_HIGH + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetIdleState(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel])) >> SHIFT_TAB_OISx[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\n + * CCMR3 OC5FE LL_TIM_OC_EnableFast\n + * CCMR3 OC6FE 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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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\n + * CCMR3 OC5FE LL_TIM_OC_DisableFast\n + * CCMR3 OC6FE 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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 + * CCMR3 OC5FE LL_TIM_OC_IsEnabledFast\n + * CCMR3 OC6FE LL_TIM_OC_IsEnabledFast + * @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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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\n + * CCMR3 OC5PE LL_TIM_OC_EnablePreload\n + * CCMR3 OC6PE 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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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\n + * CCMR3 OC5PE LL_TIM_OC_DisablePreload\n + * CCMR3 OC6PE 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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 + * CCMR3 OC5PE LL_TIM_OC_IsEnabledPreload\n + * CCMR3 OC6PE LL_TIM_OC_IsEnabledPreload + * @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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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\n + * CCMR3 OC5CE LL_TIM_OC_EnableClear\n + * CCMR3 OC6CE 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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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\n + * CCMR3 OC5CE LL_TIM_OC_DisableClear\n + * CCMR3 OC6CE 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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 + * CCMR3 OC5CE LL_TIM_OC_IsEnabledClear\n + * CCMR3 OC6CE LL_TIM_OC_IsEnabledClear + * @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 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @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 the dead-time delay (delay inserted between the rising edge of the OCxREF signal and the rising edge of + * the Ocx and OCxN signals). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * dead-time insertion feature is supported by a timer instance. + * @note Helper macro @ref __LL_TIM_CALC_DEADTIME can be used to calculate the DeadTime parameter + * @rmtoll BDTR DTG LL_TIM_OC_SetDeadTime + * @param TIMx Timer instance + * @param DeadTime between Min_Data=0 and Max_Data=255 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetDeadTime(TIM_TypeDef *TIMx, uint32_t DeadTime) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_DTG, DeadTime); +} + +/** + * @brief Set compare value for output channel 1 (TIMx_CCR1). + * @note In 32-bit timer implementations compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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 In 32-bit timer implementations compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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 In 32-bit timer implementations compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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 In 32-bit timer implementations compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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 Set compare value for output channel 5 (TIMx_CCR5). + * @note Macro IS_TIM_CC5_INSTANCE(TIMx) can be used to check whether or not + * output channel 5 is supported by a timer instance. + * @rmtoll CCR5 CCR5 LL_TIM_OC_SetCompareCH5 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH5(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + MODIFY_REG(TIMx->CCR5, TIM_CCR5_CCR5, CompareValue); +} + +/** + * @brief Set compare value for output channel 6 (TIMx_CCR6). + * @note Macro IS_TIM_CC6_INSTANCE(TIMx) can be used to check whether or not + * output channel 6 is supported by a timer instance. + * @rmtoll CCR6 CCR6 LL_TIM_OC_SetCompareCH6 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH6(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR6, CompareValue); +} + +/** + * @brief Get compare value (TIMx_CCR1) set for output channel 1. + * @note In 32-bit timer implementations returned compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR1)); +} + +/** + * @brief Get compare value (TIMx_CCR2) set for output channel 2. + * @note In 32-bit timer implementations returned compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR2)); +} + +/** + * @brief Get compare value (TIMx_CCR3) set for output channel 3. + * @note In 32-bit timer implementations returned compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR3)); +} + +/** + * @brief Get compare value (TIMx_CCR4) set for output channel 4. + * @note In 32-bit timer implementations returned compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR4)); +} + +/** + * @brief Get compare value (TIMx_CCR5) set for output channel 5. + * @note Macro IS_TIM_CC5_INSTANCE(TIMx) can be used to check whether or not + * output channel 5 is supported by a timer instance. + * @rmtoll CCR5 CCR5 LL_TIM_OC_GetCompareCH5 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH5(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CCR5, TIM_CCR5_CCR5)); +} + +/** + * @brief Get compare value (TIMx_CCR6) set for output channel 6. + * @note Macro IS_TIM_CC6_INSTANCE(TIMx) can be used to check whether or not + * output channel 6 is supported by a timer instance. + * @rmtoll CCR6 CCR6 LL_TIM_OC_GetCompareCH6 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH6(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR6)); +} + +/** + * @brief Select on which reference signal the OC5REF is combined to. + * @note Macro IS_TIM_COMBINED3PHASEPWM_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the combined 3-phase PWM mode. + * @rmtoll CCR5 GC5C3 LL_TIM_SetCH5CombinedChannels\n + * CCR5 GC5C2 LL_TIM_SetCH5CombinedChannels\n + * CCR5 GC5C1 LL_TIM_SetCH5CombinedChannels + * @param TIMx Timer instance + * @param GroupCH5 This parameter can be a combination of the following values: + * @arg @ref LL_TIM_GROUPCH5_NONE + * @arg @ref LL_TIM_GROUPCH5_OC1REFC + * @arg @ref LL_TIM_GROUPCH5_OC2REFC + * @arg @ref LL_TIM_GROUPCH5_OC3REFC + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetCH5CombinedChannels(TIM_TypeDef *TIMx, uint32_t GroupCH5) +{ + MODIFY_REG(TIMx->CCR5, (TIM_CCR5_GC5C3 | TIM_CCR5_GC5C2 | TIM_CCR5_GC5C1), GroupCH5); +} + +/** + * @} + */ + +/** @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(const 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(const 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(const 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(const 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 In 32-bit timer implementations returned captured value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR1)); +} + +/** + * @brief Get captured value for input channel 2. + * @note In 32-bit timer implementations returned captured value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR2)); +} + +/** + * @brief Get captured value for input channel 3. + * @note In 32-bit timer implementations returned captured value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR3)); +} + +/** + * @brief Get captured value for input channel 4. + * @note In 32-bit timer implementations returned captured value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @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(const 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(const 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 trigger output 2 (TRGO2) used for ADC synchronization . + * @note Macro IS_TIM_TRGO2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance can be used for ADC synchronization. + * @rmtoll CR2 MMS2 LL_TIM_SetTriggerOutput2 + * @param TIMx Timer Instance + * @param ADCSynchronization This parameter can be one of the following values: + * @arg @ref LL_TIM_TRGO2_RESET + * @arg @ref LL_TIM_TRGO2_ENABLE + * @arg @ref LL_TIM_TRGO2_UPDATE + * @arg @ref LL_TIM_TRGO2_CC1F + * @arg @ref LL_TIM_TRGO2_OC1 + * @arg @ref LL_TIM_TRGO2_OC2 + * @arg @ref LL_TIM_TRGO2_OC3 + * @arg @ref LL_TIM_TRGO2_OC4 + * @arg @ref LL_TIM_TRGO2_OC5 + * @arg @ref LL_TIM_TRGO2_OC6 + * @arg @ref LL_TIM_TRGO2_OC4_RISINGFALLING + * @arg @ref LL_TIM_TRGO2_OC6_RISINGFALLING + * @arg @ref LL_TIM_TRGO2_OC4_RISING_OC6_RISING + * @arg @ref LL_TIM_TRGO2_OC4_RISING_OC6_FALLING + * @arg @ref LL_TIM_TRGO2_OC5_RISING_OC6_RISING + * @arg @ref LL_TIM_TRGO2_OC5_RISING_OC6_FALLING + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetTriggerOutput2(TIM_TypeDef *TIMx, uint32_t ADCSynchronization) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_MMS2, ADCSynchronization); +} + +/** + * @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 + * @arg @ref LL_TIM_SLAVEMODE_COMBINED_RESETTRIGGER + * @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(const 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); +} + +/** + * @brief Select the external trigger (ETR) input source. + * @note Macro IS_TIM_ETRSEL_INSTANCE(TIMx) can be used to check whether or + * not a timer instance supports ETR source selection. + * @rmtoll OR2 ETRSEL LL_TIM_SetETRSource + * @param TIMx Timer instance + * @param ETRSource This parameter can be one of the following values: + * @arg @ref LL_TIM_ETRSOURCE_LEGACY + * @arg @ref LL_TIM_ETRSOURCE_COMP1 + * @arg @ref LL_TIM_ETRSOURCE_COMP2 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetETRSource(TIM_TypeDef *TIMx, uint32_t ETRSource) +{ + MODIFY_REG(TIMx->OR2, TIMx_OR2_ETRSEL, ETRSource); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Break_Function Break function configuration + * @{ + */ +/** + * @brief Enable the break function. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR BKE LL_TIM_EnableBRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableBRK(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_BKE); +} + +/** + * @brief Disable the break function. + * @rmtoll BDTR BKE LL_TIM_DisableBRK + * @param TIMx Timer instance + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableBRK(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_BKE); +} + +/** + * @brief Configure the break input. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR BKP LL_TIM_ConfigBRK\n + * BDTR BKF LL_TIM_ConfigBRK + * @param TIMx Timer instance + * @param BreakPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_POLARITY_LOW + * @arg @ref LL_TIM_BREAK_POLARITY_HIGH + * @param BreakFilter This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_FILTER_FDIV1 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV32_N8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigBRK(TIM_TypeDef *TIMx, uint32_t BreakPolarity, + uint32_t BreakFilter) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_BKP | TIM_BDTR_BKF, BreakPolarity | BreakFilter); +} + +/** + * @brief Enable the break 2 function. + * @note Macro IS_TIM_BKIN2_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a second break input. + * @rmtoll BDTR BK2E LL_TIM_EnableBRK2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableBRK2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_BK2E); +} + +/** + * @brief Disable the break 2 function. + * @note Macro IS_TIM_BKIN2_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a second break input. + * @rmtoll BDTR BK2E LL_TIM_DisableBRK2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableBRK2(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_BK2E); +} + +/** + * @brief Configure the break 2 input. + * @note Macro IS_TIM_BKIN2_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a second break input. + * @rmtoll BDTR BK2P LL_TIM_ConfigBRK2\n + * BDTR BK2F LL_TIM_ConfigBRK2 + * @param TIMx Timer instance + * @param Break2Polarity This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK2_POLARITY_LOW + * @arg @ref LL_TIM_BREAK2_POLARITY_HIGH + * @param Break2Filter This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV1 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV32_N8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigBRK2(TIM_TypeDef *TIMx, uint32_t Break2Polarity, uint32_t Break2Filter) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_BK2P | TIM_BDTR_BK2F, Break2Polarity | Break2Filter); +} + +/** + * @brief Select the outputs off state (enabled v.s. disabled) in Idle and Run modes. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR OSSI LL_TIM_SetOffStates\n + * BDTR OSSR LL_TIM_SetOffStates + * @param TIMx Timer instance + * @param OffStateIdle This parameter can be one of the following values: + * @arg @ref LL_TIM_OSSI_DISABLE + * @arg @ref LL_TIM_OSSI_ENABLE + * @param OffStateRun This parameter can be one of the following values: + * @arg @ref LL_TIM_OSSR_DISABLE + * @arg @ref LL_TIM_OSSR_ENABLE + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetOffStates(TIM_TypeDef *TIMx, uint32_t OffStateIdle, uint32_t OffStateRun) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_OSSI | TIM_BDTR_OSSR, OffStateIdle | OffStateRun); +} + +/** + * @brief Enable automatic output (MOE can be set by software or automatically when a break input is active). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_EnableAutomaticOutput + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableAutomaticOutput(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_AOE); +} + +/** + * @brief Disable automatic output (MOE can be set only by software). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_DisableAutomaticOutput + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableAutomaticOutput(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_AOE); +} + +/** + * @brief Indicate whether automatic output is enabled. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_IsEnabledAutomaticOutput + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledAutomaticOutput(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->BDTR, TIM_BDTR_AOE) == (TIM_BDTR_AOE)) ? 1UL : 0UL); +} + +/** + * @brief Enable the outputs (set the MOE bit in TIMx_BDTR register). + * @note The MOE bit in TIMx_BDTR register allows to enable /disable the outputs by + * software and is reset in case of break or break2 event + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_EnableAllOutputs + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableAllOutputs(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_MOE); +} + +/** + * @brief Disable the outputs (reset the MOE bit in TIMx_BDTR register). + * @note The MOE bit in TIMx_BDTR register allows to enable /disable the outputs by + * software and is reset in case of break or break2 event. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_DisableAllOutputs + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableAllOutputs(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_MOE); +} + +/** + * @brief Indicates whether outputs are enabled. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_IsEnabledAllOutputs + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledAllOutputs(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->BDTR, TIM_BDTR_MOE) == (TIM_BDTR_MOE)) ? 1UL : 0UL); +} + +/** + * @brief Enable the signals connected to the designated timer break input. + * @note Macro IS_TIM_BREAKSOURCE_INSTANCE(TIMx) can be used to check whether + * or not a timer instance allows for break input selection. + * @rmtoll OR2 BKINE LL_TIM_EnableBreakInputSource\n + * OR2 BKCMP1E LL_TIM_EnableBreakInputSource\n + * OR2 BKCMP2E LL_TIM_EnableBreakInputSource\n + * OR2 BKDF1BK0E LL_TIM_EnableBreakInputSource\n + * OR3 BK2INE LL_TIM_EnableBreakInputSource\n + * OR3 BK2CMP1E LL_TIM_EnableBreakInputSource\n + * OR3 BK2CMP2E LL_TIM_EnableBreakInputSource\n + * OR3 BK2DF1BK1E LL_TIM_EnableBreakInputSource + * @param TIMx Timer instance + * @param BreakInput This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_INPUT_BKIN + * @arg @ref LL_TIM_BREAK_INPUT_BKIN2 + * @param Source This parameter can be one of the following values: + * @arg @ref LL_TIM_BKIN_SOURCE_BKIN + * @arg @ref LL_TIM_BKIN_SOURCE_BKCOMP1 + * @arg @ref LL_TIM_BKIN_SOURCE_BKCOMP2 + * @arg @ref LL_TIM_BKIN_SOURCE_DF1BK + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableBreakInputSource(TIM_TypeDef *TIMx, uint32_t BreakInput, uint32_t Source) +{ + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->OR2) + BreakInput)); + SET_BIT(*pReg, Source); +} + +/** + * @brief Disable the signals connected to the designated timer break input. + * @note Macro IS_TIM_BREAKSOURCE_INSTANCE(TIMx) can be used to check whether + * or not a timer instance allows for break input selection. + * @rmtoll OR2 BKINE LL_TIM_DisableBreakInputSource\n + * OR2 BKCMP1E LL_TIM_DisableBreakInputSource\n + * OR2 BKCMP2E LL_TIM_DisableBreakInputSource\n + * OR2 BKDF1BK0E LL_TIM_DisableBreakInputSource\n + * OR3 BK2INE LL_TIM_DisableBreakInputSource\n + * OR3 BK2CMP1E LL_TIM_DisableBreakInputSource\n + * OR3 BK2CMP2E LL_TIM_DisableBreakInputSource\n + * OR3 BK2DF1BK1E LL_TIM_DisableBreakInputSource + * @param TIMx Timer instance + * @param BreakInput This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_INPUT_BKIN + * @arg @ref LL_TIM_BREAK_INPUT_BKIN2 + * @param Source This parameter can be one of the following values: + * @arg @ref LL_TIM_BKIN_SOURCE_BKIN + * @arg @ref LL_TIM_BKIN_SOURCE_BKCOMP1 + * @arg @ref LL_TIM_BKIN_SOURCE_BKCOMP2 + * @arg @ref LL_TIM_BKIN_SOURCE_DF1BK + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableBreakInputSource(TIM_TypeDef *TIMx, uint32_t BreakInput, uint32_t Source) +{ + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->OR2) + BreakInput)); + CLEAR_BIT(*pReg, Source); +} + +/** + * @brief Set the polarity of the break signal for the timer break input. + * @note Macro IS_TIM_BREAKSOURCE_INSTANCE(TIMx) can be used to check whether + * or not a timer instance allows for break input selection. + * @rmtoll OR2 BKINP LL_TIM_SetBreakInputSourcePolarity\n + * OR2 BKCMP1P LL_TIM_SetBreakInputSourcePolarity\n + * OR2 BKCMP2P LL_TIM_SetBreakInputSourcePolarity\n + * OR3 BK2INP LL_TIM_SetBreakInputSourcePolarity\n + * OR3 BK2CMP1P LL_TIM_SetBreakInputSourcePolarity\n + * OR3 BK2CMP2P LL_TIM_SetBreakInputSourcePolarity + * @param TIMx Timer instance + * @param BreakInput This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_INPUT_BKIN + * @arg @ref LL_TIM_BREAK_INPUT_BKIN2 + * @param Source This parameter can be one of the following values: + * @arg @ref LL_TIM_BKIN_SOURCE_BKIN + * @arg @ref LL_TIM_BKIN_SOURCE_BKCOMP1 + * @arg @ref LL_TIM_BKIN_SOURCE_BKCOMP2 + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_TIM_BKIN_POLARITY_LOW + * @arg @ref LL_TIM_BKIN_POLARITY_HIGH + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetBreakInputSourcePolarity(TIM_TypeDef *TIMx, uint32_t BreakInput, uint32_t Source, + uint32_t Polarity) +{ + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->OR2) + BreakInput)); + MODIFY_REG(*pReg, (TIMx_OR2_BKINP << TIM_POSITION_BRK_SOURCE), (Polarity << TIM_POSITION_BRK_SOURCE)); +} +/** + * @} + */ + +/** @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_RCR + * @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_BDTR + * @arg @ref LL_TIM_DMABURST_BASEADDR_OR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCMR3 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR5 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR6 + * @arg @ref LL_TIM_DMABURST_BASEADDR_OR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_OR3 + * @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. + @if STM32L486xx + * @rmtoll TIM1_OR1 ETR_ADC1_RMP LL_TIM_SetRemap\n + * TIM1_OR1 ETR_ADC3_RMP LL_TIM_SetRemap\n + * TIM1_OR1 TI1_RMP LL_TIM_SetRemap\n + * TIM8_OR1 ETR_ADC2_RMP LL_TIM_SetRemap\n + * TIM8_OR1 ETR_ADC3_RMP LL_TIM_SetRemap\n + * TIM8_OR1 TI1_RMP LL_TIM_SetRemap\n + * TIM2_OR1 ITR1_RMP LL_TIM_SetRemap\n + * TIM2_OR1 TI4_RMP LL_TIM_SetRemap\n + * TIM2_OR1 TI1_RMP LL_TIM_SetRemap\n + * TIM3_OR1 TI1_RMP LL_TIM_SetRemap\n + * TIM15_OR1 TI1_RMP LL_TIM_SetRemap\n + * TIM15_OR1 ENCODER_MODE LL_TIM_SetRemap\n + * TIM16_OR1 TI1_RMP LL_TIM_SetRemap\n + * TIM17_OR1 TI1_RMP LL_TIM_SetRemap + @endif + @if STM32L443xx + * @rmtoll TIM1_OR1 ETR_ADC1_RMP LL_TIM_SetRemap\n + * TIM1_OR1 ETR_ADC3_RMP LL_TIM_SetRemap\n + * TIM1_OR1 TI1_RMP LL_TIM_SetRemap\n + * TIM2_OR1 ITR1_RMP LL_TIM_SetRemap\n + * TIM2_OR1 TI4_RMP LL_TIM_SetRemap\n + * TIM2_OR1 TI1_RMP LL_TIM_SetRemap\n + * TIM15_OR1 TI1_RMP LL_TIM_SetRemap\n + * TIM15_OR1 ENCODER_MODE LL_TIM_SetRemap\n + * TIM16_OR1 TI1_RMP LL_TIM_SetRemap\n + @endif + * @param TIMx Timer instance + * @param Remap Remap param 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: + * + @if STM32L486xx + * TIM1: any combination of TI1_RMP, ADC3_RMP, ADC1_RMP where + * + * . . ADC1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM1_ETR_ADC1_RMP_NC + * @arg @ref LL_TIM_TIM1_ETR_ADC1_RMP_AWD1 + * @arg @ref LL_TIM_TIM1_ETR_ADC1_RMP_AWD2 + * @arg @ref LL_TIM_TIM1_ETR_ADC1_RMP_AWD3 + * + * . . ADC3_RMP can be one of the following values + * @arg @ref LL_TIM_TIM1_ETR_ADC3_RMP_NC + * @arg @ref LL_TIM_TIM1_ETR_ADC3_RMP_AWD1 + * @arg @ref LL_TIM_TIM1_ETR_ADC3_RMP_AWD2 + * @arg @ref LL_TIM_TIM1_ETR_ADC3_RMP_AWD3 + * + * . . TI1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM1_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM1_TI1_RMP_COMP1 + * + * TIM2: any combination of ITR1_RMP, ETR1_RMP, TI4_RMP where + * + * ITR1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM2_ITR1_RMP_TIM8_TRGO + * @arg @ref LL_TIM_TIM2_ITR1_RMP_OTG_FS_SOF + * + * . . ETR1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM2_ETR_RMP_GPIO + * @arg @ref LL_TIM_TIM2_ETR_RMP_LSE + * + * . . 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 + * @arg @ref LL_TIM_TIM2_TI4_RMP_COMP1_COMP2 + * + * TIM3: one of the following values + * + * @arg @ref LL_TIM_TIM3_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM3_TI1_RMP_COMP1 + * @arg @ref LL_TIM_TIM3_TI1_RMP_COMP2 + * @arg @ref LL_TIM_TIM3_TI1_RMP_COMP1_COMP2 + * + * TIM8: any combination of TI1_RMP, ADC3_RMP, ADC1_RMP where + * + * . . ADC1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM8_ETR_ADC2_RMP_NC + * @arg @ref LL_TIM_TIM8_ETR_ADC2_RMP_AWD1 + * @arg @ref LL_TIM_TIM8_ETR_ADC2_RMP_AWD2 + * @arg @ref LL_TIM_TIM8_ETR_ADC2_RMP_AWD3 + * + * . . ADC3_RMP can be one of the following values + * @arg @ref LL_TIM_TIM8_ETR_ADC3_RMP_NC + * @arg @ref LL_TIM_TIM8_ETR_ADC3_RMP_AWD1 + * @arg @ref LL_TIM_TIM8_ETR_ADC3_RMP_AWD2 + * @arg @ref LL_TIM_TIM8_ETR_ADC3_RMP_AWD3 + * + * . . TI1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM8_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM8_TI1_RMP_COMP2 + * + * TIM15: any combination of TI1_RMP, ENCODER_MODE where + * + * . . TI1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM15_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM15_TI1_RMP_LSE + * + * . . ENCODER_MODE can be one of the following values + * @arg @ref LL_TIM_TIM15_ENCODERMODE_NOREDIRECTION + * @arg @ref LL_TIM_TIM15_ENCODERMODE_TIM2 + * @arg @ref LL_TIM_TIM15_ENCODERMODE_TIM3 + * @arg @ref LL_TIM_TIM15_ENCODERMODE_TIM4 + * + * TIM16: one of the following values + * + * @arg @ref LL_TIM_TIM16_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM16_TI1_RMP_LSI + * @arg @ref LL_TIM_TIM16_TI1_RMP_LSE + * @arg @ref LL_TIM_TIM16_TI1_RMP_RTC + * @arg @ref LL_TIM_TIM16_TI1_RMP_MSI + * @arg @ref LL_TIM_TIM16_TI1_RMP_HSE_32 + * @arg @ref LL_TIM_TIM16_TI1_RMP_MCO + * + * TIM17: one of the following values + * + * @arg @ref LL_TIM_TIM17_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM17_TI1_RMP_MSI + * @arg @ref LL_TIM_TIM17_TI1_RMP_HSE_32 + * @arg @ref LL_TIM_TIM17_TI1_RMP_MCO + @endif + @if STM32L443xx + * TIM1: any combination of TI1_RMP, ADC3_RMP, ADC1_RMP where + * + * . . ADC1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM1_ETR_ADC1_RMP_NC + * @arg @ref LL_TIM_TIM1_ETR_ADC1_RMP_AWD1 + * @arg @ref LL_TIM_TIM1_ETR_ADC1_RMP_AWD2 + * @arg @ref LL_TIM_TIM1_ETR_ADC1_RMP_AWD3 + * + * . . TI1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM1_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM1_TI1_RMP_COMP1 + * + * TIM2: any combination of ITR1_RMP, ETR1_RMP, TI4_RMP where + * + * ITR1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM2_ITR1_RMP_NONE + * @arg @ref LL_TIM_TIM2_ITR1_RMP_USB_SOF + * + * . . ETR1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM2_ETR_RMP_GPIO + * @arg @ref LL_TIM_TIM2_ETR_RMP_LSE + * + * . . 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 + * @arg @ref LL_TIM_TIM2_TI4_RMP_COMP1_COMP2 + * + * TIM15: any combination of TI1_RMP, ENCODER_MODE where + * + * . . TI1_RMP can be one of the following values + * @arg @ref LL_TIM_TIM15_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM15_TI1_RMP_LSE + * + * . . ENCODER_MODE can be one of the following values + * @arg @ref LL_TIM_TIM15_ENCODERMODE_NOREDIRECTION + * @arg @ref LL_TIM_TIM15_ENCODERMODE_TIM2 + * @arg @ref LL_TIM_TIM15_ENCODERMODE_TIM3 + * @arg @ref LL_TIM_TIM15_ENCODERMODE_TIM4 + * + * TIM16: one of the following values + * + * @arg @ref LL_TIM_TIM16_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM16_TI1_RMP_LSI + * @arg @ref LL_TIM_TIM16_TI1_RMP_LSE + * @arg @ref LL_TIM_TIM16_TI1_RMP_RTC + * @arg @ref LL_TIM_TIM16_TI1_RMP_MSI + * @arg @ref LL_TIM_TIM16_TI1_RMP_HSE_32 + * @arg @ref LL_TIM_TIM16_TI1_RMP_MCO + @endif + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetRemap(TIM_TypeDef *TIMx, uint32_t Remap) +{ + MODIFY_REG(TIMx->OR1, (Remap >> TIMx_OR1_RMP_SHIFT), (Remap & TIMx_OR1_RMP_MASK)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_OCREF_Clear OCREF_Clear_Management + * @{ + */ +/** + * @brief Set the OCREF clear input source + * @note The OCxREF signal of a given channel can be cleared when a high level is applied on the OCREF_CLR_INPUT + * @note This function can only be used in Output compare and PWM modes. + * @rmtoll SMCR OCCS LL_TIM_SetOCRefClearInputSource + * @param TIMx Timer instance + * @param OCRefClearInputSource This parameter can be one of the following values: + * @arg @ref LL_TIM_OCREF_CLR_INT_NC + * @arg @ref LL_TIM_OCREF_CLR_INT_ETR + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetOCRefClearInputSource(TIM_TypeDef *TIMx, uint32_t OCRefClearInputSource) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_OCCS, OCRefClearInputSource); +} +/** + * @} + */ + +/** @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(const 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(const 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(const 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(const 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(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC4IF) == (TIM_SR_CC4IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 5 interrupt flag (CC5F). + * @rmtoll SR CC5IF LL_TIM_ClearFlag_CC5 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC5(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC5IF)); +} + +/** + * @brief Indicate whether Capture/Compare 5 interrupt flag (CC5F) is set (Capture/Compare 5 interrupt is pending). + * @rmtoll SR CC5IF LL_TIM_IsActiveFlag_CC5 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC5(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC5IF) == (TIM_SR_CC5IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 6 interrupt flag (CC6F). + * @rmtoll SR CC6IF LL_TIM_ClearFlag_CC6 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC6(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC6IF)); +} + +/** + * @brief Indicate whether Capture/Compare 6 interrupt flag (CC6F) is set (Capture/Compare 6 interrupt is pending). + * @rmtoll SR CC6IF LL_TIM_IsActiveFlag_CC6 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC6(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC6IF) == (TIM_SR_CC6IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the commutation interrupt flag (COMIF). + * @rmtoll SR COMIF LL_TIM_ClearFlag_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_COM(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_COMIF)); +} + +/** + * @brief Indicate whether commutation interrupt flag (COMIF) is set (commutation interrupt is pending). + * @rmtoll SR COMIF LL_TIM_IsActiveFlag_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_COM(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_COMIF) == (TIM_SR_COMIF)) ? 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(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_TIF) == (TIM_SR_TIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the break interrupt flag (BIF). + * @rmtoll SR BIF LL_TIM_ClearFlag_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_BRK(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_BIF)); +} + +/** + * @brief Indicate whether break interrupt flag (BIF) is set (break interrupt is pending). + * @rmtoll SR BIF LL_TIM_IsActiveFlag_BRK + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_BRK(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_BIF) == (TIM_SR_BIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the break 2 interrupt flag (B2IF). + * @rmtoll SR B2IF LL_TIM_ClearFlag_BRK2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_BRK2(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_B2IF)); +} + +/** + * @brief Indicate whether break 2 interrupt flag (B2IF) is set (break 2 interrupt is pending). + * @rmtoll SR B2IF LL_TIM_IsActiveFlag_BRK2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_BRK2(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_B2IF) == (TIM_SR_B2IF)) ? 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(const 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(const 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(const 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(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC4OF) == (TIM_SR_CC4OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the system break interrupt flag (SBIF). + * @rmtoll SR SBIF LL_TIM_ClearFlag_SYSBRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_SYSBRK(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_SBIF)); +} + +/** + * @brief Indicate whether system break interrupt flag (SBIF) is set (system break interrupt is pending). + * @rmtoll SR SBIF LL_TIM_IsActiveFlag_SYSBRK + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_SYSBRK(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_SBIF) == (TIM_SR_SBIF)) ? 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(const 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(const 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(const 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(const 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(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC4IE) == (TIM_DIER_CC4IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable commutation interrupt (COMIE). + * @rmtoll DIER COMIE LL_TIM_EnableIT_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_COM(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_COMIE); +} + +/** + * @brief Disable commutation interrupt (COMIE). + * @rmtoll DIER COMIE LL_TIM_DisableIT_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_COM(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_COMIE); +} + +/** + * @brief Indicates whether the commutation interrupt (COMIE) is enabled. + * @rmtoll DIER COMIE LL_TIM_IsEnabledIT_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_COM(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_COMIE) == (TIM_DIER_COMIE)) ? 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(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_TIE) == (TIM_DIER_TIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable break interrupt (BIE). + * @rmtoll DIER BIE LL_TIM_EnableIT_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_BRK(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_BIE); +} + +/** + * @brief Disable break interrupt (BIE). + * @rmtoll DIER BIE LL_TIM_DisableIT_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_BRK(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_BIE); +} + +/** + * @brief Indicates whether the break interrupt (BIE) is enabled. + * @rmtoll DIER BIE LL_TIM_IsEnabledIT_BRK + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_BRK(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_BIE) == (TIM_DIER_BIE)) ? 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(const 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(const 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(const 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(const 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(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC4DE) == (TIM_DIER_CC4DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable commutation DMA request (COMDE). + * @rmtoll DIER COMDE LL_TIM_EnableDMAReq_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_COM(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_COMDE); +} + +/** + * @brief Disable commutation DMA request (COMDE). + * @rmtoll DIER COMDE LL_TIM_DisableDMAReq_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_COM(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_COMDE); +} + +/** + * @brief Indicates whether the commutation DMA request (COMDE) is enabled. + * @rmtoll DIER COMDE LL_TIM_IsEnabledDMAReq_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_COM(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_COMDE) == (TIM_DIER_COMDE)) ? 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(const 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 commutation event. + * @rmtoll EGR COMG LL_TIM_GenerateEvent_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_COM(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_COMG); +} + +/** + * @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); +} + +/** + * @brief Generate break event. + * @rmtoll EGR BG LL_TIM_GenerateEvent_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_BRK(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_BG); +} + +/** + * @brief Generate break 2 event. + * @rmtoll EGR B2G LL_TIM_GenerateEvent_BRK2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_BRK2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_B2G); +} + +/** + * @} + */ + +#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, const 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, const 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, const 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, const LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); +void LL_TIM_HALLSENSOR_StructInit(LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct); +ErrorStatus LL_TIM_HALLSENSOR_Init(TIM_TypeDef *TIMx, const LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct); +void LL_TIM_BDTR_StructInit(LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct); +ErrorStatus LL_TIM_BDTR_Init(TIM_TypeDef *TIMx, const LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct); +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* TIM1 || TIM8 || TIM2 || TIM3 || TIM4 || TIM5 || TIM15 || TIM16 || TIM17 || TIM6 || TIM7 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L4xx_LL_TIM_H */ diff --git a/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usart.h b/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usart.h deleted file mode 100644 index ee831a8..0000000 --- a/Firmware/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usart.h +++ /dev/null @@ -1,4701 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l4xx_ll_usart.h - * @author MCD Application Team - * @brief Header file of USART LL module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef STM32L4xx_LL_USART_H -#define STM32L4xx_LL_USART_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l4xx.h" - -/** @addtogroup STM32L4xx_LL_Driver - * @{ - */ - -#if defined (USART1) || defined (USART2) || defined (USART3) || defined (UART4) || defined (UART5) - -/** @defgroup USART_LL USART - * @{ - */ - -/* Private types -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -#if defined(USART_PRESC_PRESCALER) -/** @defgroup USART_LL_Private_Variables USART Private Variables - * @{ - */ -/* Array used to get the USART prescaler division decimal values versus @ref USART_LL_EC_PRESCALER values */ -static const uint32_t USART_PRESCALER_TAB[] = -{ - 1UL, - 2UL, - 4UL, - 6UL, - 8UL, - 10UL, - 12UL, - 16UL, - 32UL, - 64UL, - 128UL, - 256UL -}; -/** - * @} - */ -#endif /* USART_PRESC_PRESCALER */ - -/* Private constants ---------------------------------------------------------*/ -/* Private macros ------------------------------------------------------------*/ -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup USART_LL_Private_Macros USART Private Macros - * @{ - */ -/** - * @} - */ -#endif /*USE_FULL_LL_DRIVER*/ - -/* Exported types ------------------------------------------------------------*/ -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup USART_LL_ES_INIT USART Exported Init structures - * @{ - */ - -/** - * @brief LL USART Init Structure definition - */ -typedef struct -{ -#if defined(USART_PRESC_PRESCALER) - uint32_t PrescalerValue; /*!< Specifies the Prescaler to compute the communication baud rate. - This parameter can be a value of @ref USART_LL_EC_PRESCALER. - - This feature can be modified afterwards using unitary - function @ref LL_USART_SetPrescaler().*/ -#endif /* USART_PRESC_PRESCALER */ - - uint32_t BaudRate; /*!< This field defines expected Usart communication baud rate. - - This feature can be modified afterwards using unitary - function @ref LL_USART_SetBaudRate().*/ - - uint32_t DataWidth; /*!< Specifies the number of data bits transmitted or received in a frame. - This parameter can be a value of @ref USART_LL_EC_DATAWIDTH. - - This feature can be modified afterwards using unitary - function @ref LL_USART_SetDataWidth().*/ - - uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. - This parameter can be a value of @ref USART_LL_EC_STOPBITS. - - This feature can be modified afterwards using unitary - function @ref LL_USART_SetStopBitsLength().*/ - - uint32_t Parity; /*!< Specifies the parity mode. - This parameter can be a value of @ref USART_LL_EC_PARITY. - - This feature can be modified afterwards using unitary - function @ref LL_USART_SetParity().*/ - - uint32_t TransferDirection; /*!< Specifies whether the Receive and/or Transmit mode is enabled or disabled. - This parameter can be a value of @ref USART_LL_EC_DIRECTION. - - This feature can be modified afterwards using unitary - function @ref LL_USART_SetTransferDirection().*/ - - uint32_t HardwareFlowControl; /*!< Specifies whether the hardware flow control mode is enabled or disabled. - This parameter can be a value of @ref USART_LL_EC_HWCONTROL. - - This feature can be modified afterwards using unitary - function @ref LL_USART_SetHWFlowCtrl().*/ - - uint32_t OverSampling; /*!< Specifies whether USART oversampling mode is 16 or 8. - This parameter can be a value of @ref USART_LL_EC_OVERSAMPLING. - - This feature can be modified afterwards using unitary - function @ref LL_USART_SetOverSampling().*/ - -} LL_USART_InitTypeDef; - -/** - * @brief LL USART Clock Init Structure definition - */ -typedef struct -{ - uint32_t ClockOutput; /*!< Specifies whether the USART clock is enabled or disabled. - This parameter can be a value of @ref USART_LL_EC_CLOCK. - - USART HW configuration can be modified afterwards using unitary functions - @ref LL_USART_EnableSCLKOutput() or @ref LL_USART_DisableSCLKOutput(). - For more details, refer to description of this function. */ - - uint32_t ClockPolarity; /*!< Specifies the steady state of the serial clock. - This parameter can be a value of @ref USART_LL_EC_POLARITY. - - USART HW configuration can be modified afterwards using unitary - functions @ref LL_USART_SetClockPolarity(). - For more details, refer to description of this function. */ - - uint32_t ClockPhase; /*!< Specifies the clock transition on which the bit capture is made. - This parameter can be a value of @ref USART_LL_EC_PHASE. - - USART HW configuration can be modified afterwards using unitary - functions @ref LL_USART_SetClockPhase(). - For more details, refer to description of this function. */ - - uint32_t LastBitClockPulse; /*!< Specifies whether the clock pulse corresponding to the last transmitted - data bit (MSB) has to be output on the SCLK pin in synchronous mode. - This parameter can be a value of @ref USART_LL_EC_LASTCLKPULSE. - - USART HW configuration can be modified afterwards using unitary - functions @ref LL_USART_SetLastClkPulseOutput(). - For more details, refer to description of this function. */ - -} LL_USART_ClockInitTypeDef; - -/** - * @} - */ -#endif /* USE_FULL_LL_DRIVER */ - -/* Exported constants --------------------------------------------------------*/ -/** @defgroup USART_LL_Exported_Constants USART Exported Constants - * @{ - */ - -/** @defgroup USART_LL_EC_CLEAR_FLAG Clear Flags Defines - * @brief Flags defines which can be used with LL_USART_WriteReg function - * @{ - */ -#define LL_USART_ICR_PECF USART_ICR_PECF /*!< Parity error clear flag */ -#define LL_USART_ICR_FECF USART_ICR_FECF /*!< Framing error clear flag */ -#define LL_USART_ICR_NECF USART_ICR_NECF /*!< Noise error detected clear flag */ -#define LL_USART_ICR_ORECF USART_ICR_ORECF /*!< Overrun error clear flag */ -#define LL_USART_ICR_IDLECF USART_ICR_IDLECF /*!< Idle line detected clear flag */ -#if defined(USART_CR1_FIFOEN) -#define LL_USART_ICR_TXFECF USART_ICR_TXFECF /*!< TX FIFO Empty clear flag */ -#endif /* USART_CR1_FIFOEN */ -#define LL_USART_ICR_TCCF USART_ICR_TCCF /*!< Transmission complete clear flag */ -#if defined(USART_TCBGT_SUPPORT) -#define LL_USART_ICR_TCBGTCF USART_ICR_TCBGTCF /*!< Transmission completed before guard time clear flag */ -#endif /* USART_TCBGT_SUPPORT */ -#define LL_USART_ICR_LBDCF USART_ICR_LBDCF /*!< LIN break detection clear flag */ -#define LL_USART_ICR_CTSCF USART_ICR_CTSCF /*!< CTS clear flag */ -#define LL_USART_ICR_RTOCF USART_ICR_RTOCF /*!< Receiver timeout clear flag */ -#define LL_USART_ICR_EOBCF USART_ICR_EOBCF /*!< End of block clear flag */ -#if defined(USART_CR2_SLVEN) -#define LL_USART_ICR_UDRCF USART_ICR_UDRCF /*!< SPI Slave Underrun clear flag */ -#endif /* USART_CR2_SLVEN */ -#define LL_USART_ICR_CMCF USART_ICR_CMCF /*!< Character match clear flag */ -#define LL_USART_ICR_WUCF USART_ICR_WUCF /*!< Wakeup from Stop mode clear flag */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_GET_FLAG Get Flags Defines - * @brief Flags defines which can be used with LL_USART_ReadReg function - * @{ - */ -#define LL_USART_ISR_PE USART_ISR_PE /*!< Parity error flag */ -#define LL_USART_ISR_FE USART_ISR_FE /*!< Framing error flag */ -#define LL_USART_ISR_NE USART_ISR_NE /*!< Noise detected flag */ -#define LL_USART_ISR_ORE USART_ISR_ORE /*!< Overrun error flag */ -#define LL_USART_ISR_IDLE USART_ISR_IDLE /*!< Idle line detected flag */ -#if defined(USART_CR1_FIFOEN) -#define LL_USART_ISR_RXNE_RXFNE USART_ISR_RXNE_RXFNE /*!< Read data register or RX FIFO not empty flag */ -#else -#define LL_USART_ISR_RXNE USART_ISR_RXNE /*!< Read data register not empty flag */ -#endif /* USART_CR1_FIFOEN */ -#define LL_USART_ISR_TC USART_ISR_TC /*!< Transmission complete flag */ -#if defined(USART_CR1_FIFOEN) -#define LL_USART_ISR_TXE_TXFNF USART_ISR_TXE_TXFNF /*!< Transmit data register empty or TX FIFO Not Full flag*/ -#else -#define LL_USART_ISR_TXE USART_ISR_TXE /*!< Transmit data register empty flag */ -#endif /* USART_CR1_FIFOEN */ -#define LL_USART_ISR_LBDF USART_ISR_LBDF /*!< LIN break detection flag */ -#define LL_USART_ISR_CTSIF USART_ISR_CTSIF /*!< CTS interrupt flag */ -#define LL_USART_ISR_CTS USART_ISR_CTS /*!< CTS flag */ -#define LL_USART_ISR_RTOF USART_ISR_RTOF /*!< Receiver timeout flag */ -#define LL_USART_ISR_EOBF USART_ISR_EOBF /*!< End of block flag */ -#if defined(USART_CR2_SLVEN) -#define LL_USART_ISR_UDR USART_ISR_UDR /*!< SPI Slave underrun error flag */ -#endif /* USART_CR2_SLVEN */ -#define LL_USART_ISR_ABRE USART_ISR_ABRE /*!< Auto baud rate error flag */ -#define LL_USART_ISR_ABRF USART_ISR_ABRF /*!< Auto baud rate flag */ -#define LL_USART_ISR_BUSY USART_ISR_BUSY /*!< Busy flag */ -#define LL_USART_ISR_CMF USART_ISR_CMF /*!< Character match flag */ -#define LL_USART_ISR_SBKF USART_ISR_SBKF /*!< Send break flag */ -#define LL_USART_ISR_RWU USART_ISR_RWU /*!< Receiver wakeup from Mute mode flag */ -#define LL_USART_ISR_WUF USART_ISR_WUF /*!< Wakeup from Stop mode flag */ -#define LL_USART_ISR_TEACK USART_ISR_TEACK /*!< Transmit enable acknowledge flag */ -#define LL_USART_ISR_REACK USART_ISR_REACK /*!< Receive enable acknowledge flag */ -#if defined(USART_CR1_FIFOEN) -#define LL_USART_ISR_TXFE USART_ISR_TXFE /*!< TX FIFO empty flag */ -#define LL_USART_ISR_RXFF USART_ISR_RXFF /*!< RX FIFO full flag */ -#endif /* USART_CR1_FIFOEN */ -#if defined(USART_TCBGT_SUPPORT) -#define LL_USART_ISR_TCBGT USART_ISR_TCBGT /*!< Transmission complete before guard time completion flag */ -#endif /* USART_TCBGT_SUPPORT */ -#if defined(USART_CR1_FIFOEN) -#define LL_USART_ISR_RXFT USART_ISR_RXFT /*!< RX FIFO threshold flag */ -#define LL_USART_ISR_TXFT USART_ISR_TXFT /*!< TX FIFO threshold flag */ -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_IT IT Defines - * @brief IT defines which can be used with LL_USART_ReadReg and LL_USART_WriteReg functions - * @{ - */ -#define LL_USART_CR1_IDLEIE USART_CR1_IDLEIE /*!< IDLE interrupt enable */ -#if defined(USART_CR1_FIFOEN) -#define LL_USART_CR1_RXNEIE_RXFNEIE USART_CR1_RXNEIE_RXFNEIE /*!< Read data register and RXFIFO not empty interrupt enable */ -#else -#define LL_USART_CR1_RXNEIE USART_CR1_RXNEIE /*!< Read data register not empty interrupt enable */ -#endif /* USART_CR1_FIFOEN */ -#define LL_USART_CR1_TCIE USART_CR1_TCIE /*!< Transmission complete interrupt enable */ -#if defined(USART_CR1_FIFOEN) -#define LL_USART_CR1_TXEIE_TXFNFIE USART_CR1_TXEIE_TXFNFIE /*!< Transmit data register empty and TX FIFO not full interrupt enable */ -#else -#define LL_USART_CR1_TXEIE USART_CR1_TXEIE /*!< Transmit data register empty interrupt enable */ -#endif /* USART_CR1_FIFOEN */ -#define LL_USART_CR1_PEIE USART_CR1_PEIE /*!< Parity error */ -#define LL_USART_CR1_CMIE USART_CR1_CMIE /*!< Character match interrupt enable */ -#define LL_USART_CR1_RTOIE USART_CR1_RTOIE /*!< Receiver timeout interrupt enable */ -#define LL_USART_CR1_EOBIE USART_CR1_EOBIE /*!< End of Block interrupt enable */ -#if defined(USART_CR1_FIFOEN) -#define LL_USART_CR1_TXFEIE USART_CR1_TXFEIE /*!< TX FIFO empty interrupt enable */ -#define LL_USART_CR1_RXFFIE USART_CR1_RXFFIE /*!< RX FIFO full interrupt enable */ -#endif /* USART_CR1_FIFOEN */ -#define LL_USART_CR2_LBDIE USART_CR2_LBDIE /*!< LIN break detection interrupt enable */ -#define LL_USART_CR3_EIE USART_CR3_EIE /*!< Error interrupt enable */ -#define LL_USART_CR3_CTSIE USART_CR3_CTSIE /*!< CTS interrupt enable */ -#define LL_USART_CR3_WUFIE USART_CR3_WUFIE /*!< Wakeup from Stop mode interrupt enable */ -#if defined(USART_CR1_FIFOEN) -#define LL_USART_CR3_TXFTIE USART_CR3_TXFTIE /*!< TX FIFO threshold interrupt enable */ -#endif /* USART_CR1_FIFOEN */ -#if defined(USART_TCBGT_SUPPORT) -#define LL_USART_CR3_TCBGTIE USART_CR3_TCBGTIE /*!< Transmission complete before guard time interrupt enable */ -#endif /* USART_TCBGT_SUPPORT */ -#if defined(USART_CR1_FIFOEN) -#define LL_USART_CR3_RXFTIE USART_CR3_RXFTIE /*!< RX FIFO threshold interrupt enable */ -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ - -#if defined(USART_CR1_FIFOEN) -/** @defgroup USART_LL_EC_FIFOTHRESHOLD FIFO Threshold - * @{ - */ -#define LL_USART_FIFOTHRESHOLD_1_8 0x00000000U /*!< FIFO reaches 1/8 of its depth */ -#define LL_USART_FIFOTHRESHOLD_1_4 0x00000001U /*!< FIFO reaches 1/4 of its depth */ -#define LL_USART_FIFOTHRESHOLD_1_2 0x00000002U /*!< FIFO reaches 1/2 of its depth */ -#define LL_USART_FIFOTHRESHOLD_3_4 0x00000003U /*!< FIFO reaches 3/4 of its depth */ -#define LL_USART_FIFOTHRESHOLD_7_8 0x00000004U /*!< FIFO reaches 7/8 of its depth */ -#define LL_USART_FIFOTHRESHOLD_8_8 0x00000005U /*!< FIFO becomes empty for TX and full for RX */ -/** - * @} - */ - -#endif /* USART_CR1_FIFOEN */ -/** @defgroup USART_LL_EC_DIRECTION Communication Direction - * @{ - */ -#define LL_USART_DIRECTION_NONE 0x00000000U /*!< Transmitter and Receiver are disabled */ -#define LL_USART_DIRECTION_RX USART_CR1_RE /*!< Transmitter is disabled and Receiver is enabled */ -#define LL_USART_DIRECTION_TX USART_CR1_TE /*!< Transmitter is enabled and Receiver is disabled */ -#define LL_USART_DIRECTION_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< Transmitter and Receiver are enabled */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_PARITY Parity Control - * @{ - */ -#define LL_USART_PARITY_NONE 0x00000000U /*!< Parity control disabled */ -#define LL_USART_PARITY_EVEN USART_CR1_PCE /*!< Parity control enabled and Even Parity is selected */ -#define LL_USART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Parity control enabled and Odd Parity is selected */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_WAKEUP Wakeup - * @{ - */ -#define LL_USART_WAKEUP_IDLELINE 0x00000000U /*!< USART wake up from Mute mode on Idle Line */ -#define LL_USART_WAKEUP_ADDRESSMARK USART_CR1_WAKE /*!< USART wake up from Mute mode on Address Mark */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_DATAWIDTH Datawidth - * @{ - */ -#define LL_USART_DATAWIDTH_7B USART_CR1_M1 /*!< 7 bits word length : Start bit, 7 data bits, n stop bits */ -#define LL_USART_DATAWIDTH_8B 0x00000000U /*!< 8 bits word length : Start bit, 8 data bits, n stop bits */ -#define LL_USART_DATAWIDTH_9B USART_CR1_M0 /*!< 9 bits word length : Start bit, 9 data bits, n stop bits */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_OVERSAMPLING Oversampling - * @{ - */ -#define LL_USART_OVERSAMPLING_16 0x00000000U /*!< Oversampling by 16 */ -#define LL_USART_OVERSAMPLING_8 USART_CR1_OVER8 /*!< Oversampling by 8 */ -/** - * @} - */ - -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup USART_LL_EC_CLOCK Clock Signal - * @{ - */ - -#define LL_USART_CLOCK_DISABLE 0x00000000U /*!< Clock signal not provided */ -#define LL_USART_CLOCK_ENABLE USART_CR2_CLKEN /*!< Clock signal provided */ -/** - * @} - */ -#endif /*USE_FULL_LL_DRIVER*/ - -/** @defgroup USART_LL_EC_LASTCLKPULSE Last Clock Pulse - * @{ - */ -#define LL_USART_LASTCLKPULSE_NO_OUTPUT 0x00000000U /*!< The clock pulse of the last data bit is not output to the SCLK pin */ -#define LL_USART_LASTCLKPULSE_OUTPUT USART_CR2_LBCL /*!< The clock pulse of the last data bit is output to the SCLK pin */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_PHASE Clock Phase - * @{ - */ -#define LL_USART_PHASE_1EDGE 0x00000000U /*!< The first clock transition is the first data capture edge */ -#define LL_USART_PHASE_2EDGE USART_CR2_CPHA /*!< The second clock transition is the first data capture edge */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_POLARITY Clock Polarity - * @{ - */ -#define LL_USART_POLARITY_LOW 0x00000000U /*!< Steady low value on SCLK pin outside transmission window*/ -#define LL_USART_POLARITY_HIGH USART_CR2_CPOL /*!< Steady high value on SCLK pin outside transmission window */ -/** - * @} - */ - -#if defined(USART_PRESC_PRESCALER) -/** @defgroup USART_LL_EC_PRESCALER Clock Source Prescaler - * @{ - */ -#define LL_USART_PRESCALER_DIV1 0x00000000U /*!< Input clock not divided */ -#define LL_USART_PRESCALER_DIV2 (USART_PRESC_PRESCALER_0) /*!< Input clock divided by 2 */ -#define LL_USART_PRESCALER_DIV4 (USART_PRESC_PRESCALER_1) /*!< Input clock divided by 4 */ -#define LL_USART_PRESCALER_DIV6 (USART_PRESC_PRESCALER_1 | USART_PRESC_PRESCALER_0) /*!< Input clock divided by 6 */ -#define LL_USART_PRESCALER_DIV8 (USART_PRESC_PRESCALER_2) /*!< Input clock divided by 8 */ -#define LL_USART_PRESCALER_DIV10 (USART_PRESC_PRESCALER_2 | USART_PRESC_PRESCALER_0) /*!< Input clock divided by 10 */ -#define LL_USART_PRESCALER_DIV12 (USART_PRESC_PRESCALER_2 | USART_PRESC_PRESCALER_1) /*!< Input clock divided by 12 */ -#define LL_USART_PRESCALER_DIV16 (USART_PRESC_PRESCALER_2 | USART_PRESC_PRESCALER_1 | USART_PRESC_PRESCALER_0) /*!< Input clock divided by 16 */ -#define LL_USART_PRESCALER_DIV32 (USART_PRESC_PRESCALER_3) /*!< Input clock divided by 32 */ -#define LL_USART_PRESCALER_DIV64 (USART_PRESC_PRESCALER_3 | USART_PRESC_PRESCALER_0) /*!< Input clock divided by 64 */ -#define LL_USART_PRESCALER_DIV128 (USART_PRESC_PRESCALER_3 | USART_PRESC_PRESCALER_1) /*!< Input clock divided by 128 */ -#define LL_USART_PRESCALER_DIV256 (USART_PRESC_PRESCALER_3 | USART_PRESC_PRESCALER_1 | USART_PRESC_PRESCALER_0) /*!< Input clock divided by 256 */ -/** - * @} - */ - -#endif /* USART_PRESC_PRESCALER */ -/** @defgroup USART_LL_EC_STOPBITS Stop Bits - * @{ - */ -#define LL_USART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< 0.5 stop bit */ -#define LL_USART_STOPBITS_1 0x00000000U /*!< 1 stop bit */ -#define LL_USART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< 1.5 stop bits */ -#define LL_USART_STOPBITS_2 USART_CR2_STOP_1 /*!< 2 stop bits */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_TXRX TX RX Pins Swap - * @{ - */ -#define LL_USART_TXRX_STANDARD 0x00000000U /*!< TX/RX pins are used as defined in standard pinout */ -#define LL_USART_TXRX_SWAPPED (USART_CR2_SWAP) /*!< TX and RX pins functions are swapped. */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_RXPIN_LEVEL RX Pin Active Level Inversion - * @{ - */ -#define LL_USART_RXPIN_LEVEL_STANDARD 0x00000000U /*!< RX pin signal works using the standard logic levels */ -#define LL_USART_RXPIN_LEVEL_INVERTED (USART_CR2_RXINV) /*!< RX pin signal values are inverted. */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_TXPIN_LEVEL TX Pin Active Level Inversion - * @{ - */ -#define LL_USART_TXPIN_LEVEL_STANDARD 0x00000000U /*!< TX pin signal works using the standard logic levels */ -#define LL_USART_TXPIN_LEVEL_INVERTED (USART_CR2_TXINV) /*!< TX pin signal values are inverted. */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_BINARY_LOGIC Binary Data Inversion - * @{ - */ -#define LL_USART_BINARY_LOGIC_POSITIVE 0x00000000U /*!< Logical data from the data register are send/received in positive/direct logic. (1=H, 0=L) */ -#define LL_USART_BINARY_LOGIC_NEGATIVE USART_CR2_DATAINV /*!< Logical data from the data register are send/received in negative/inverse logic. (1=L, 0=H). The parity bit is also inverted. */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_BITORDER Bit Order - * @{ - */ -#define LL_USART_BITORDER_LSBFIRST 0x00000000U /*!< data is transmitted/received with data bit 0 first, following the start bit */ -#define LL_USART_BITORDER_MSBFIRST USART_CR2_MSBFIRST /*!< data is transmitted/received with the MSB first, following the start bit */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_AUTOBAUD_DETECT_ON Autobaud Detection - * @{ - */ -#define LL_USART_AUTOBAUD_DETECT_ON_STARTBIT 0x00000000U /*!< Measurement of the start bit is used to detect the baud rate */ -#define LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE USART_CR2_ABRMODE_0 /*!< Falling edge to falling edge measurement. Received frame must start with a single bit = 1 -> Frame = Start10xxxxxx */ -#define LL_USART_AUTOBAUD_DETECT_ON_7F_FRAME USART_CR2_ABRMODE_1 /*!< 0x7F frame detection */ -#define LL_USART_AUTOBAUD_DETECT_ON_55_FRAME (USART_CR2_ABRMODE_1 | USART_CR2_ABRMODE_0) /*!< 0x55 frame detection */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_ADDRESS_DETECT Address Length Detection - * @{ - */ -#define LL_USART_ADDRESS_DETECT_4B 0x00000000U /*!< 4-bit address detection method selected */ -#define LL_USART_ADDRESS_DETECT_7B USART_CR2_ADDM7 /*!< 7-bit address detection (in 8-bit data mode) method selected */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_HWCONTROL Hardware Control - * @{ - */ -#define LL_USART_HWCONTROL_NONE 0x00000000U /*!< CTS and RTS hardware flow control disabled */ -#define LL_USART_HWCONTROL_RTS USART_CR3_RTSE /*!< RTS output enabled, data is only requested when there is space in the receive buffer */ -#define LL_USART_HWCONTROL_CTS USART_CR3_CTSE /*!< CTS mode enabled, data is only transmitted when the nCTS input is asserted (tied to 0) */ -#define LL_USART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) /*!< CTS and RTS hardware flow control enabled */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_WAKEUP_ON Wakeup Activation - * @{ - */ -#define LL_USART_WAKEUP_ON_ADDRESS 0x00000000U /*!< Wake up active on address match */ -#define LL_USART_WAKEUP_ON_STARTBIT USART_CR3_WUS_1 /*!< Wake up active on Start bit detection */ -#define LL_USART_WAKEUP_ON_RXNE (USART_CR3_WUS_0 | USART_CR3_WUS_1) /*!< Wake up active on RXNE */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_IRDA_POWER IrDA Power - * @{ - */ -#define LL_USART_IRDA_POWER_NORMAL 0x00000000U /*!< IrDA normal power mode */ -#define LL_USART_IRDA_POWER_LOW USART_CR3_IRLP /*!< IrDA low power mode */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_LINBREAK_DETECT LIN Break Detection Length - * @{ - */ -#define LL_USART_LINBREAK_DETECT_10B 0x00000000U /*!< 10-bit break detection method selected */ -#define LL_USART_LINBREAK_DETECT_11B USART_CR2_LBDL /*!< 11-bit break detection method selected */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_DE_POLARITY Driver Enable Polarity - * @{ - */ -#define LL_USART_DE_POLARITY_HIGH 0x00000000U /*!< DE signal is active high */ -#define LL_USART_DE_POLARITY_LOW USART_CR3_DEP /*!< DE signal is active low */ -/** - * @} - */ - -/** @defgroup USART_LL_EC_DMA_REG_DATA DMA Register Data - * @{ - */ -#define LL_USART_DMA_REG_DATA_TRANSMIT 0x00000000U /*!< Get address of data register used for transmission */ -#define LL_USART_DMA_REG_DATA_RECEIVE 0x00000001U /*!< Get address of data register used for reception */ -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/** @defgroup USART_LL_Exported_Macros USART Exported Macros - * @{ - */ - -/** @defgroup USART_LL_EM_WRITE_READ Common Write and read registers Macros - * @{ - */ - -/** - * @brief Write a value in USART register - * @param __INSTANCE__ USART Instance - * @param __REG__ Register to be written - * @param __VALUE__ Value to be written in the register - * @retval None - */ -#define LL_USART_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) - -/** - * @brief Read a value in USART register - * @param __INSTANCE__ USART Instance - * @param __REG__ Register to be read - * @retval Register value - */ -#define LL_USART_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) -/** - * @} - */ - -/** @defgroup USART_LL_EM_Exported_Macros_Helper Exported_Macros_Helper - * @{ - */ - -/** - * @brief Compute USARTDIV value according to Peripheral Clock and - * expected Baud Rate in 8 bits sampling mode (32 bits value of USARTDIV is returned) - * @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance - @if USART_PRESC_PRESCALER - * @param __PRESCALER__ This parameter can be one of the following values: - * @arg @ref LL_USART_PRESCALER_DIV1 - * @arg @ref LL_USART_PRESCALER_DIV2 - * @arg @ref LL_USART_PRESCALER_DIV4 - * @arg @ref LL_USART_PRESCALER_DIV6 - * @arg @ref LL_USART_PRESCALER_DIV8 - * @arg @ref LL_USART_PRESCALER_DIV10 - * @arg @ref LL_USART_PRESCALER_DIV12 - * @arg @ref LL_USART_PRESCALER_DIV16 - * @arg @ref LL_USART_PRESCALER_DIV32 - * @arg @ref LL_USART_PRESCALER_DIV64 - * @arg @ref LL_USART_PRESCALER_DIV128 - * @arg @ref LL_USART_PRESCALER_DIV256 - @endif - * @param __BAUDRATE__ Baud rate value to achieve - * @retval USARTDIV value to be used for BRR register filling in OverSampling_8 case - */ -#if defined(USART_PRESC_PRESCALER) -#define __LL_USART_DIV_SAMPLING8(__PERIPHCLK__, __PRESCALER__, __BAUDRATE__) \ - (((((__PERIPHCLK__)/(USART_PRESCALER_TAB[(__PRESCALER__)]))*2U)\ - + ((__BAUDRATE__)/2U))/(__BAUDRATE__)) -#else -#define __LL_USART_DIV_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) ((((__PERIPHCLK__)*2U)\ - + ((__BAUDRATE__)/2U))/(__BAUDRATE__)) -#endif /* USART_PRESC_PRESCALER */ - -/** - * @brief Compute USARTDIV value according to Peripheral Clock and - * expected Baud Rate in 16 bits sampling mode (32 bits value of USARTDIV is returned) - * @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance - @if USART_PRESC_PRESCALER - * @param __PRESCALER__ This parameter can be one of the following values: - * @arg @ref LL_USART_PRESCALER_DIV1 - * @arg @ref LL_USART_PRESCALER_DIV2 - * @arg @ref LL_USART_PRESCALER_DIV4 - * @arg @ref LL_USART_PRESCALER_DIV6 - * @arg @ref LL_USART_PRESCALER_DIV8 - * @arg @ref LL_USART_PRESCALER_DIV10 - * @arg @ref LL_USART_PRESCALER_DIV12 - * @arg @ref LL_USART_PRESCALER_DIV16 - * @arg @ref LL_USART_PRESCALER_DIV32 - * @arg @ref LL_USART_PRESCALER_DIV64 - * @arg @ref LL_USART_PRESCALER_DIV128 - * @arg @ref LL_USART_PRESCALER_DIV256 - @endif - * @param __BAUDRATE__ Baud rate value to achieve - * @retval USARTDIV value to be used for BRR register filling in OverSampling_16 case - */ -#if defined(USART_PRESC_PRESCALER) -#define __LL_USART_DIV_SAMPLING16(__PERIPHCLK__, __PRESCALER__, __BAUDRATE__) \ - ((((__PERIPHCLK__)/(USART_PRESCALER_TAB[(__PRESCALER__)]))\ - + ((__BAUDRATE__)/2U))/(__BAUDRATE__)) -#else -#define __LL_USART_DIV_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) (((__PERIPHCLK__) + ((__BAUDRATE__)/2U))/(__BAUDRATE__)) -#endif /* USART_PRESC_PRESCALER */ - -/** - * @} - */ - -/** - * @} - */ - -/* Exported functions --------------------------------------------------------*/ - -/** @defgroup USART_LL_Exported_Functions USART Exported Functions - * @{ - */ - -/** @defgroup USART_LL_EF_Configuration Configuration functions - * @{ - */ - -/** - * @brief USART Enable - * @rmtoll CR1 UE LL_USART_Enable - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_Enable(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR1, USART_CR1_UE); -} - -/** - * @brief USART Disable (all USART prescalers and outputs are disabled) - * @note When USART is disabled, USART prescalers and outputs are stopped immediately, - * and current operations are discarded. The configuration of the USART is kept, but all the status - * flags, in the USARTx_ISR are set to their default values. - * @rmtoll CR1 UE LL_USART_Disable - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_Disable(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR1, USART_CR1_UE); -} - -/** - * @brief Indicate if USART is enabled - * @rmtoll CR1 UE LL_USART_IsEnabled - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabled(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_UE) == (USART_CR1_UE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief FIFO Mode Enable - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 FIFOEN LL_USART_EnableFIFO - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableFIFO(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR1, USART_CR1_FIFOEN); -} - -/** - * @brief FIFO Mode Disable - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 FIFOEN LL_USART_DisableFIFO - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableFIFO(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR1, USART_CR1_FIFOEN); -} - -/** - * @brief Indicate if FIFO Mode is enabled - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 FIFOEN LL_USART_IsEnabledFIFO - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledFIFO(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_FIFOEN) == (USART_CR1_FIFOEN)) ? 1UL : 0UL); -} - -/** - * @brief Configure TX FIFO Threshold - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 TXFTCFG LL_USART_SetTXFIFOThreshold - * @param USARTx USART Instance - * @param Threshold This parameter can be one of the following values: - * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 - * @retval None - */ -__STATIC_INLINE void LL_USART_SetTXFIFOThreshold(USART_TypeDef *USARTx, uint32_t Threshold) -{ - ATOMIC_MODIFY_REG(USARTx->CR3, USART_CR3_TXFTCFG, Threshold << USART_CR3_TXFTCFG_Pos); -} - -/** - * @brief Return TX FIFO Threshold Configuration - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 TXFTCFG LL_USART_GetTXFIFOThreshold - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 - */ -__STATIC_INLINE uint32_t LL_USART_GetTXFIFOThreshold(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos); -} - -/** - * @brief Configure RX FIFO Threshold - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 RXFTCFG LL_USART_SetRXFIFOThreshold - * @param USARTx USART Instance - * @param Threshold This parameter can be one of the following values: - * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 - * @retval None - */ -__STATIC_INLINE void LL_USART_SetRXFIFOThreshold(USART_TypeDef *USARTx, uint32_t Threshold) -{ - ATOMIC_MODIFY_REG(USARTx->CR3, USART_CR3_RXFTCFG, Threshold << USART_CR3_RXFTCFG_Pos); -} - -/** - * @brief Return RX FIFO Threshold Configuration - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 RXFTCFG LL_USART_GetRXFIFOThreshold - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 - */ -__STATIC_INLINE uint32_t LL_USART_GetRXFIFOThreshold(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos); -} - -/** - * @brief Configure TX and RX FIFOs Threshold - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 TXFTCFG LL_USART_ConfigFIFOsThreshold\n - * CR3 RXFTCFG LL_USART_ConfigFIFOsThreshold - * @param USARTx USART Instance - * @param TXThreshold This parameter can be one of the following values: - * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 - * @param RXThreshold This parameter can be one of the following values: - * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 - * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 - * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 - * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigFIFOsThreshold(USART_TypeDef *USARTx, uint32_t TXThreshold, uint32_t RXThreshold) -{ - ATOMIC_MODIFY_REG(USARTx->CR3, USART_CR3_TXFTCFG | USART_CR3_RXFTCFG, (TXThreshold << USART_CR3_TXFTCFG_Pos) | - (RXThreshold << USART_CR3_RXFTCFG_Pos)); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief USART enabled in STOP Mode. - * @note When this function is enabled, USART is able to wake up the MCU from Stop mode, provided that - * USART clock selection is HSI or LSE in RCC. - * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not - * Wake-up from Stop mode feature is supported by the USARTx instance. - * @rmtoll CR1 UESM LL_USART_EnableInStopMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableInStopMode(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_UESM); -} - -/** - * @brief USART disabled in STOP Mode. - * @note When this function is disabled, USART is not able to wake up the MCU from Stop mode - * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not - * Wake-up from Stop mode feature is supported by the USARTx instance. - * @rmtoll CR1 UESM LL_USART_DisableInStopMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableInStopMode(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_UESM); -} - -/** - * @brief Indicate if USART is enabled in STOP Mode (able to wake up MCU from Stop mode or not) - * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not - * Wake-up from Stop mode feature is supported by the USARTx instance. - * @rmtoll CR1 UESM LL_USART_IsEnabledInStopMode - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledInStopMode(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_UESM) == (USART_CR1_UESM)) ? 1UL : 0UL); -} - -#if defined(USART_CR3_UCESM) -/** - * @brief USART Clock enabled in STOP Mode - * @note When this function is called, USART Clock is enabled while in STOP mode - * @rmtoll CR3 UCESM LL_USART_EnableClockInStopMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableClockInStopMode(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_UCESM); -} - -/** - * @brief USART clock disabled in STOP Mode - * @note When this function is called, USART Clock is disabled while in STOP mode - * @rmtoll CR3 UCESM LL_USART_DisableClockInStopMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableClockInStopMode(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_UCESM); -} - -/** - * @brief Indicate if USART clock is enabled in STOP Mode - * @rmtoll CR3 UCESM LL_USART_IsClockEnabledInStopMode - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsClockEnabledInStopMode(const USART_TypeDef *USARTx) -{ - return (READ_BIT(USARTx->CR3, USART_CR3_UCESM) == (USART_CR3_UCESM)); -} - -#endif /* USART_CR3_UCESM */ -/** - * @brief Receiver Enable (Receiver is enabled and begins searching for a start bit) - * @rmtoll CR1 RE LL_USART_EnableDirectionRx - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableDirectionRx(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RE); -} - -/** - * @brief Receiver Disable - * @rmtoll CR1 RE LL_USART_DisableDirectionRx - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableDirectionRx(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RE); -} - -/** - * @brief Transmitter Enable - * @rmtoll CR1 TE LL_USART_EnableDirectionTx - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableDirectionTx(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TE); -} - -/** - * @brief Transmitter Disable - * @rmtoll CR1 TE LL_USART_DisableDirectionTx - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableDirectionTx(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TE); -} - -/** - * @brief Configure simultaneously enabled/disabled states - * of Transmitter and Receiver - * @rmtoll CR1 RE LL_USART_SetTransferDirection\n - * CR1 TE LL_USART_SetTransferDirection - * @param USARTx USART Instance - * @param TransferDirection This parameter can be one of the following values: - * @arg @ref LL_USART_DIRECTION_NONE - * @arg @ref LL_USART_DIRECTION_RX - * @arg @ref LL_USART_DIRECTION_TX - * @arg @ref LL_USART_DIRECTION_TX_RX - * @retval None - */ -__STATIC_INLINE void LL_USART_SetTransferDirection(USART_TypeDef *USARTx, uint32_t TransferDirection) -{ - ATOMIC_MODIFY_REG(USARTx->CR1, USART_CR1_RE | USART_CR1_TE, TransferDirection); -} - -/** - * @brief Return enabled/disabled states of Transmitter and Receiver - * @rmtoll CR1 RE LL_USART_GetTransferDirection\n - * CR1 TE LL_USART_GetTransferDirection - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_DIRECTION_NONE - * @arg @ref LL_USART_DIRECTION_RX - * @arg @ref LL_USART_DIRECTION_TX - * @arg @ref LL_USART_DIRECTION_TX_RX - */ -__STATIC_INLINE uint32_t LL_USART_GetTransferDirection(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_RE | USART_CR1_TE)); -} - -/** - * @brief Configure Parity (enabled/disabled and parity mode if enabled). - * @note This function selects if hardware parity control (generation and detection) is enabled or disabled. - * When the parity control is enabled (Odd or Even), computed parity bit is inserted at the MSB position - * (9th or 8th bit depending on data width) and parity is checked on the received data. - * @rmtoll CR1 PS LL_USART_SetParity\n - * CR1 PCE LL_USART_SetParity - * @param USARTx USART Instance - * @param Parity This parameter can be one of the following values: - * @arg @ref LL_USART_PARITY_NONE - * @arg @ref LL_USART_PARITY_EVEN - * @arg @ref LL_USART_PARITY_ODD - * @retval None - */ -__STATIC_INLINE void LL_USART_SetParity(USART_TypeDef *USARTx, uint32_t Parity) -{ - MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE, Parity); -} - -/** - * @brief Return Parity configuration (enabled/disabled and parity mode if enabled) - * @rmtoll CR1 PS LL_USART_GetParity\n - * CR1 PCE LL_USART_GetParity - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_PARITY_NONE - * @arg @ref LL_USART_PARITY_EVEN - * @arg @ref LL_USART_PARITY_ODD - */ -__STATIC_INLINE uint32_t LL_USART_GetParity(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE)); -} - -/** - * @brief Set Receiver Wake Up method from Mute mode. - * @rmtoll CR1 WAKE LL_USART_SetWakeUpMethod - * @param USARTx USART Instance - * @param Method This parameter can be one of the following values: - * @arg @ref LL_USART_WAKEUP_IDLELINE - * @arg @ref LL_USART_WAKEUP_ADDRESSMARK - * @retval None - */ -__STATIC_INLINE void LL_USART_SetWakeUpMethod(USART_TypeDef *USARTx, uint32_t Method) -{ - MODIFY_REG(USARTx->CR1, USART_CR1_WAKE, Method); -} - -/** - * @brief Return Receiver Wake Up method from Mute mode - * @rmtoll CR1 WAKE LL_USART_GetWakeUpMethod - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_WAKEUP_IDLELINE - * @arg @ref LL_USART_WAKEUP_ADDRESSMARK - */ -__STATIC_INLINE uint32_t LL_USART_GetWakeUpMethod(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_WAKE)); -} - -/** - * @brief Set Word length (i.e. nb of data bits, excluding start and stop bits) - * @rmtoll CR1 M0 LL_USART_SetDataWidth\n - * CR1 M1 LL_USART_SetDataWidth - * @param USARTx USART Instance - * @param DataWidth This parameter can be one of the following values: - * @arg @ref LL_USART_DATAWIDTH_7B - * @arg @ref LL_USART_DATAWIDTH_8B - * @arg @ref LL_USART_DATAWIDTH_9B - * @retval None - */ -__STATIC_INLINE void LL_USART_SetDataWidth(USART_TypeDef *USARTx, uint32_t DataWidth) -{ - MODIFY_REG(USARTx->CR1, USART_CR1_M, DataWidth); -} - -/** - * @brief Return Word length (i.e. nb of data bits, excluding start and stop bits) - * @rmtoll CR1 M0 LL_USART_GetDataWidth\n - * CR1 M1 LL_USART_GetDataWidth - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_DATAWIDTH_7B - * @arg @ref LL_USART_DATAWIDTH_8B - * @arg @ref LL_USART_DATAWIDTH_9B - */ -__STATIC_INLINE uint32_t LL_USART_GetDataWidth(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_M)); -} - -/** - * @brief Allow switch between Mute Mode and Active mode - * @rmtoll CR1 MME LL_USART_EnableMuteMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableMuteMode(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_MME); -} - -/** - * @brief Prevent Mute Mode use. Set Receiver in active mode permanently. - * @rmtoll CR1 MME LL_USART_DisableMuteMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableMuteMode(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_MME); -} - -/** - * @brief Indicate if switch between Mute Mode and Active mode is allowed - * @rmtoll CR1 MME LL_USART_IsEnabledMuteMode - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledMuteMode(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_MME) == (USART_CR1_MME)) ? 1UL : 0UL); -} - -/** - * @brief Set Oversampling to 8-bit or 16-bit mode - * @rmtoll CR1 OVER8 LL_USART_SetOverSampling - * @param USARTx USART Instance - * @param OverSampling This parameter can be one of the following values: - * @arg @ref LL_USART_OVERSAMPLING_16 - * @arg @ref LL_USART_OVERSAMPLING_8 - * @retval None - */ -__STATIC_INLINE void LL_USART_SetOverSampling(USART_TypeDef *USARTx, uint32_t OverSampling) -{ - MODIFY_REG(USARTx->CR1, USART_CR1_OVER8, OverSampling); -} - -/** - * @brief Return Oversampling mode - * @rmtoll CR1 OVER8 LL_USART_GetOverSampling - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_OVERSAMPLING_16 - * @arg @ref LL_USART_OVERSAMPLING_8 - */ -__STATIC_INLINE uint32_t LL_USART_GetOverSampling(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_OVER8)); -} - -/** - * @brief Configure if Clock pulse of the last data bit is output to the SCLK pin or not - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @rmtoll CR2 LBCL LL_USART_SetLastClkPulseOutput - * @param USARTx USART Instance - * @param LastBitClockPulse This parameter can be one of the following values: - * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT - * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT - * @retval None - */ -__STATIC_INLINE void LL_USART_SetLastClkPulseOutput(USART_TypeDef *USARTx, uint32_t LastBitClockPulse) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_LBCL, LastBitClockPulse); -} - -/** - * @brief Retrieve Clock pulse of the last data bit output configuration - * (Last bit Clock pulse output to the SCLK pin or not) - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @rmtoll CR2 LBCL LL_USART_GetLastClkPulseOutput - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT - * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT - */ -__STATIC_INLINE uint32_t LL_USART_GetLastClkPulseOutput(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBCL)); -} - -/** - * @brief Select the phase of the clock output on the SCLK pin in synchronous mode - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @rmtoll CR2 CPHA LL_USART_SetClockPhase - * @param USARTx USART Instance - * @param ClockPhase This parameter can be one of the following values: - * @arg @ref LL_USART_PHASE_1EDGE - * @arg @ref LL_USART_PHASE_2EDGE - * @retval None - */ -__STATIC_INLINE void LL_USART_SetClockPhase(USART_TypeDef *USARTx, uint32_t ClockPhase) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_CPHA, ClockPhase); -} - -/** - * @brief Return phase of the clock output on the SCLK pin in synchronous mode - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @rmtoll CR2 CPHA LL_USART_GetClockPhase - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_PHASE_1EDGE - * @arg @ref LL_USART_PHASE_2EDGE - */ -__STATIC_INLINE uint32_t LL_USART_GetClockPhase(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPHA)); -} - -/** - * @brief Select the polarity of the clock output on the SCLK pin in synchronous mode - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @rmtoll CR2 CPOL LL_USART_SetClockPolarity - * @param USARTx USART Instance - * @param ClockPolarity This parameter can be one of the following values: - * @arg @ref LL_USART_POLARITY_LOW - * @arg @ref LL_USART_POLARITY_HIGH - * @retval None - */ -__STATIC_INLINE void LL_USART_SetClockPolarity(USART_TypeDef *USARTx, uint32_t ClockPolarity) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_CPOL, ClockPolarity); -} - -/** - * @brief Return polarity of the clock output on the SCLK pin in synchronous mode - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @rmtoll CR2 CPOL LL_USART_GetClockPolarity - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_POLARITY_LOW - * @arg @ref LL_USART_POLARITY_HIGH - */ -__STATIC_INLINE uint32_t LL_USART_GetClockPolarity(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPOL)); -} - -/** - * @brief Configure Clock signal format (Phase Polarity and choice about output of last bit clock pulse) - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @note Call of this function is equivalent to following function call sequence : - * - Clock Phase configuration using @ref LL_USART_SetClockPhase() function - * - Clock Polarity configuration using @ref LL_USART_SetClockPolarity() function - * - Output of Last bit Clock pulse configuration using @ref LL_USART_SetLastClkPulseOutput() function - * @rmtoll CR2 CPHA LL_USART_ConfigClock\n - * CR2 CPOL LL_USART_ConfigClock\n - * CR2 LBCL LL_USART_ConfigClock - * @param USARTx USART Instance - * @param Phase This parameter can be one of the following values: - * @arg @ref LL_USART_PHASE_1EDGE - * @arg @ref LL_USART_PHASE_2EDGE - * @param Polarity This parameter can be one of the following values: - * @arg @ref LL_USART_POLARITY_LOW - * @arg @ref LL_USART_POLARITY_HIGH - * @param LBCPOutput This parameter can be one of the following values: - * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT - * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigClock(USART_TypeDef *USARTx, uint32_t Phase, uint32_t Polarity, uint32_t LBCPOutput) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL, Phase | Polarity | LBCPOutput); -} - -#if defined(USART_PRESC_PRESCALER) -/** - * @brief Configure Clock source prescaler for baudrate generator and oversampling - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll PRESC PRESCALER LL_USART_SetPrescaler - * @param USARTx USART Instance - * @param PrescalerValue This parameter can be one of the following values: - * @arg @ref LL_USART_PRESCALER_DIV1 - * @arg @ref LL_USART_PRESCALER_DIV2 - * @arg @ref LL_USART_PRESCALER_DIV4 - * @arg @ref LL_USART_PRESCALER_DIV6 - * @arg @ref LL_USART_PRESCALER_DIV8 - * @arg @ref LL_USART_PRESCALER_DIV10 - * @arg @ref LL_USART_PRESCALER_DIV12 - * @arg @ref LL_USART_PRESCALER_DIV16 - * @arg @ref LL_USART_PRESCALER_DIV32 - * @arg @ref LL_USART_PRESCALER_DIV64 - * @arg @ref LL_USART_PRESCALER_DIV128 - * @arg @ref LL_USART_PRESCALER_DIV256 - * @retval None - */ -__STATIC_INLINE void LL_USART_SetPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue) -{ - MODIFY_REG(USARTx->PRESC, USART_PRESC_PRESCALER, (uint16_t)PrescalerValue); -} - -/** - * @brief Retrieve the Clock source prescaler for baudrate generator and oversampling - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll PRESC PRESCALER LL_USART_GetPrescaler - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_PRESCALER_DIV1 - * @arg @ref LL_USART_PRESCALER_DIV2 - * @arg @ref LL_USART_PRESCALER_DIV4 - * @arg @ref LL_USART_PRESCALER_DIV6 - * @arg @ref LL_USART_PRESCALER_DIV8 - * @arg @ref LL_USART_PRESCALER_DIV10 - * @arg @ref LL_USART_PRESCALER_DIV12 - * @arg @ref LL_USART_PRESCALER_DIV16 - * @arg @ref LL_USART_PRESCALER_DIV32 - * @arg @ref LL_USART_PRESCALER_DIV64 - * @arg @ref LL_USART_PRESCALER_DIV128 - * @arg @ref LL_USART_PRESCALER_DIV256 - */ -__STATIC_INLINE uint32_t LL_USART_GetPrescaler(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->PRESC, USART_PRESC_PRESCALER)); -} - -#endif /* USART_PRESC_PRESCALER */ -/** - * @brief Enable Clock output on SCLK pin - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @rmtoll CR2 CLKEN LL_USART_EnableSCLKOutput - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableSCLKOutput(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR2, USART_CR2_CLKEN); -} - -/** - * @brief Disable Clock output on SCLK pin - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @rmtoll CR2 CLKEN LL_USART_DisableSCLKOutput - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableSCLKOutput(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR2, USART_CR2_CLKEN); -} - -/** - * @brief Indicate if Clock output on SCLK pin is enabled - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @rmtoll CR2 CLKEN LL_USART_IsEnabledSCLKOutput - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledSCLKOutput(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR2, USART_CR2_CLKEN) == (USART_CR2_CLKEN)) ? 1UL : 0UL); -} - -/** - * @brief Set the length of the stop bits - * @rmtoll CR2 STOP LL_USART_SetStopBitsLength - * @param USARTx USART Instance - * @param StopBits This parameter can be one of the following values: - * @arg @ref LL_USART_STOPBITS_0_5 - * @arg @ref LL_USART_STOPBITS_1 - * @arg @ref LL_USART_STOPBITS_1_5 - * @arg @ref LL_USART_STOPBITS_2 - * @retval None - */ -__STATIC_INLINE void LL_USART_SetStopBitsLength(USART_TypeDef *USARTx, uint32_t StopBits) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits); -} - -/** - * @brief Retrieve the length of the stop bits - * @rmtoll CR2 STOP LL_USART_GetStopBitsLength - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_STOPBITS_0_5 - * @arg @ref LL_USART_STOPBITS_1 - * @arg @ref LL_USART_STOPBITS_1_5 - * @arg @ref LL_USART_STOPBITS_2 - */ -__STATIC_INLINE uint32_t LL_USART_GetStopBitsLength(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_STOP)); -} - -/** - * @brief Configure Character frame format (Datawidth, Parity control, Stop Bits) - * @note Call of this function is equivalent to following function call sequence : - * - Data Width configuration using @ref LL_USART_SetDataWidth() function - * - Parity Control and mode configuration using @ref LL_USART_SetParity() function - * - Stop bits configuration using @ref LL_USART_SetStopBitsLength() function - * @rmtoll CR1 PS LL_USART_ConfigCharacter\n - * CR1 PCE LL_USART_ConfigCharacter\n - * CR1 M0 LL_USART_ConfigCharacter\n - * CR1 M1 LL_USART_ConfigCharacter\n - * CR2 STOP LL_USART_ConfigCharacter - * @param USARTx USART Instance - * @param DataWidth This parameter can be one of the following values: - * @arg @ref LL_USART_DATAWIDTH_7B - * @arg @ref LL_USART_DATAWIDTH_8B - * @arg @ref LL_USART_DATAWIDTH_9B - * @param Parity This parameter can be one of the following values: - * @arg @ref LL_USART_PARITY_NONE - * @arg @ref LL_USART_PARITY_EVEN - * @arg @ref LL_USART_PARITY_ODD - * @param StopBits This parameter can be one of the following values: - * @arg @ref LL_USART_STOPBITS_0_5 - * @arg @ref LL_USART_STOPBITS_1 - * @arg @ref LL_USART_STOPBITS_1_5 - * @arg @ref LL_USART_STOPBITS_2 - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigCharacter(USART_TypeDef *USARTx, uint32_t DataWidth, uint32_t Parity, - uint32_t StopBits) -{ - MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE | USART_CR1_M, Parity | DataWidth); - MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits); -} - -/** - * @brief Configure TX/RX pins swapping setting. - * @rmtoll CR2 SWAP LL_USART_SetTXRXSwap - * @param USARTx USART Instance - * @param SwapConfig This parameter can be one of the following values: - * @arg @ref LL_USART_TXRX_STANDARD - * @arg @ref LL_USART_TXRX_SWAPPED - * @retval None - */ -__STATIC_INLINE void LL_USART_SetTXRXSwap(USART_TypeDef *USARTx, uint32_t SwapConfig) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_SWAP, SwapConfig); -} - -/** - * @brief Retrieve TX/RX pins swapping configuration. - * @rmtoll CR2 SWAP LL_USART_GetTXRXSwap - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_TXRX_STANDARD - * @arg @ref LL_USART_TXRX_SWAPPED - */ -__STATIC_INLINE uint32_t LL_USART_GetTXRXSwap(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_SWAP)); -} - -/** - * @brief Configure RX pin active level logic - * @rmtoll CR2 RXINV LL_USART_SetRXPinLevel - * @param USARTx USART Instance - * @param PinInvMethod This parameter can be one of the following values: - * @arg @ref LL_USART_RXPIN_LEVEL_STANDARD - * @arg @ref LL_USART_RXPIN_LEVEL_INVERTED - * @retval None - */ -__STATIC_INLINE void LL_USART_SetRXPinLevel(USART_TypeDef *USARTx, uint32_t PinInvMethod) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_RXINV, PinInvMethod); -} - -/** - * @brief Retrieve RX pin active level logic configuration - * @rmtoll CR2 RXINV LL_USART_GetRXPinLevel - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_RXPIN_LEVEL_STANDARD - * @arg @ref LL_USART_RXPIN_LEVEL_INVERTED - */ -__STATIC_INLINE uint32_t LL_USART_GetRXPinLevel(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_RXINV)); -} - -/** - * @brief Configure TX pin active level logic - * @rmtoll CR2 TXINV LL_USART_SetTXPinLevel - * @param USARTx USART Instance - * @param PinInvMethod This parameter can be one of the following values: - * @arg @ref LL_USART_TXPIN_LEVEL_STANDARD - * @arg @ref LL_USART_TXPIN_LEVEL_INVERTED - * @retval None - */ -__STATIC_INLINE void LL_USART_SetTXPinLevel(USART_TypeDef *USARTx, uint32_t PinInvMethod) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_TXINV, PinInvMethod); -} - -/** - * @brief Retrieve TX pin active level logic configuration - * @rmtoll CR2 TXINV LL_USART_GetTXPinLevel - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_TXPIN_LEVEL_STANDARD - * @arg @ref LL_USART_TXPIN_LEVEL_INVERTED - */ -__STATIC_INLINE uint32_t LL_USART_GetTXPinLevel(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_TXINV)); -} - -/** - * @brief Configure Binary data logic. - * @note Allow to define how Logical data from the data register are send/received : - * either in positive/direct logic (1=H, 0=L) or in negative/inverse logic (1=L, 0=H) - * @rmtoll CR2 DATAINV LL_USART_SetBinaryDataLogic - * @param USARTx USART Instance - * @param DataLogic This parameter can be one of the following values: - * @arg @ref LL_USART_BINARY_LOGIC_POSITIVE - * @arg @ref LL_USART_BINARY_LOGIC_NEGATIVE - * @retval None - */ -__STATIC_INLINE void LL_USART_SetBinaryDataLogic(USART_TypeDef *USARTx, uint32_t DataLogic) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_DATAINV, DataLogic); -} - -/** - * @brief Retrieve Binary data configuration - * @rmtoll CR2 DATAINV LL_USART_GetBinaryDataLogic - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_BINARY_LOGIC_POSITIVE - * @arg @ref LL_USART_BINARY_LOGIC_NEGATIVE - */ -__STATIC_INLINE uint32_t LL_USART_GetBinaryDataLogic(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_DATAINV)); -} - -/** - * @brief Configure transfer bit order (either Less or Most Significant Bit First) - * @note MSB First means data is transmitted/received with the MSB first, following the start bit. - * LSB First means data is transmitted/received with data bit 0 first, following the start bit. - * @rmtoll CR2 MSBFIRST LL_USART_SetTransferBitOrder - * @param USARTx USART Instance - * @param BitOrder This parameter can be one of the following values: - * @arg @ref LL_USART_BITORDER_LSBFIRST - * @arg @ref LL_USART_BITORDER_MSBFIRST - * @retval None - */ -__STATIC_INLINE void LL_USART_SetTransferBitOrder(USART_TypeDef *USARTx, uint32_t BitOrder) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_MSBFIRST, BitOrder); -} - -/** - * @brief Return transfer bit order (either Less or Most Significant Bit First) - * @note MSB First means data is transmitted/received with the MSB first, following the start bit. - * LSB First means data is transmitted/received with data bit 0 first, following the start bit. - * @rmtoll CR2 MSBFIRST LL_USART_GetTransferBitOrder - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_BITORDER_LSBFIRST - * @arg @ref LL_USART_BITORDER_MSBFIRST - */ -__STATIC_INLINE uint32_t LL_USART_GetTransferBitOrder(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_MSBFIRST)); -} - -/** - * @brief Enable Auto Baud-Rate Detection - * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not - * Auto Baud Rate detection feature is supported by the USARTx instance. - * @rmtoll CR2 ABREN LL_USART_EnableAutoBaudRate - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableAutoBaudRate(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR2, USART_CR2_ABREN); -} - -/** - * @brief Disable Auto Baud-Rate Detection - * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not - * Auto Baud Rate detection feature is supported by the USARTx instance. - * @rmtoll CR2 ABREN LL_USART_DisableAutoBaudRate - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableAutoBaudRate(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR2, USART_CR2_ABREN); -} - -/** - * @brief Indicate if Auto Baud-Rate Detection mechanism is enabled - * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not - * Auto Baud Rate detection feature is supported by the USARTx instance. - * @rmtoll CR2 ABREN LL_USART_IsEnabledAutoBaud - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledAutoBaud(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR2, USART_CR2_ABREN) == (USART_CR2_ABREN)) ? 1UL : 0UL); -} - -/** - * @brief Set Auto Baud-Rate mode bits - * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not - * Auto Baud Rate detection feature is supported by the USARTx instance. - * @rmtoll CR2 ABRMODE LL_USART_SetAutoBaudRateMode - * @param USARTx USART Instance - * @param AutoBaudRateMode This parameter can be one of the following values: - * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_STARTBIT - * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE - * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_7F_FRAME - * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_55_FRAME - * @retval None - */ -__STATIC_INLINE void LL_USART_SetAutoBaudRateMode(USART_TypeDef *USARTx, uint32_t AutoBaudRateMode) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_ABRMODE, AutoBaudRateMode); -} - -/** - * @brief Return Auto Baud-Rate mode - * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not - * Auto Baud Rate detection feature is supported by the USARTx instance. - * @rmtoll CR2 ABRMODE LL_USART_GetAutoBaudRateMode - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_STARTBIT - * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE - * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_7F_FRAME - * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_55_FRAME - */ -__STATIC_INLINE uint32_t LL_USART_GetAutoBaudRateMode(USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ABRMODE)); -} - -/** - * @brief Enable Receiver Timeout - * @rmtoll CR2 RTOEN LL_USART_EnableRxTimeout - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableRxTimeout(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR2, USART_CR2_RTOEN); -} - -/** - * @brief Disable Receiver Timeout - * @rmtoll CR2 RTOEN LL_USART_DisableRxTimeout - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableRxTimeout(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR2, USART_CR2_RTOEN); -} - -/** - * @brief Indicate if Receiver Timeout feature is enabled - * @rmtoll CR2 RTOEN LL_USART_IsEnabledRxTimeout - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledRxTimeout(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR2, USART_CR2_RTOEN) == (USART_CR2_RTOEN)) ? 1UL : 0UL); -} - -/** - * @brief Set Address of the USART node. - * @note This is used in multiprocessor communication during Mute mode or Stop mode, - * for wake up with address mark detection. - * @note 4bits address node is used when 4-bit Address Detection is selected in ADDM7. - * (b7-b4 should be set to 0) - * 8bits address node is used when 7-bit Address Detection is selected in ADDM7. - * (This is used in multiprocessor communication during Mute mode or Stop mode, - * for wake up with 7-bit address mark detection. - * The MSB of the character sent by the transmitter should be equal to 1. - * It may also be used for character detection during normal reception, - * Mute mode inactive (for example, end of block detection in ModBus protocol). - * In this case, the whole received character (8-bit) is compared to the ADD[7:0] - * value and CMF flag is set on match) - * @rmtoll CR2 ADD LL_USART_ConfigNodeAddress\n - * CR2 ADDM7 LL_USART_ConfigNodeAddress - * @param USARTx USART Instance - * @param AddressLen This parameter can be one of the following values: - * @arg @ref LL_USART_ADDRESS_DETECT_4B - * @arg @ref LL_USART_ADDRESS_DETECT_7B - * @param NodeAddress 4 or 7 bit Address of the USART node. - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigNodeAddress(USART_TypeDef *USARTx, uint32_t AddressLen, uint32_t NodeAddress) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_ADD | USART_CR2_ADDM7, - (uint32_t)(AddressLen | (NodeAddress << USART_CR2_ADD_Pos))); -} - -/** - * @brief Return 8 bit Address of the USART node as set in ADD field of CR2. - * @note If 4-bit Address Detection is selected in ADDM7, - * only 4bits (b3-b0) of returned value are relevant (b31-b4 are not relevant) - * If 7-bit Address Detection is selected in ADDM7, - * only 8bits (b7-b0) of returned value are relevant (b31-b8 are not relevant) - * @rmtoll CR2 ADD LL_USART_GetNodeAddress - * @param USARTx USART Instance - * @retval Address of the USART node (Value between Min_Data=0 and Max_Data=255) - */ -__STATIC_INLINE uint32_t LL_USART_GetNodeAddress(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ADD) >> USART_CR2_ADD_Pos); -} - -/** - * @brief Return Length of Node Address used in Address Detection mode (7-bit or 4-bit) - * @rmtoll CR2 ADDM7 LL_USART_GetNodeAddressLen - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_ADDRESS_DETECT_4B - * @arg @ref LL_USART_ADDRESS_DETECT_7B - */ -__STATIC_INLINE uint32_t LL_USART_GetNodeAddressLen(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ADDM7)); -} - -/** - * @brief Enable RTS HW Flow Control - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll CR3 RTSE LL_USART_EnableRTSHWFlowCtrl - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableRTSHWFlowCtrl(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR3, USART_CR3_RTSE); -} - -/** - * @brief Disable RTS HW Flow Control - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll CR3 RTSE LL_USART_DisableRTSHWFlowCtrl - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableRTSHWFlowCtrl(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR3, USART_CR3_RTSE); -} - -/** - * @brief Enable CTS HW Flow Control - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll CR3 CTSE LL_USART_EnableCTSHWFlowCtrl - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableCTSHWFlowCtrl(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR3, USART_CR3_CTSE); -} - -/** - * @brief Disable CTS HW Flow Control - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll CR3 CTSE LL_USART_DisableCTSHWFlowCtrl - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableCTSHWFlowCtrl(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR3, USART_CR3_CTSE); -} - -/** - * @brief Configure HW Flow Control mode (both CTS and RTS) - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll CR3 RTSE LL_USART_SetHWFlowCtrl\n - * CR3 CTSE LL_USART_SetHWFlowCtrl - * @param USARTx USART Instance - * @param HardwareFlowControl This parameter can be one of the following values: - * @arg @ref LL_USART_HWCONTROL_NONE - * @arg @ref LL_USART_HWCONTROL_RTS - * @arg @ref LL_USART_HWCONTROL_CTS - * @arg @ref LL_USART_HWCONTROL_RTS_CTS - * @retval None - */ -__STATIC_INLINE void LL_USART_SetHWFlowCtrl(USART_TypeDef *USARTx, uint32_t HardwareFlowControl) -{ - MODIFY_REG(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE, HardwareFlowControl); -} - -/** - * @brief Return HW Flow Control configuration (both CTS and RTS) - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll CR3 RTSE LL_USART_GetHWFlowCtrl\n - * CR3 CTSE LL_USART_GetHWFlowCtrl - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_HWCONTROL_NONE - * @arg @ref LL_USART_HWCONTROL_RTS - * @arg @ref LL_USART_HWCONTROL_CTS - * @arg @ref LL_USART_HWCONTROL_RTS_CTS - */ -__STATIC_INLINE uint32_t LL_USART_GetHWFlowCtrl(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE)); -} - -/** - * @brief Enable One bit sampling method - * @rmtoll CR3 ONEBIT LL_USART_EnableOneBitSamp - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableOneBitSamp(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR3, USART_CR3_ONEBIT); -} - -/** - * @brief Disable One bit sampling method - * @rmtoll CR3 ONEBIT LL_USART_DisableOneBitSamp - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableOneBitSamp(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR3, USART_CR3_ONEBIT); -} - -/** - * @brief Indicate if One bit sampling method is enabled - * @rmtoll CR3 ONEBIT LL_USART_IsEnabledOneBitSamp - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledOneBitSamp(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_ONEBIT) == (USART_CR3_ONEBIT)) ? 1UL : 0UL); -} - -/** - * @brief Enable Overrun detection - * @rmtoll CR3 OVRDIS LL_USART_EnableOverrunDetect - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableOverrunDetect(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR3, USART_CR3_OVRDIS); -} - -/** - * @brief Disable Overrun detection - * @rmtoll CR3 OVRDIS LL_USART_DisableOverrunDetect - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableOverrunDetect(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR3, USART_CR3_OVRDIS); -} - -/** - * @brief Indicate if Overrun detection is enabled - * @rmtoll CR3 OVRDIS LL_USART_IsEnabledOverrunDetect - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledOverrunDetect(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_OVRDIS) != USART_CR3_OVRDIS) ? 1UL : 0UL); -} - -/** - * @brief Select event type for Wake UP Interrupt Flag (WUS[1:0] bits) - * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not - * Wake-up from Stop mode feature is supported by the USARTx instance. - * @rmtoll CR3 WUS LL_USART_SetWKUPType - * @param USARTx USART Instance - * @param Type This parameter can be one of the following values: - * @arg @ref LL_USART_WAKEUP_ON_ADDRESS - * @arg @ref LL_USART_WAKEUP_ON_STARTBIT - * @arg @ref LL_USART_WAKEUP_ON_RXNE - * @retval None - */ -__STATIC_INLINE void LL_USART_SetWKUPType(USART_TypeDef *USARTx, uint32_t Type) -{ - MODIFY_REG(USARTx->CR3, USART_CR3_WUS, Type); -} - -/** - * @brief Return event type for Wake UP Interrupt Flag (WUS[1:0] bits) - * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not - * Wake-up from Stop mode feature is supported by the USARTx instance. - * @rmtoll CR3 WUS LL_USART_GetWKUPType - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_WAKEUP_ON_ADDRESS - * @arg @ref LL_USART_WAKEUP_ON_STARTBIT - * @arg @ref LL_USART_WAKEUP_ON_RXNE - */ -__STATIC_INLINE uint32_t LL_USART_GetWKUPType(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_WUS)); -} - -/** - * @brief Configure USART BRR register for achieving expected Baud Rate value. - * @note Compute and set USARTDIV value in BRR Register (full BRR content) - * according to used Peripheral Clock, Oversampling mode, and expected Baud Rate values - * @note Peripheral clock and Baud rate values provided as function parameters should be valid - * (Baud rate value != 0) - * @note In case of oversampling by 16 and 8, BRR content must be greater than or equal to 16d. - * @rmtoll BRR BRR LL_USART_SetBaudRate - * @param USARTx USART Instance - * @param PeriphClk Peripheral Clock - @if USART_PRESC_PRESCALER - * @param PrescalerValue This parameter can be one of the following values: - * @arg @ref LL_USART_PRESCALER_DIV1 - * @arg @ref LL_USART_PRESCALER_DIV2 - * @arg @ref LL_USART_PRESCALER_DIV4 - * @arg @ref LL_USART_PRESCALER_DIV6 - * @arg @ref LL_USART_PRESCALER_DIV8 - * @arg @ref LL_USART_PRESCALER_DIV10 - * @arg @ref LL_USART_PRESCALER_DIV12 - * @arg @ref LL_USART_PRESCALER_DIV16 - * @arg @ref LL_USART_PRESCALER_DIV32 - * @arg @ref LL_USART_PRESCALER_DIV64 - * @arg @ref LL_USART_PRESCALER_DIV128 - * @arg @ref LL_USART_PRESCALER_DIV256 - @endif - * @param OverSampling This parameter can be one of the following values: - * @arg @ref LL_USART_OVERSAMPLING_16 - * @arg @ref LL_USART_OVERSAMPLING_8 - * @param BaudRate Baud Rate - * @retval None - */ -#if defined(USART_PRESC_PRESCALER) -__STATIC_INLINE void LL_USART_SetBaudRate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t PrescalerValue, - uint32_t OverSampling, - uint32_t BaudRate) -#else -__STATIC_INLINE void LL_USART_SetBaudRate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t OverSampling, - uint32_t BaudRate) -#endif /* USART_PRESC_PRESCALER */ -{ - uint32_t usartdiv; - uint32_t brrtemp; - -#if defined(USART_PRESC_PRESCALER) - if (PrescalerValue > LL_USART_PRESCALER_DIV256) - { - /* Do not overstep the size of USART_PRESCALER_TAB */ - } - else if (BaudRate == 0U) - { - /* Can Not divide per 0 */ - } - else if (OverSampling == LL_USART_OVERSAMPLING_8) -#else - if (OverSampling == LL_USART_OVERSAMPLING_8) -#endif /* USART_PRESC_PRESCALER */ - { -#if defined(USART_PRESC_PRESCALER) - usartdiv = (uint16_t)(__LL_USART_DIV_SAMPLING8(PeriphClk, (uint8_t)PrescalerValue, BaudRate)); -#else - usartdiv = (uint16_t)(__LL_USART_DIV_SAMPLING8(PeriphClk, BaudRate)); -#endif /* USART_PRESC_PRESCALER */ - brrtemp = usartdiv & 0xFFF0U; - brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); - USARTx->BRR = brrtemp; - } - else - { -#if defined(USART_PRESC_PRESCALER) - USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING16(PeriphClk, (uint8_t)PrescalerValue, BaudRate)); -#else - USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING16(PeriphClk, BaudRate)); -#endif /* USART_PRESC_PRESCALER */ - } -} - -/** - * @brief Return current Baud Rate value, according to USARTDIV present in BRR register - * (full BRR content), and to used Peripheral Clock and Oversampling mode values - * @note In case of non-initialized or invalid value stored in BRR register, value 0 will be returned. - * @note In case of oversampling by 16 and 8, BRR content must be greater than or equal to 16d. - * @rmtoll BRR BRR LL_USART_GetBaudRate - * @param USARTx USART Instance - * @param PeriphClk Peripheral Clock - @if USART_PRESC_PRESCALER - * @param PrescalerValue This parameter can be one of the following values: - * @arg @ref LL_USART_PRESCALER_DIV1 - * @arg @ref LL_USART_PRESCALER_DIV2 - * @arg @ref LL_USART_PRESCALER_DIV4 - * @arg @ref LL_USART_PRESCALER_DIV6 - * @arg @ref LL_USART_PRESCALER_DIV8 - * @arg @ref LL_USART_PRESCALER_DIV10 - * @arg @ref LL_USART_PRESCALER_DIV12 - * @arg @ref LL_USART_PRESCALER_DIV16 - * @arg @ref LL_USART_PRESCALER_DIV32 - * @arg @ref LL_USART_PRESCALER_DIV64 - * @arg @ref LL_USART_PRESCALER_DIV128 - * @arg @ref LL_USART_PRESCALER_DIV256 - @endif - * @param OverSampling This parameter can be one of the following values: - * @arg @ref LL_USART_OVERSAMPLING_16 - * @arg @ref LL_USART_OVERSAMPLING_8 - * @retval Baud Rate - */ -#if defined(USART_PRESC_PRESCALER) -__STATIC_INLINE uint32_t LL_USART_GetBaudRate(const USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t PrescalerValue, - uint32_t OverSampling) -#else -__STATIC_INLINE uint32_t LL_USART_GetBaudRate(const USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t OverSampling) -#endif /* USART_PRESC_PRESCALER */ -{ - uint32_t usartdiv; - uint32_t brrresult = 0x0U; -#if defined(USART_PRESC_PRESCALER) - uint32_t periphclkpresc = (uint32_t)(PeriphClk / (USART_PRESCALER_TAB[(uint8_t)PrescalerValue])); -#endif /* USART_PRESC_PRESCALER */ - - usartdiv = USARTx->BRR; - - if (usartdiv == 0U) - { - /* Do not perform a division by 0 */ - } - else if (OverSampling == LL_USART_OVERSAMPLING_8) - { - usartdiv = (uint16_t)((usartdiv & 0xFFF0U) | ((usartdiv & 0x0007U) << 1U)) ; - if (usartdiv != 0U) - { -#if defined(USART_PRESC_PRESCALER) - brrresult = (periphclkpresc * 2U) / usartdiv; -#else - brrresult = (PeriphClk * 2U) / usartdiv; -#endif /* USART_PRESC_PRESCALER */ - } - } - else - { - if ((usartdiv & 0xFFFFU) != 0U) - { -#if defined(USART_PRESC_PRESCALER) - brrresult = periphclkpresc / usartdiv; -#else - brrresult = PeriphClk / usartdiv; -#endif /* USART_PRESC_PRESCALER */ - } - } - return (brrresult); -} - -/** - * @brief Set Receiver Time Out Value (expressed in nb of bits duration) - * @rmtoll RTOR RTO LL_USART_SetRxTimeout - * @param USARTx USART Instance - * @param Timeout Value between Min_Data=0x00 and Max_Data=0x00FFFFFF - * @retval None - */ -__STATIC_INLINE void LL_USART_SetRxTimeout(USART_TypeDef *USARTx, uint32_t Timeout) -{ - MODIFY_REG(USARTx->RTOR, USART_RTOR_RTO, Timeout); -} - -/** - * @brief Get Receiver Time Out Value (expressed in nb of bits duration) - * @rmtoll RTOR RTO LL_USART_GetRxTimeout - * @param USARTx USART Instance - * @retval Value between Min_Data=0x00 and Max_Data=0x00FFFFFF - */ -__STATIC_INLINE uint32_t LL_USART_GetRxTimeout(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->RTOR, USART_RTOR_RTO)); -} - -/** - * @brief Set Block Length value in reception - * @rmtoll RTOR BLEN LL_USART_SetBlockLength - * @param USARTx USART Instance - * @param BlockLength Value between Min_Data=0x00 and Max_Data=0xFF - * @retval None - */ -__STATIC_INLINE void LL_USART_SetBlockLength(USART_TypeDef *USARTx, uint32_t BlockLength) -{ - MODIFY_REG(USARTx->RTOR, USART_RTOR_BLEN, BlockLength << USART_RTOR_BLEN_Pos); -} - -/** - * @brief Get Block Length value in reception - * @rmtoll RTOR BLEN LL_USART_GetBlockLength - * @param USARTx USART Instance - * @retval Value between Min_Data=0x00 and Max_Data=0xFF - */ -__STATIC_INLINE uint32_t LL_USART_GetBlockLength(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->RTOR, USART_RTOR_BLEN) >> USART_RTOR_BLEN_Pos); -} - -/** - * @} - */ - -/** @defgroup USART_LL_EF_Configuration_IRDA Configuration functions related to Irda feature - * @{ - */ - -/** - * @brief Enable IrDA mode - * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not - * IrDA feature is supported by the USARTx instance. - * @rmtoll CR3 IREN LL_USART_EnableIrda - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIrda(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR3, USART_CR3_IREN); -} - -/** - * @brief Disable IrDA mode - * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not - * IrDA feature is supported by the USARTx instance. - * @rmtoll CR3 IREN LL_USART_DisableIrda - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIrda(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR3, USART_CR3_IREN); -} - -/** - * @brief Indicate if IrDA mode is enabled - * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not - * IrDA feature is supported by the USARTx instance. - * @rmtoll CR3 IREN LL_USART_IsEnabledIrda - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIrda(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_IREN) == (USART_CR3_IREN)) ? 1UL : 0UL); -} - -/** - * @brief Configure IrDA Power Mode (Normal or Low Power) - * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not - * IrDA feature is supported by the USARTx instance. - * @rmtoll CR3 IRLP LL_USART_SetIrdaPowerMode - * @param USARTx USART Instance - * @param PowerMode This parameter can be one of the following values: - * @arg @ref LL_USART_IRDA_POWER_NORMAL - * @arg @ref LL_USART_IRDA_POWER_LOW - * @retval None - */ -__STATIC_INLINE void LL_USART_SetIrdaPowerMode(USART_TypeDef *USARTx, uint32_t PowerMode) -{ - MODIFY_REG(USARTx->CR3, USART_CR3_IRLP, PowerMode); -} - -/** - * @brief Retrieve IrDA Power Mode configuration (Normal or Low Power) - * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not - * IrDA feature is supported by the USARTx instance. - * @rmtoll CR3 IRLP LL_USART_GetIrdaPowerMode - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_IRDA_POWER_NORMAL - * @arg @ref LL_USART_PHASE_2EDGE - */ -__STATIC_INLINE uint32_t LL_USART_GetIrdaPowerMode(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_IRLP)); -} - -/** - * @brief Set Irda prescaler value, used for dividing the USART clock source - * to achieve the Irda Low Power frequency (8 bits value) - * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not - * IrDA feature is supported by the USARTx instance. - * @rmtoll GTPR PSC LL_USART_SetIrdaPrescaler - * @param USARTx USART Instance - * @param PrescalerValue Value between Min_Data=0x00 and Max_Data=0xFF - * @retval None - */ -__STATIC_INLINE void LL_USART_SetIrdaPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue) -{ - MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, (uint16_t)PrescalerValue); -} - -/** - * @brief Return Irda prescaler value, used for dividing the USART clock source - * to achieve the Irda Low Power frequency (8 bits value) - * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not - * IrDA feature is supported by the USARTx instance. - * @rmtoll GTPR PSC LL_USART_GetIrdaPrescaler - * @param USARTx USART Instance - * @retval Irda prescaler value (Value between Min_Data=0x00 and Max_Data=0xFF) - */ -__STATIC_INLINE uint32_t LL_USART_GetIrdaPrescaler(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC)); -} - -/** - * @} - */ - -/** @defgroup USART_LL_EF_Configuration_Smartcard Configuration functions related to Smartcard feature - * @{ - */ - -/** - * @brief Enable Smartcard NACK transmission - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR3 NACK LL_USART_EnableSmartcardNACK - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableSmartcardNACK(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR3, USART_CR3_NACK); -} - -/** - * @brief Disable Smartcard NACK transmission - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR3 NACK LL_USART_DisableSmartcardNACK - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableSmartcardNACK(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR3, USART_CR3_NACK); -} - -/** - * @brief Indicate if Smartcard NACK transmission is enabled - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR3 NACK LL_USART_IsEnabledSmartcardNACK - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcardNACK(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_NACK) == (USART_CR3_NACK)) ? 1UL : 0UL); -} - -/** - * @brief Enable Smartcard mode - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR3 SCEN LL_USART_EnableSmartcard - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableSmartcard(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR3, USART_CR3_SCEN); -} - -/** - * @brief Disable Smartcard mode - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR3 SCEN LL_USART_DisableSmartcard - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableSmartcard(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR3, USART_CR3_SCEN); -} - -/** - * @brief Indicate if Smartcard mode is enabled - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR3 SCEN LL_USART_IsEnabledSmartcard - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcard(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_SCEN) == (USART_CR3_SCEN)) ? 1UL : 0UL); -} - -/** - * @brief Set Smartcard Auto-Retry Count value (SCARCNT[2:0] bits) - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @note This bit-field specifies the number of retries in transmit and receive, in Smartcard mode. - * In transmission mode, it specifies the number of automatic retransmission retries, before - * generating a transmission error (FE bit set). - * In reception mode, it specifies the number or erroneous reception trials, before generating a - * reception error (RXNE and PE bits set) - * @rmtoll CR3 SCARCNT LL_USART_SetSmartcardAutoRetryCount - * @param USARTx USART Instance - * @param AutoRetryCount Value between Min_Data=0 and Max_Data=7 - * @retval None - */ -__STATIC_INLINE void LL_USART_SetSmartcardAutoRetryCount(USART_TypeDef *USARTx, uint32_t AutoRetryCount) -{ - MODIFY_REG(USARTx->CR3, USART_CR3_SCARCNT, AutoRetryCount << USART_CR3_SCARCNT_Pos); -} - -/** - * @brief Return Smartcard Auto-Retry Count value (SCARCNT[2:0] bits) - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR3 SCARCNT LL_USART_GetSmartcardAutoRetryCount - * @param USARTx USART Instance - * @retval Smartcard Auto-Retry Count value (Value between Min_Data=0 and Max_Data=7) - */ -__STATIC_INLINE uint32_t LL_USART_GetSmartcardAutoRetryCount(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_SCARCNT) >> USART_CR3_SCARCNT_Pos); -} - -/** - * @brief Set Smartcard prescaler value, used for dividing the USART clock - * source to provide the SMARTCARD Clock (5 bits value) - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll GTPR PSC LL_USART_SetSmartcardPrescaler - * @param USARTx USART Instance - * @param PrescalerValue Value between Min_Data=0 and Max_Data=31 - * @retval None - */ -__STATIC_INLINE void LL_USART_SetSmartcardPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue) -{ - MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, (uint16_t)PrescalerValue); -} - -/** - * @brief Return Smartcard prescaler value, used for dividing the USART clock - * source to provide the SMARTCARD Clock (5 bits value) - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll GTPR PSC LL_USART_GetSmartcardPrescaler - * @param USARTx USART Instance - * @retval Smartcard prescaler value (Value between Min_Data=0 and Max_Data=31) - */ -__STATIC_INLINE uint32_t LL_USART_GetSmartcardPrescaler(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC)); -} - -/** - * @brief Set Smartcard Guard time value, expressed in nb of baud clocks periods - * (GT[7:0] bits : Guard time value) - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll GTPR GT LL_USART_SetSmartcardGuardTime - * @param USARTx USART Instance - * @param GuardTime Value between Min_Data=0x00 and Max_Data=0xFF - * @retval None - */ -__STATIC_INLINE void LL_USART_SetSmartcardGuardTime(USART_TypeDef *USARTx, uint32_t GuardTime) -{ - MODIFY_REG(USARTx->GTPR, USART_GTPR_GT, (uint16_t)(GuardTime << USART_GTPR_GT_Pos)); -} - -/** - * @brief Return Smartcard Guard time value, expressed in nb of baud clocks periods - * (GT[7:0] bits : Guard time value) - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll GTPR GT LL_USART_GetSmartcardGuardTime - * @param USARTx USART Instance - * @retval Smartcard Guard time value (Value between Min_Data=0x00 and Max_Data=0xFF) - */ -__STATIC_INLINE uint32_t LL_USART_GetSmartcardGuardTime(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_GT) >> USART_GTPR_GT_Pos); -} - -/** - * @} - */ - -/** @defgroup USART_LL_EF_Configuration_HalfDuplex Configuration functions related to Half Duplex feature - * @{ - */ - -/** - * @brief Enable Single Wire Half-Duplex mode - * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not - * Half-Duplex mode is supported by the USARTx instance. - * @rmtoll CR3 HDSEL LL_USART_EnableHalfDuplex - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableHalfDuplex(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR3, USART_CR3_HDSEL); -} - -/** - * @brief Disable Single Wire Half-Duplex mode - * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not - * Half-Duplex mode is supported by the USARTx instance. - * @rmtoll CR3 HDSEL LL_USART_DisableHalfDuplex - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableHalfDuplex(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR3, USART_CR3_HDSEL); -} - -/** - * @brief Indicate if Single Wire Half-Duplex mode is enabled - * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not - * Half-Duplex mode is supported by the USARTx instance. - * @rmtoll CR3 HDSEL LL_USART_IsEnabledHalfDuplex - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledHalfDuplex(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_HDSEL) == (USART_CR3_HDSEL)) ? 1UL : 0UL); -} - -/** - * @} - */ - -#if defined(USART_CR2_SLVEN) -/** @defgroup USART_LL_EF_Configuration_SPI_SLAVE Configuration functions related to SPI Slave feature - * @{ - */ -/** - * @brief Enable SPI Synchronous Slave mode - * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not - * SPI Slave mode feature is supported by the USARTx instance. - * @rmtoll CR2 SLVEN LL_USART_EnableSPISlave - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableSPISlave(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR2, USART_CR2_SLVEN); -} - -/** - * @brief Disable SPI Synchronous Slave mode - * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not - * SPI Slave mode feature is supported by the USARTx instance. - * @rmtoll CR2 SLVEN LL_USART_DisableSPISlave - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableSPISlave(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR2, USART_CR2_SLVEN); -} - -/** - * @brief Indicate if SPI Synchronous Slave mode is enabled - * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not - * SPI Slave mode feature is supported by the USARTx instance. - * @rmtoll CR2 SLVEN LL_USART_IsEnabledSPISlave - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledSPISlave(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR2, USART_CR2_SLVEN) == (USART_CR2_SLVEN)) ? 1UL : 0UL); -} - -/** - * @brief Enable SPI Slave Selection using NSS input pin - * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not - * SPI Slave mode feature is supported by the USARTx instance. - * @note SPI Slave Selection depends on NSS input pin - * (The slave is selected when NSS is low and deselected when NSS is high). - * @rmtoll CR2 DIS_NSS LL_USART_EnableSPISlaveSelect - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableSPISlaveSelect(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR2, USART_CR2_DIS_NSS); -} - -/** - * @brief Disable SPI Slave Selection using NSS input pin - * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not - * SPI Slave mode feature is supported by the USARTx instance. - * @note SPI Slave will be always selected and NSS input pin will be ignored. - * @rmtoll CR2 DIS_NSS LL_USART_DisableSPISlaveSelect - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableSPISlaveSelect(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR2, USART_CR2_DIS_NSS); -} - -/** - * @brief Indicate if SPI Slave Selection depends on NSS input pin - * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not - * SPI Slave mode feature is supported by the USARTx instance. - * @rmtoll CR2 DIS_NSS LL_USART_IsEnabledSPISlaveSelect - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledSPISlaveSelect(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR2, USART_CR2_DIS_NSS) != (USART_CR2_DIS_NSS)) ? 1UL : 0UL); -} - -/** - * @} - */ - -#endif /* USART_CR2_SLVEN */ -/** @defgroup USART_LL_EF_Configuration_LIN Configuration functions related to LIN feature - * @{ - */ - -/** - * @brief Set LIN Break Detection Length - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @rmtoll CR2 LBDL LL_USART_SetLINBrkDetectionLen - * @param USARTx USART Instance - * @param LINBDLength This parameter can be one of the following values: - * @arg @ref LL_USART_LINBREAK_DETECT_10B - * @arg @ref LL_USART_LINBREAK_DETECT_11B - * @retval None - */ -__STATIC_INLINE void LL_USART_SetLINBrkDetectionLen(USART_TypeDef *USARTx, uint32_t LINBDLength) -{ - MODIFY_REG(USARTx->CR2, USART_CR2_LBDL, LINBDLength); -} - -/** - * @brief Return LIN Break Detection Length - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @rmtoll CR2 LBDL LL_USART_GetLINBrkDetectionLen - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_LINBREAK_DETECT_10B - * @arg @ref LL_USART_LINBREAK_DETECT_11B - */ -__STATIC_INLINE uint32_t LL_USART_GetLINBrkDetectionLen(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBDL)); -} - -/** - * @brief Enable LIN mode - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @rmtoll CR2 LINEN LL_USART_EnableLIN - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableLIN(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR2, USART_CR2_LINEN); -} - -/** - * @brief Disable LIN mode - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @rmtoll CR2 LINEN LL_USART_DisableLIN - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableLIN(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR2, USART_CR2_LINEN); -} - -/** - * @brief Indicate if LIN mode is enabled - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @rmtoll CR2 LINEN LL_USART_IsEnabledLIN - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledLIN(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR2, USART_CR2_LINEN) == (USART_CR2_LINEN)) ? 1UL : 0UL); -} - -/** - * @} - */ - -/** @defgroup USART_LL_EF_Configuration_DE Configuration functions related to Driver Enable feature - * @{ - */ - -/** - * @brief Set DEDT (Driver Enable De-Assertion Time), Time value expressed on 5 bits ([4:0] bits). - * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not - * Driver Enable feature is supported by the USARTx instance. - * @rmtoll CR1 DEDT LL_USART_SetDEDeassertionTime - * @param USARTx USART Instance - * @param Time Value between Min_Data=0 and Max_Data=31 - * @retval None - */ -__STATIC_INLINE void LL_USART_SetDEDeassertionTime(USART_TypeDef *USARTx, uint32_t Time) -{ - MODIFY_REG(USARTx->CR1, USART_CR1_DEDT, Time << USART_CR1_DEDT_Pos); -} - -/** - * @brief Return DEDT (Driver Enable De-Assertion Time) - * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not - * Driver Enable feature is supported by the USARTx instance. - * @rmtoll CR1 DEDT LL_USART_GetDEDeassertionTime - * @param USARTx USART Instance - * @retval Time value expressed on 5 bits ([4:0] bits) : Value between Min_Data=0 and Max_Data=31 - */ -__STATIC_INLINE uint32_t LL_USART_GetDEDeassertionTime(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_DEDT) >> USART_CR1_DEDT_Pos); -} - -/** - * @brief Set DEAT (Driver Enable Assertion Time), Time value expressed on 5 bits ([4:0] bits). - * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not - * Driver Enable feature is supported by the USARTx instance. - * @rmtoll CR1 DEAT LL_USART_SetDEAssertionTime - * @param USARTx USART Instance - * @param Time Value between Min_Data=0 and Max_Data=31 - * @retval None - */ -__STATIC_INLINE void LL_USART_SetDEAssertionTime(USART_TypeDef *USARTx, uint32_t Time) -{ - MODIFY_REG(USARTx->CR1, USART_CR1_DEAT, Time << USART_CR1_DEAT_Pos); -} - -/** - * @brief Return DEAT (Driver Enable Assertion Time) - * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not - * Driver Enable feature is supported by the USARTx instance. - * @rmtoll CR1 DEAT LL_USART_GetDEAssertionTime - * @param USARTx USART Instance - * @retval Time value expressed on 5 bits ([4:0] bits) : Value between Min_Data=0 and Max_Data=31 - */ -__STATIC_INLINE uint32_t LL_USART_GetDEAssertionTime(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_DEAT) >> USART_CR1_DEAT_Pos); -} - -/** - * @brief Enable Driver Enable (DE) Mode - * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not - * Driver Enable feature is supported by the USARTx instance. - * @rmtoll CR3 DEM LL_USART_EnableDEMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableDEMode(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR3, USART_CR3_DEM); -} - -/** - * @brief Disable Driver Enable (DE) Mode - * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not - * Driver Enable feature is supported by the USARTx instance. - * @rmtoll CR3 DEM LL_USART_DisableDEMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableDEMode(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR3, USART_CR3_DEM); -} - -/** - * @brief Indicate if Driver Enable (DE) Mode is enabled - * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not - * Driver Enable feature is supported by the USARTx instance. - * @rmtoll CR3 DEM LL_USART_IsEnabledDEMode - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledDEMode(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_DEM) == (USART_CR3_DEM)) ? 1UL : 0UL); -} - -/** - * @brief Select Driver Enable Polarity - * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not - * Driver Enable feature is supported by the USARTx instance. - * @rmtoll CR3 DEP LL_USART_SetDESignalPolarity - * @param USARTx USART Instance - * @param Polarity This parameter can be one of the following values: - * @arg @ref LL_USART_DE_POLARITY_HIGH - * @arg @ref LL_USART_DE_POLARITY_LOW - * @retval None - */ -__STATIC_INLINE void LL_USART_SetDESignalPolarity(USART_TypeDef *USARTx, uint32_t Polarity) -{ - MODIFY_REG(USARTx->CR3, USART_CR3_DEP, Polarity); -} - -/** - * @brief Return Driver Enable Polarity - * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not - * Driver Enable feature is supported by the USARTx instance. - * @rmtoll CR3 DEP LL_USART_GetDESignalPolarity - * @param USARTx USART Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_USART_DE_POLARITY_HIGH - * @arg @ref LL_USART_DE_POLARITY_LOW - */ -__STATIC_INLINE uint32_t LL_USART_GetDESignalPolarity(const USART_TypeDef *USARTx) -{ - return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_DEP)); -} - -/** - * @} - */ - -/** @defgroup USART_LL_EF_AdvancedConfiguration Advanced Configurations services - * @{ - */ - -/** - * @brief Perform basic configuration of USART for enabling use in Asynchronous Mode (UART) - * @note In UART mode, the following bits must be kept cleared: - * - LINEN bit in the USART_CR2 register, - * - CLKEN bit in the USART_CR2 register, - * - SCEN bit in the USART_CR3 register, - * - IREN bit in the USART_CR3 register, - * - HDSEL bit in the USART_CR3 register. - * @note Call of this function is equivalent to following function call sequence : - * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function - * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function - * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function - * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function - * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function - * @note Other remaining configurations items related to Asynchronous Mode - * (as Baud Rate, Word length, Parity, ...) should be set using - * dedicated functions - * @rmtoll CR2 LINEN LL_USART_ConfigAsyncMode\n - * CR2 CLKEN LL_USART_ConfigAsyncMode\n - * CR3 SCEN LL_USART_ConfigAsyncMode\n - * CR3 IREN LL_USART_ConfigAsyncMode\n - * CR3 HDSEL LL_USART_ConfigAsyncMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigAsyncMode(USART_TypeDef *USARTx) -{ - /* In Asynchronous mode, the following bits must be kept cleared: - - LINEN, CLKEN bits in the USART_CR2 register, - - SCEN, IREN and HDSEL bits in the USART_CR3 register. - */ - CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); - CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL)); -} - -/** - * @brief Perform basic configuration of USART for enabling use in Synchronous Mode - * @note In Synchronous mode, the following bits must be kept cleared: - * - LINEN bit in the USART_CR2 register, - * - SCEN bit in the USART_CR3 register, - * - IREN bit in the USART_CR3 register, - * - HDSEL bit in the USART_CR3 register. - * This function also sets the USART in Synchronous mode. - * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not - * Synchronous mode is supported by the USARTx instance. - * @note Call of this function is equivalent to following function call sequence : - * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function - * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function - * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function - * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function - * - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function - * @note Other remaining configurations items related to Synchronous Mode - * (as Baud Rate, Word length, Parity, Clock Polarity, ...) should be set using - * dedicated functions - * @rmtoll CR2 LINEN LL_USART_ConfigSyncMode\n - * CR2 CLKEN LL_USART_ConfigSyncMode\n - * CR3 SCEN LL_USART_ConfigSyncMode\n - * CR3 IREN LL_USART_ConfigSyncMode\n - * CR3 HDSEL LL_USART_ConfigSyncMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigSyncMode(USART_TypeDef *USARTx) -{ - /* In Synchronous mode, the following bits must be kept cleared: - - LINEN bit in the USART_CR2 register, - - SCEN, IREN and HDSEL bits in the USART_CR3 register. - */ - CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN)); - CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL)); - /* set the UART/USART in Synchronous mode */ - SET_BIT(USARTx->CR2, USART_CR2_CLKEN); -} - -/** - * @brief Perform basic configuration of USART for enabling use in LIN Mode - * @note In LIN mode, the following bits must be kept cleared: - * - STOP and CLKEN bits in the USART_CR2 register, - * - SCEN bit in the USART_CR3 register, - * - IREN bit in the USART_CR3 register, - * - HDSEL bit in the USART_CR3 register. - * This function also set the UART/USART in LIN mode. - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @note Call of this function is equivalent to following function call sequence : - * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function - * - Clear STOP in CR2 using @ref LL_USART_SetStopBitsLength() function - * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function - * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function - * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function - * - Set LINEN in CR2 using @ref LL_USART_EnableLIN() function - * @note Other remaining configurations items related to LIN Mode - * (as Baud Rate, Word length, LIN Break Detection Length, ...) should be set using - * dedicated functions - * @rmtoll CR2 CLKEN LL_USART_ConfigLINMode\n - * CR2 STOP LL_USART_ConfigLINMode\n - * CR2 LINEN LL_USART_ConfigLINMode\n - * CR3 IREN LL_USART_ConfigLINMode\n - * CR3 SCEN LL_USART_ConfigLINMode\n - * CR3 HDSEL LL_USART_ConfigLINMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigLINMode(USART_TypeDef *USARTx) -{ - /* In LIN mode, the following bits must be kept cleared: - - STOP and CLKEN bits in the USART_CR2 register, - - IREN, SCEN and HDSEL bits in the USART_CR3 register. - */ - CLEAR_BIT(USARTx->CR2, (USART_CR2_CLKEN | USART_CR2_STOP)); - CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_SCEN | USART_CR3_HDSEL)); - /* Set the UART/USART in LIN mode */ - SET_BIT(USARTx->CR2, USART_CR2_LINEN); -} - -/** - * @brief Perform basic configuration of USART for enabling use in Half Duplex Mode - * @note In Half Duplex mode, the following bits must be kept cleared: - * - LINEN bit in the USART_CR2 register, - * - CLKEN bit in the USART_CR2 register, - * - SCEN bit in the USART_CR3 register, - * - IREN bit in the USART_CR3 register, - * This function also sets the UART/USART in Half Duplex mode. - * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not - * Half-Duplex mode is supported by the USARTx instance. - * @note Call of this function is equivalent to following function call sequence : - * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function - * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function - * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function - * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function - * - Set HDSEL in CR3 using @ref LL_USART_EnableHalfDuplex() function - * @note Other remaining configurations items related to Half Duplex Mode - * (as Baud Rate, Word length, Parity, ...) should be set using - * dedicated functions - * @rmtoll CR2 LINEN LL_USART_ConfigHalfDuplexMode\n - * CR2 CLKEN LL_USART_ConfigHalfDuplexMode\n - * CR3 HDSEL LL_USART_ConfigHalfDuplexMode\n - * CR3 SCEN LL_USART_ConfigHalfDuplexMode\n - * CR3 IREN LL_USART_ConfigHalfDuplexMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigHalfDuplexMode(USART_TypeDef *USARTx) -{ - /* In Half Duplex mode, the following bits must be kept cleared: - - LINEN and CLKEN bits in the USART_CR2 register, - - SCEN and IREN bits in the USART_CR3 register. - */ - CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); - CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN)); - /* set the UART/USART in Half Duplex mode */ - SET_BIT(USARTx->CR3, USART_CR3_HDSEL); -} - -/** - * @brief Perform basic configuration of USART for enabling use in Smartcard Mode - * @note In Smartcard mode, the following bits must be kept cleared: - * - LINEN bit in the USART_CR2 register, - * - IREN bit in the USART_CR3 register, - * - HDSEL bit in the USART_CR3 register. - * This function also configures Stop bits to 1.5 bits and - * sets the USART in Smartcard mode (SCEN bit). - * Clock Output is also enabled (CLKEN). - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @note Call of this function is equivalent to following function call sequence : - * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function - * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function - * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function - * - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function - * - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function - * - Set SCEN in CR3 using @ref LL_USART_EnableSmartcard() function - * @note Other remaining configurations items related to Smartcard Mode - * (as Baud Rate, Word length, Parity, ...) should be set using - * dedicated functions - * @rmtoll CR2 LINEN LL_USART_ConfigSmartcardMode\n - * CR2 STOP LL_USART_ConfigSmartcardMode\n - * CR2 CLKEN LL_USART_ConfigSmartcardMode\n - * CR3 HDSEL LL_USART_ConfigSmartcardMode\n - * CR3 SCEN LL_USART_ConfigSmartcardMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigSmartcardMode(USART_TypeDef *USARTx) -{ - /* In Smartcard mode, the following bits must be kept cleared: - - LINEN bit in the USART_CR2 register, - - IREN and HDSEL bits in the USART_CR3 register. - */ - CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN)); - CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_HDSEL)); - /* Configure Stop bits to 1.5 bits */ - /* Synchronous mode is activated by default */ - SET_BIT(USARTx->CR2, (USART_CR2_STOP_0 | USART_CR2_STOP_1 | USART_CR2_CLKEN)); - /* set the UART/USART in Smartcard mode */ - SET_BIT(USARTx->CR3, USART_CR3_SCEN); -} - -/** - * @brief Perform basic configuration of USART for enabling use in Irda Mode - * @note In IRDA mode, the following bits must be kept cleared: - * - LINEN bit in the USART_CR2 register, - * - STOP and CLKEN bits in the USART_CR2 register, - * - SCEN bit in the USART_CR3 register, - * - HDSEL bit in the USART_CR3 register. - * This function also sets the UART/USART in IRDA mode (IREN bit). - * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not - * IrDA feature is supported by the USARTx instance. - * @note Call of this function is equivalent to following function call sequence : - * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function - * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function - * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function - * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function - * - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function - * - Set IREN in CR3 using @ref LL_USART_EnableIrda() function - * @note Other remaining configurations items related to Irda Mode - * (as Baud Rate, Word length, Power mode, ...) should be set using - * dedicated functions - * @rmtoll CR2 LINEN LL_USART_ConfigIrdaMode\n - * CR2 CLKEN LL_USART_ConfigIrdaMode\n - * CR2 STOP LL_USART_ConfigIrdaMode\n - * CR3 SCEN LL_USART_ConfigIrdaMode\n - * CR3 HDSEL LL_USART_ConfigIrdaMode\n - * CR3 IREN LL_USART_ConfigIrdaMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigIrdaMode(USART_TypeDef *USARTx) -{ - /* In IRDA mode, the following bits must be kept cleared: - - LINEN, STOP and CLKEN bits in the USART_CR2 register, - - SCEN and HDSEL bits in the USART_CR3 register. - */ - CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP)); - CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL)); - /* set the UART/USART in IRDA mode */ - SET_BIT(USARTx->CR3, USART_CR3_IREN); -} - -/** - * @brief Perform basic configuration of USART for enabling use in Multi processor Mode - * (several USARTs connected in a network, one of the USARTs can be the master, - * its TX output connected to the RX inputs of the other slaves USARTs). - * @note In MultiProcessor mode, the following bits must be kept cleared: - * - LINEN bit in the USART_CR2 register, - * - CLKEN bit in the USART_CR2 register, - * - SCEN bit in the USART_CR3 register, - * - IREN bit in the USART_CR3 register, - * - HDSEL bit in the USART_CR3 register. - * @note Call of this function is equivalent to following function call sequence : - * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function - * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function - * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function - * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function - * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function - * @note Other remaining configurations items related to Multi processor Mode - * (as Baud Rate, Wake Up Method, Node address, ...) should be set using - * dedicated functions - * @rmtoll CR2 LINEN LL_USART_ConfigMultiProcessMode\n - * CR2 CLKEN LL_USART_ConfigMultiProcessMode\n - * CR3 SCEN LL_USART_ConfigMultiProcessMode\n - * CR3 HDSEL LL_USART_ConfigMultiProcessMode\n - * CR3 IREN LL_USART_ConfigMultiProcessMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ConfigMultiProcessMode(USART_TypeDef *USARTx) -{ - /* In Multi Processor mode, the following bits must be kept cleared: - - LINEN and CLKEN bits in the USART_CR2 register, - - IREN, SCEN and HDSEL bits in the USART_CR3 register. - */ - CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); - CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); -} - -/** - * @} - */ - -/** @defgroup USART_LL_EF_FLAG_Management FLAG_Management - * @{ - */ - -/** - * @brief Check if the USART Parity Error Flag is set or not - * @rmtoll ISR PE LL_USART_IsActiveFlag_PE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_PE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_PE) == (USART_ISR_PE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Framing Error Flag is set or not - * @rmtoll ISR FE LL_USART_IsActiveFlag_FE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_FE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_FE) == (USART_ISR_FE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Noise error detected Flag is set or not - * @rmtoll ISR NE LL_USART_IsActiveFlag_NE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_NE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_NE) == (USART_ISR_NE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART OverRun Error Flag is set or not - * @rmtoll ISR ORE LL_USART_IsActiveFlag_ORE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ORE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_ORE) == (USART_ISR_ORE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART IDLE line detected Flag is set or not - * @rmtoll ISR IDLE LL_USART_IsActiveFlag_IDLE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_IDLE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_IDLE) == (USART_ISR_IDLE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_USART_IsActiveFlag_RXNE LL_USART_IsActiveFlag_RXNE_RXFNE - -/** - * @brief Check if the USART Read Data Register or USART RX FIFO Not Empty Flag is set or not - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll ISR RXNE_RXFNE LL_USART_IsActiveFlag_RXNE_RXFNE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXNE_RXFNE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_RXNE_RXFNE) == (USART_ISR_RXNE_RXFNE)) ? 1UL : 0UL); -} - -#else -/** - * @brief Check if the USART Read Data Register Not Empty Flag is set or not - * @rmtoll ISR RXNE LL_USART_IsActiveFlag_RXNE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXNE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_RXNE) == (USART_ISR_RXNE)) ? 1UL : 0UL); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Check if the USART Transmission Complete Flag is set or not - * @rmtoll ISR TC LL_USART_IsActiveFlag_TC - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TC(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_TC) == (USART_ISR_TC)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_USART_IsActiveFlag_TXE LL_USART_IsActiveFlag_TXE_TXFNF - -/** - * @brief Check if the USART Transmit Data Register Empty or USART TX FIFO Not Full Flag is set or not - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll ISR TXE_TXFNF LL_USART_IsActiveFlag_TXE_TXFNF - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXE_TXFNF(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_TXE_TXFNF) == (USART_ISR_TXE_TXFNF)) ? 1UL : 0UL); -} - -#else -/** - * @brief Check if the USART Transmit Data Register Empty Flag is set or not - * @rmtoll ISR TXE LL_USART_IsActiveFlag_TXE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_TXE) == (USART_ISR_TXE)) ? 1UL : 0UL); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Check if the USART LIN Break Detection Flag is set or not - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @rmtoll ISR LBDF LL_USART_IsActiveFlag_LBD - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_LBD(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_LBDF) == (USART_ISR_LBDF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART CTS interrupt Flag is set or not - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll ISR CTSIF LL_USART_IsActiveFlag_nCTS - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_nCTS(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_CTSIF) == (USART_ISR_CTSIF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART CTS Flag is set or not - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll ISR CTS LL_USART_IsActiveFlag_CTS - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_CTS(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_CTS) == (USART_ISR_CTS)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Receiver Time Out Flag is set or not - * @rmtoll ISR RTOF LL_USART_IsActiveFlag_RTO - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RTO(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_RTOF) == (USART_ISR_RTOF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART End Of Block Flag is set or not - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll ISR EOBF LL_USART_IsActiveFlag_EOB - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_EOB(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_EOBF) == (USART_ISR_EOBF)) ? 1UL : 0UL); -} - -#if defined(USART_CR2_SLVEN) -/** - * @brief Check if the SPI Slave Underrun error flag is set or not - * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not - * SPI Slave mode feature is supported by the USARTx instance. - * @rmtoll ISR UDR LL_USART_IsActiveFlag_UDR - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_UDR(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_UDR) == (USART_ISR_UDR)) ? 1UL : 0UL); -} - -#endif /* USART_CR2_SLVEN */ -/** - * @brief Check if the USART Auto-Baud Rate Error Flag is set or not - * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not - * Auto Baud Rate detection feature is supported by the USARTx instance. - * @rmtoll ISR ABRE LL_USART_IsActiveFlag_ABRE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ABRE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_ABRE) == (USART_ISR_ABRE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Auto-Baud Rate Flag is set or not - * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not - * Auto Baud Rate detection feature is supported by the USARTx instance. - * @rmtoll ISR ABRF LL_USART_IsActiveFlag_ABR - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ABR(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_ABRF) == (USART_ISR_ABRF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Busy Flag is set or not - * @rmtoll ISR BUSY LL_USART_IsActiveFlag_BUSY - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_BUSY(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_BUSY) == (USART_ISR_BUSY)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Character Match Flag is set or not - * @rmtoll ISR CMF LL_USART_IsActiveFlag_CM - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_CM(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_CMF) == (USART_ISR_CMF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Send Break Flag is set or not - * @rmtoll ISR SBKF LL_USART_IsActiveFlag_SBK - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_SBK(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_SBKF) == (USART_ISR_SBKF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Receive Wake Up from mute mode Flag is set or not - * @rmtoll ISR RWU LL_USART_IsActiveFlag_RWU - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RWU(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_RWU) == (USART_ISR_RWU)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Wake Up from stop mode Flag is set or not - * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not - * Wake-up from Stop mode feature is supported by the USARTx instance. - * @rmtoll ISR WUF LL_USART_IsActiveFlag_WKUP - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_WKUP(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_WUF) == (USART_ISR_WUF)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Transmit Enable Acknowledge Flag is set or not - * @rmtoll ISR TEACK LL_USART_IsActiveFlag_TEACK - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TEACK(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_TEACK) == (USART_ISR_TEACK)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Receive Enable Acknowledge Flag is set or not - * @rmtoll ISR REACK LL_USART_IsActiveFlag_REACK - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_REACK(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_REACK) == (USART_ISR_REACK)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Check if the USART TX FIFO Empty Flag is set or not - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll ISR TXFE LL_USART_IsActiveFlag_TXFE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXFE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_TXFE) == (USART_ISR_TXFE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART RX FIFO Full Flag is set or not - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll ISR RXFF LL_USART_IsActiveFlag_RXFF - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXFF(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_RXFF) == (USART_ISR_RXFF)) ? 1UL : 0UL); -} - -#endif /* USART_CR1_FIFOEN */ -#if defined(USART_TCBGT_SUPPORT) -/* Function available only on devices supporting Transmit Complete before Guard Time feature */ -/** - * @brief Check if the Smartcard Transmission Complete Before Guard Time Flag is set or not - * @rmtoll ISR TCBGT LL_USART_IsActiveFlag_TCBGT - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TCBGT(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_TCBGT) == (USART_ISR_TCBGT)) ? 1UL : 0UL); -} - -#endif /* USART_TCBGT_SUPPORT */ -#if defined(USART_CR1_FIFOEN) -/** - * @brief Check if the USART TX FIFO Threshold Flag is set or not - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll ISR TXFT LL_USART_IsActiveFlag_TXFT - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXFT(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_TXFT) == (USART_ISR_TXFT)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART RX FIFO Threshold Flag is set or not - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll ISR RXFT LL_USART_IsActiveFlag_RXFT - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXFT(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->ISR, USART_ISR_RXFT) == (USART_ISR_RXFT)) ? 1UL : 0UL); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Clear Parity Error Flag - * @rmtoll ICR PECF LL_USART_ClearFlag_PE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_PE(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_PECF); -} - -/** - * @brief Clear Framing Error Flag - * @rmtoll ICR FECF LL_USART_ClearFlag_FE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_FE(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_FECF); -} - -/** - * @brief Clear Noise Error detected Flag - * @rmtoll ICR NECF LL_USART_ClearFlag_NE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_NE(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_NECF); -} - -/** - * @brief Clear OverRun Error Flag - * @rmtoll ICR ORECF LL_USART_ClearFlag_ORE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_ORE(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_ORECF); -} - -/** - * @brief Clear IDLE line detected Flag - * @rmtoll ICR IDLECF LL_USART_ClearFlag_IDLE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_IDLECF); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Clear TX FIFO Empty Flag - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll ICR TXFECF LL_USART_ClearFlag_TXFE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_TXFE(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_TXFECF); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Clear Transmission Complete Flag - * @rmtoll ICR TCCF LL_USART_ClearFlag_TC - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_TC(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_TCCF); -} - -#if defined(USART_TCBGT_SUPPORT) -/* Function available only on devices supporting Transmit Complete before Guard Time feature */ -/** - * @brief Clear Smartcard Transmission Complete Before Guard Time Flag - * @rmtoll ICR TCBGTCF LL_USART_ClearFlag_TCBGT - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_TCBGT(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_TCBGTCF); -} -#endif /* USART_TCBGT_SUPPORT */ - -/** - * @brief Clear LIN Break Detection Flag - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @rmtoll ICR LBDCF LL_USART_ClearFlag_LBD - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_LBD(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_LBDCF); -} - -/** - * @brief Clear CTS Interrupt Flag - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll ICR CTSCF LL_USART_ClearFlag_nCTS - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_nCTS(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_CTSCF); -} - -/** - * @brief Clear Receiver Time Out Flag - * @rmtoll ICR RTOCF LL_USART_ClearFlag_RTO - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_RTO(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_RTOCF); -} - -/** - * @brief Clear End Of Block Flag - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll ICR EOBCF LL_USART_ClearFlag_EOB - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_EOB(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_EOBCF); -} - -#if defined(USART_CR2_SLVEN) -/** - * @brief Clear SPI Slave Underrun Flag - * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not - * SPI Slave mode feature is supported by the USARTx instance. - * @rmtoll ICR UDRCF LL_USART_ClearFlag_UDR - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_UDR(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_UDRCF); -} - -#endif /* USART_CR2_SLVEN */ -/** - * @brief Clear Character Match Flag - * @rmtoll ICR CMCF LL_USART_ClearFlag_CM - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_CM(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_CMCF); -} - -/** - * @brief Clear Wake Up from stop mode Flag - * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not - * Wake-up from Stop mode feature is supported by the USARTx instance. - * @rmtoll ICR WUCF LL_USART_ClearFlag_WKUP - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_ClearFlag_WKUP(USART_TypeDef *USARTx) -{ - WRITE_REG(USARTx->ICR, USART_ICR_WUCF); -} - -/** - * @} - */ - -/** @defgroup USART_LL_EF_IT_Management IT_Management - * @{ - */ - -/** - * @brief Enable IDLE Interrupt - * @rmtoll CR1 IDLEIE LL_USART_EnableIT_IDLE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_IDLEIE); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_USART_EnableIT_RXNE LL_USART_EnableIT_RXNE_RXFNE - -/** - * @brief Enable RX Not Empty and RX FIFO Not Empty Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 RXNEIE_RXFNEIE LL_USART_EnableIT_RXNE_RXFNE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_RXNE_RXFNE(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RXNEIE_RXFNEIE); -} - -#else -/** - * @brief Enable RX Not Empty Interrupt - * @rmtoll CR1 RXNEIE LL_USART_EnableIT_RXNE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_RXNE(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RXNEIE); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Enable Transmission Complete Interrupt - * @rmtoll CR1 TCIE LL_USART_EnableIT_TC - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_TC(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TCIE); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_USART_EnableIT_TXE LL_USART_EnableIT_TXE_TXFNF - -/** - * @brief Enable TX Empty and TX FIFO Not Full Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 TXEIE_TXFNFIE LL_USART_EnableIT_TXE_TXFNF - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_TXE_TXFNF(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TXEIE_TXFNFIE); -} - -#else -/** - * @brief Enable TX Empty Interrupt - * @rmtoll CR1 TXEIE LL_USART_EnableIT_TXE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_TXE(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TXEIE); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Enable Parity Error Interrupt - * @rmtoll CR1 PEIE LL_USART_EnableIT_PE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_PE(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_PEIE); -} - -/** - * @brief Enable Character Match Interrupt - * @rmtoll CR1 CMIE LL_USART_EnableIT_CM - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_CM(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_CMIE); -} - -/** - * @brief Enable Receiver Timeout Interrupt - * @rmtoll CR1 RTOIE LL_USART_EnableIT_RTO - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_RTO(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RTOIE); -} - -/** - * @brief Enable End Of Block Interrupt - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR1 EOBIE LL_USART_EnableIT_EOB - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_EOB(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_EOBIE); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Enable TX FIFO Empty Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 TXFEIE LL_USART_EnableIT_TXFE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_TXFE(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TXFEIE); -} - -/** - * @brief Enable RX FIFO Full Interrupt - * @rmtoll CR1 RXFFIE LL_USART_EnableIT_RXFF - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_RXFF(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RXFFIE); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Enable LIN Break Detection Interrupt - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @rmtoll CR2 LBDIE LL_USART_EnableIT_LBD - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_LBD(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR2, USART_CR2_LBDIE); -} - -/** - * @brief Enable Error Interrupt - * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing - * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the USARTx_ISR register). - * 0: Interrupt is inhibited - * 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the USARTx_ISR register. - * @rmtoll CR3 EIE LL_USART_EnableIT_ERROR - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_ERROR(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_EIE); -} - -/** - * @brief Enable CTS Interrupt - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll CR3 CTSIE LL_USART_EnableIT_CTS - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_CTS(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_CTSIE); -} - -/** - * @brief Enable Wake Up from Stop Mode Interrupt - * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not - * Wake-up from Stop mode feature is supported by the USARTx instance. - * @rmtoll CR3 WUFIE LL_USART_EnableIT_WKUP - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_WKUP(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_WUFIE); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Enable TX FIFO Threshold Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 TXFTIE LL_USART_EnableIT_TXFT - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_TXFT(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_TXFTIE); -} - -#endif /* USART_CR1_FIFOEN */ -#if defined(USART_TCBGT_SUPPORT) -/* Function available only on devices supporting Transmit Complete before Guard Time feature */ -/** - * @brief Enable Smartcard Transmission Complete Before Guard Time Interrupt - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR3 TCBGTIE LL_USART_EnableIT_TCBGT - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_TCBGT(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_TCBGTIE); -} -#endif /* USART_TCBGT_SUPPORT */ - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Enable RX FIFO Threshold Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 RXFTIE LL_USART_EnableIT_RXFT - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableIT_RXFT(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_RXFTIE); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Disable IDLE Interrupt - * @rmtoll CR1 IDLEIE LL_USART_DisableIT_IDLE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_IDLE(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_IDLEIE); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_USART_DisableIT_RXNE LL_USART_DisableIT_RXNE_RXFNE - -/** - * @brief Disable RX Not Empty and RX FIFO Not Empty Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 RXNEIE_RXFNEIE LL_USART_DisableIT_RXNE_RXFNE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_RXNE_RXFNE(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RXNEIE_RXFNEIE); -} - -#else -/** - * @brief Disable RX Not Empty Interrupt - * @rmtoll CR1 RXNEIE LL_USART_DisableIT_RXNE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_RXNE(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RXNEIE); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Disable Transmission Complete Interrupt - * @rmtoll CR1 TCIE LL_USART_DisableIT_TC - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_TC(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TCIE); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_USART_DisableIT_TXE LL_USART_DisableIT_TXE_TXFNF - -/** - * @brief Disable TX Empty and TX FIFO Not Full Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 TXEIE_TXFNFIE LL_USART_DisableIT_TXE_TXFNF - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_TXE_TXFNF(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TXEIE_TXFNFIE); -} - -#else -/** - * @brief Disable TX Empty Interrupt - * @rmtoll CR1 TXEIE LL_USART_DisableIT_TXE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_TXE(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TXEIE); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Disable Parity Error Interrupt - * @rmtoll CR1 PEIE LL_USART_DisableIT_PE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_PE(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_PEIE); -} - -/** - * @brief Disable Character Match Interrupt - * @rmtoll CR1 CMIE LL_USART_DisableIT_CM - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_CM(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_CMIE); -} - -/** - * @brief Disable Receiver Timeout Interrupt - * @rmtoll CR1 RTOIE LL_USART_DisableIT_RTO - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_RTO(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RTOIE); -} - -/** - * @brief Disable End Of Block Interrupt - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR1 EOBIE LL_USART_DisableIT_EOB - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_EOB(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_EOBIE); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Disable TX FIFO Empty Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 TXFEIE LL_USART_DisableIT_TXFE - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_TXFE(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TXFEIE); -} - -/** - * @brief Disable RX FIFO Full Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 RXFFIE LL_USART_DisableIT_RXFF - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_RXFF(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RXFFIE); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Disable LIN Break Detection Interrupt - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @rmtoll CR2 LBDIE LL_USART_DisableIT_LBD - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_LBD(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR2, USART_CR2_LBDIE); -} - -/** - * @brief Disable Error Interrupt - * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing - * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the USARTx_ISR register). - * 0: Interrupt is inhibited - * 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the USARTx_ISR register. - * @rmtoll CR3 EIE LL_USART_DisableIT_ERROR - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_ERROR(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_EIE); -} - -/** - * @brief Disable CTS Interrupt - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll CR3 CTSIE LL_USART_DisableIT_CTS - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_CTS(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_CTSIE); -} - -/** - * @brief Disable Wake Up from Stop Mode Interrupt - * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not - * Wake-up from Stop mode feature is supported by the USARTx instance. - * @rmtoll CR3 WUFIE LL_USART_DisableIT_WKUP - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_WKUP(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_WUFIE); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Disable TX FIFO Threshold Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 TXFTIE LL_USART_DisableIT_TXFT - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_TXFT(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_TXFTIE); -} - -#endif /* USART_CR1_FIFOEN */ -#if defined(USART_TCBGT_SUPPORT) -/* Function available only on devices supporting Transmit Complete before Guard Time feature */ -/** - * @brief Disable Smartcard Transmission Complete Before Guard Time Interrupt - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR3 TCBGTIE LL_USART_DisableIT_TCBGT - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_TCBGT(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_TCBGTIE); -} -#endif /* USART_TCBGT_SUPPORT */ - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Disable RX FIFO Threshold Interrupt - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 RXFTIE LL_USART_DisableIT_RXFT - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableIT_RXFT(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_RXFTIE); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Check if the USART IDLE Interrupt source is enabled or disabled. - * @rmtoll CR1 IDLEIE LL_USART_IsEnabledIT_IDLE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_IDLE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_IDLEIE) == (USART_CR1_IDLEIE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_USART_IsEnabledIT_RXNE LL_USART_IsEnabledIT_RXNE_RXFNE - -/** - * @brief Check if the USART RX Not Empty and USART RX FIFO Not Empty Interrupt is enabled or disabled. - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 RXNEIE_RXFNEIE LL_USART_IsEnabledIT_RXNE_RXFNE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXNE_RXFNE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_RXNEIE_RXFNEIE) == (USART_CR1_RXNEIE_RXFNEIE)) ? 1UL : 0UL); -} - -#else -/** - * @brief Check if the USART RX Not Empty Interrupt is enabled or disabled. - * @rmtoll CR1 RXNEIE LL_USART_IsEnabledIT_RXNE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXNE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_RXNEIE) == (USART_CR1_RXNEIE)) ? 1U : 0U); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Check if the USART Transmission Complete Interrupt is enabled or disabled. - * @rmtoll CR1 TCIE LL_USART_IsEnabledIT_TC - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TC(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_TCIE) == (USART_CR1_TCIE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/* Legacy define */ -#define LL_USART_IsEnabledIT_TXE LL_USART_IsEnabledIT_TXE_TXFNF - -/** - * @brief Check if the USART TX Empty and USART TX FIFO Not Full Interrupt is enabled or disabled - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 TXEIE_TXFNFIE LL_USART_IsEnabledIT_TXE_TXFNF - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXE_TXFNF(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_TXEIE_TXFNFIE) == (USART_CR1_TXEIE_TXFNFIE)) ? 1UL : 0UL); -} - -#else -/** - * @brief Check if the USART TX Empty Interrupt is enabled or disabled. - * @rmtoll CR1 TXEIE LL_USART_IsEnabledIT_TXE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_TXEIE) == (USART_CR1_TXEIE)) ? 1U : 0U); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Check if the USART Parity Error Interrupt is enabled or disabled. - * @rmtoll CR1 PEIE LL_USART_IsEnabledIT_PE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_PE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_PEIE) == (USART_CR1_PEIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Character Match Interrupt is enabled or disabled. - * @rmtoll CR1 CMIE LL_USART_IsEnabledIT_CM - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_CM(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_CMIE) == (USART_CR1_CMIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Receiver Timeout Interrupt is enabled or disabled. - * @rmtoll CR1 RTOIE LL_USART_IsEnabledIT_RTO - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RTO(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_RTOIE) == (USART_CR1_RTOIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART End Of Block Interrupt is enabled or disabled. - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR1 EOBIE LL_USART_IsEnabledIT_EOB - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_EOB(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_EOBIE) == (USART_CR1_EOBIE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Check if the USART TX FIFO Empty Interrupt is enabled or disabled - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 TXFEIE LL_USART_IsEnabledIT_TXFE - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXFE(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_TXFEIE) == (USART_CR1_TXFEIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART RX FIFO Full Interrupt is enabled or disabled - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR1 RXFFIE LL_USART_IsEnabledIT_RXFF - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXFF(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR1, USART_CR1_RXFFIE) == (USART_CR1_RXFFIE)) ? 1UL : 0UL); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Check if the USART LIN Break Detection Interrupt is enabled or disabled. - * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not - * LIN feature is supported by the USARTx instance. - * @rmtoll CR2 LBDIE LL_USART_IsEnabledIT_LBD - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_LBD(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR2, USART_CR2_LBDIE) == (USART_CR2_LBDIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Error Interrupt is enabled or disabled. - * @rmtoll CR3 EIE LL_USART_IsEnabledIT_ERROR - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_ERROR(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_EIE) == (USART_CR3_EIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART CTS Interrupt is enabled or disabled. - * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not - * Hardware Flow control feature is supported by the USARTx instance. - * @rmtoll CR3 CTSIE LL_USART_IsEnabledIT_CTS - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_CTS(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_CTSIE) == (USART_CR3_CTSIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the USART Wake Up from Stop Mode Interrupt is enabled or disabled. - * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not - * Wake-up from Stop mode feature is supported by the USARTx instance. - * @rmtoll CR3 WUFIE LL_USART_IsEnabledIT_WKUP - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_WKUP(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_WUFIE) == (USART_CR3_WUFIE)) ? 1UL : 0UL); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Check if USART TX FIFO Threshold Interrupt is enabled or disabled - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 TXFTIE LL_USART_IsEnabledIT_TXFT - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXFT(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_TXFTIE) == (USART_CR3_TXFTIE)) ? 1UL : 0UL); -} - -#endif /* USART_CR1_FIFOEN */ -#if defined(USART_TCBGT_SUPPORT) -/* Function available only on devices supporting Transmit Complete before Guard Time feature */ -/** - * @brief Check if the Smartcard Transmission Complete Before Guard Time Interrupt is enabled or disabled. - * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not - * Smartcard feature is supported by the USARTx instance. - * @rmtoll CR3 TCBGTIE LL_USART_IsEnabledIT_TCBGT - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TCBGT(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_TCBGTIE) == (USART_CR3_TCBGTIE)) ? 1UL : 0UL); -} -#endif /* USART_TCBGT_SUPPORT */ - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Check if USART RX FIFO Threshold Interrupt is enabled or disabled - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @rmtoll CR3 RXFTIE LL_USART_IsEnabledIT_RXFT - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXFT(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_RXFTIE) == (USART_CR3_RXFTIE)) ? 1UL : 0UL); -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ - -/** @defgroup USART_LL_EF_DMA_Management DMA_Management - * @{ - */ - -/** - * @brief Enable DMA Mode for reception - * @rmtoll CR3 DMAR LL_USART_EnableDMAReq_RX - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableDMAReq_RX(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAR); -} - -/** - * @brief Disable DMA Mode for reception - * @rmtoll CR3 DMAR LL_USART_DisableDMAReq_RX - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableDMAReq_RX(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAR); -} - -/** - * @brief Check if DMA Mode is enabled for reception - * @rmtoll CR3 DMAR LL_USART_IsEnabledDMAReq_RX - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_RX(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_DMAR) == (USART_CR3_DMAR)) ? 1UL : 0UL); -} - -/** - * @brief Enable DMA Mode for transmission - * @rmtoll CR3 DMAT LL_USART_EnableDMAReq_TX - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableDMAReq_TX(USART_TypeDef *USARTx) -{ - ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAT); -} - -/** - * @brief Disable DMA Mode for transmission - * @rmtoll CR3 DMAT LL_USART_DisableDMAReq_TX - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableDMAReq_TX(USART_TypeDef *USARTx) -{ - ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAT); -} - -/** - * @brief Check if DMA Mode is enabled for transmission - * @rmtoll CR3 DMAT LL_USART_IsEnabledDMAReq_TX - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_TX(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_DMAT) == (USART_CR3_DMAT)) ? 1UL : 0UL); -} - -/** - * @brief Enable DMA Disabling on Reception Error - * @rmtoll CR3 DDRE LL_USART_EnableDMADeactOnRxErr - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_EnableDMADeactOnRxErr(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->CR3, USART_CR3_DDRE); -} - -/** - * @brief Disable DMA Disabling on Reception Error - * @rmtoll CR3 DDRE LL_USART_DisableDMADeactOnRxErr - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_DisableDMADeactOnRxErr(USART_TypeDef *USARTx) -{ - CLEAR_BIT(USARTx->CR3, USART_CR3_DDRE); -} - -/** - * @brief Indicate if DMA Disabling on Reception Error is disabled - * @rmtoll CR3 DDRE LL_USART_IsEnabledDMADeactOnRxErr - * @param USARTx USART Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_USART_IsEnabledDMADeactOnRxErr(const USART_TypeDef *USARTx) -{ - return ((READ_BIT(USARTx->CR3, USART_CR3_DDRE) == (USART_CR3_DDRE)) ? 1UL : 0UL); -} - -/** - * @brief Get the data register address used for DMA transfer - * @rmtoll RDR RDR LL_USART_DMA_GetRegAddr\n - * @rmtoll TDR TDR LL_USART_DMA_GetRegAddr - * @param USARTx USART Instance - * @param Direction This parameter can be one of the following values: - * @arg @ref LL_USART_DMA_REG_DATA_TRANSMIT - * @arg @ref LL_USART_DMA_REG_DATA_RECEIVE - * @retval Address of data register - */ -__STATIC_INLINE uint32_t LL_USART_DMA_GetRegAddr(const USART_TypeDef *USARTx, uint32_t Direction) -{ - uint32_t data_reg_addr; - - if (Direction == LL_USART_DMA_REG_DATA_TRANSMIT) - { - /* return address of TDR register */ - data_reg_addr = (uint32_t) &(USARTx->TDR); - } - else - { - /* return address of RDR register */ - data_reg_addr = (uint32_t) &(USARTx->RDR); - } - - return data_reg_addr; -} - -/** - * @} - */ - -/** @defgroup USART_LL_EF_Data_Management Data_Management - * @{ - */ - -/** - * @brief Read Receiver Data register (Receive Data value, 8 bits) - * @rmtoll RDR RDR LL_USART_ReceiveData8 - * @param USARTx USART Instance - * @retval Value between Min_Data=0x00 and Max_Data=0xFF - */ -__STATIC_INLINE uint8_t LL_USART_ReceiveData8(const USART_TypeDef *USARTx) -{ - return (uint8_t)(READ_BIT(USARTx->RDR, USART_RDR_RDR) & 0xFFU); -} - -/** - * @brief Read Receiver Data register (Receive Data value, 9 bits) - * @rmtoll RDR RDR LL_USART_ReceiveData9 - * @param USARTx USART Instance - * @retval Value between Min_Data=0x00 and Max_Data=0x1FF - */ -__STATIC_INLINE uint16_t LL_USART_ReceiveData9(const USART_TypeDef *USARTx) -{ - return (uint16_t)(READ_BIT(USARTx->RDR, USART_RDR_RDR)); -} - -/** - * @brief Write in Transmitter Data Register (Transmit Data value, 8 bits) - * @rmtoll TDR TDR LL_USART_TransmitData8 - * @param USARTx USART Instance - * @param Value between Min_Data=0x00 and Max_Data=0xFF - * @retval None - */ -__STATIC_INLINE void LL_USART_TransmitData8(USART_TypeDef *USARTx, uint8_t Value) -{ - USARTx->TDR = Value; -} - -/** - * @brief Write in Transmitter Data Register (Transmit Data value, 9 bits) - * @rmtoll TDR TDR LL_USART_TransmitData9 - * @param USARTx USART Instance - * @param Value between Min_Data=0x00 and Max_Data=0x1FF - * @retval None - */ -__STATIC_INLINE void LL_USART_TransmitData9(USART_TypeDef *USARTx, uint16_t Value) -{ - USARTx->TDR = (uint16_t)(Value & 0x1FFUL); -} - -/** - * @} - */ - -/** @defgroup USART_LL_EF_Execution Execution - * @{ - */ - -/** - * @brief Request an Automatic Baud Rate measurement on next received data frame - * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not - * Auto Baud Rate detection feature is supported by the USARTx instance. - * @rmtoll RQR ABRRQ LL_USART_RequestAutoBaudRate - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_RequestAutoBaudRate(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_ABRRQ); -} - -/** - * @brief Request Break sending - * @rmtoll RQR SBKRQ LL_USART_RequestBreakSending - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_RequestBreakSending(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_SBKRQ); -} - -/** - * @brief Put USART in mute mode and set the RWU flag - * @rmtoll RQR MMRQ LL_USART_RequestEnterMuteMode - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_RequestEnterMuteMode(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_MMRQ); -} - -/** - @if USART_CR1_FIFOEN - * @brief Request a Receive Data and FIFO flush - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - * @note Allows to discard the received data without reading them, and avoid an overrun - * condition. - @else - * @brief Request a Receive Data flush - @endif - * @rmtoll RQR RXFRQ LL_USART_RequestRxDataFlush - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_RequestRxDataFlush(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_RXFRQ); -} - -/** - @if USART_CR1_FIFOEN - * @brief Request a Transmit data and FIFO flush - * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not - * FIFO mode feature is supported by the USARTx instance. - @else - * @brief Request a Transmit data flush - @endif - * @rmtoll RQR TXFRQ LL_USART_RequestTxDataFlush - * @param USARTx USART Instance - * @retval None - */ -__STATIC_INLINE void LL_USART_RequestTxDataFlush(USART_TypeDef *USARTx) -{ - SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_TXFRQ); -} - -/** - * @} - */ - -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup USART_LL_EF_Init Initialization and de-initialization functions - * @{ - */ -ErrorStatus LL_USART_DeInit(const USART_TypeDef *USARTx); -ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, const LL_USART_InitTypeDef *USART_InitStruct); -void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct); -ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, const LL_USART_ClockInitTypeDef *USART_ClockInitStruct); -void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct); -/** - * @} - */ -#endif /* USE_FULL_LL_DRIVER */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /* USART1 || USART2 || USART3 || UART4 || UART5 */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* STM32L4xx_LL_USART_H */ - diff --git a/Firmware/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c b/Firmware/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c deleted file mode 100644 index 143bc6a..0000000 --- a/Firmware/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c +++ /dev/null @@ -1,4840 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l4xx_hal_uart.c - * @author MCD Application Team - * @brief UART HAL module driver. - * This file provides firmware functions to manage the following - * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). - * + Initialization and de-initialization functions - * + IO operation functions - * + Peripheral Control functions - * - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - @verbatim - =============================================================================== - ##### How to use this driver ##### - =============================================================================== - [..] - The UART HAL driver can be used as follows: - - (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart). - (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API: - (++) Enable the USARTx interface clock. - (++) UART pins configuration: - (+++) Enable the clock for the UART GPIOs. - (+++) Configure these UART pins as alternate function pull-up. - (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() - and HAL_UART_Receive_IT() APIs): - (+++) Configure the USARTx interrupt priority. - (+++) Enable the NVIC USART IRQ handle. - (++) UART interrupts handling: - -@@- The specific UART interrupts (Transmission complete interrupt, - RXNE interrupt, RX/TX FIFOs related interrupts and Error Interrupts) - are managed using the macros __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() - inside the transmit and receive processes. - (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() - and HAL_UART_Receive_DMA() APIs): - (+++) Declare a DMA handle structure for the Tx/Rx channel. - (+++) Enable the DMAx interface clock. - (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. - (+++) Configure the DMA Tx/Rx channel. - (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. - (+++) Configure the priority and enable the NVIC for the transfer complete - interrupt on the DMA Tx/Rx channel. - - (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Prescaler value , Hardware - flow control and Mode (Receiver/Transmitter) in the huart handle Init structure. - - (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...) - in the huart handle AdvancedInit structure. - - (#) For the UART asynchronous mode, initialize the UART registers by calling - the HAL_UART_Init() API. - - (#) For the UART Half duplex mode, initialize the UART registers by calling - the HAL_HalfDuplex_Init() API. - - (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers - by calling the HAL_LIN_Init() API. - - (#) For the UART Multiprocessor mode, initialize the UART registers - by calling the HAL_MultiProcessor_Init() API. - - (#) For the UART RS485 Driver Enabled mode, initialize the UART registers - by calling the HAL_RS485Ex_Init() API. - - [..] - (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(), - also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by - calling the customized HAL_UART_MspInit() API. - - ##### Callback registration ##### - ================================== - - [..] - The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1 - allows the user to configure dynamically the driver callbacks. - - [..] - Use Function HAL_UART_RegisterCallback() to register a user callback. - Function HAL_UART_RegisterCallback() allows to register following callbacks: - (+) TxHalfCpltCallback : Tx Half Complete Callback. - (+) TxCpltCallback : Tx Complete Callback. - (+) RxHalfCpltCallback : Rx Half Complete Callback. - (+) RxCpltCallback : Rx Complete Callback. - (+) ErrorCallback : Error Callback. - (+) AbortCpltCallback : Abort Complete Callback. - (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. - (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. - (+) WakeupCallback : Wakeup Callback. -#if defined(USART_CR1_FIFOEN) - (+) RxFifoFullCallback : Rx Fifo Full Callback. - (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. -#endif - (+) MspInitCallback : UART MspInit. - (+) MspDeInitCallback : UART MspDeInit. - This function takes as parameters the HAL peripheral handle, the Callback ID - and a pointer to the user callback function. - - [..] - Use function HAL_UART_UnRegisterCallback() to reset a callback to the default - weak (surcharged) function. - HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle, - and the Callback ID. - This function allows to reset following callbacks: - (+) TxHalfCpltCallback : Tx Half Complete Callback. - (+) TxCpltCallback : Tx Complete Callback. - (+) RxHalfCpltCallback : Rx Half Complete Callback. - (+) RxCpltCallback : Rx Complete Callback. - (+) ErrorCallback : Error Callback. - (+) AbortCpltCallback : Abort Complete Callback. - (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. - (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. - (+) WakeupCallback : Wakeup Callback. -#if defined(USART_CR1_FIFOEN) - (+) RxFifoFullCallback : Rx Fifo Full Callback. - (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. -#endif - (+) MspInitCallback : UART MspInit. - (+) MspDeInitCallback : UART MspDeInit. - - [..] - For specific callback RxEventCallback, use dedicated registration/reset functions: - respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback(). - - [..] - By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET - all callbacks are set to the corresponding weak (surcharged) functions: - examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback(). - Exception done for MspInit and MspDeInit functions that are respectively - reset to the legacy weak (surcharged) functions in the HAL_UART_Init() - and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand). - If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit() - keep and use the user MspInit/MspDeInit callbacks (registered beforehand). - - [..] - Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only. - Exception done MspInit/MspDeInit that can be registered/unregistered - in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user) - MspInit/DeInit callbacks can be used during the Init/DeInit. - In that case first register the MspInit/MspDeInit user callbacks - using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit() - or HAL_UART_Init() function. - - [..] - When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or - not defined, the callback registration feature is not available - and weak (surcharged) callbacks are used. - - - @endverbatim - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l4xx_hal.h" - -/** @addtogroup STM32L4xx_HAL_Driver - * @{ - */ - -/** @defgroup UART UART - * @brief HAL UART module driver - * @{ - */ - -#ifdef HAL_UART_MODULE_ENABLED - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/** @defgroup UART_Private_Constants UART Private Constants - * @{ - */ -#if defined(USART_CR1_FIFOEN) -#define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \ - USART_CR1_OVER8 | USART_CR1_FIFOEN)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ -#else -#define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \ - USART_CR1_OVER8)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ -#endif /* USART_CR1_FIFOEN */ - -#if defined(USART_CR1_FIFOEN) -#define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT | USART_CR3_TXFTCFG | \ - USART_CR3_RXFTCFG)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */ -#else -#define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE |\ - USART_CR3_ONEBIT)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */ -#endif /* USART_CR1_FIFOEN */ - -#define LPUART_BRR_MIN 0x00000300U /* LPUART BRR minimum authorized value */ -#define LPUART_BRR_MAX 0x000FFFFFU /* LPUART BRR maximum authorized value */ - -#define UART_BRR_MIN 0x10U /* UART BRR minimum authorized value */ -#define UART_BRR_MAX 0x0000FFFFU /* UART BRR maximum authorized value */ -/** - * @} - */ - -/* Private macros ------------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/** @addtogroup UART_Private_Functions - * @{ - */ -static void UART_EndTxTransfer(UART_HandleTypeDef *huart); -static void UART_EndRxTransfer(UART_HandleTypeDef *huart); -static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma); -static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); -static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); -static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); -static void UART_DMAError(DMA_HandleTypeDef *hdma); -static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma); -static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma); -static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma); -static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); -static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); -static void UART_TxISR_8BIT(UART_HandleTypeDef *huart); -static void UART_TxISR_16BIT(UART_HandleTypeDef *huart); -#if defined(USART_CR1_FIFOEN) -static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart); -static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart); -#endif /* USART_CR1_FIFOEN */ -static void UART_EndTransmit_IT(UART_HandleTypeDef *huart); -static void UART_RxISR_8BIT(UART_HandleTypeDef *huart); -static void UART_RxISR_16BIT(UART_HandleTypeDef *huart); -#if defined(USART_CR1_FIFOEN) -static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart); -static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart); -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ - -/* Private variables ---------------------------------------------------------*/ -#if defined(USART_PRESC_PRESCALER) -/** @addtogroup UART_Private_variables - * @{ - */ -const uint16_t UARTPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U}; -/** - * @} - */ - -#endif /* USART_PRESC_PRESCALER */ -/* Exported Constants --------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/** @defgroup UART_Exported_Functions UART Exported Functions - * @{ - */ - -/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and Configuration functions - * -@verbatim -=============================================================================== - ##### Initialization and Configuration functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to initialize the USARTx or the UARTy - in asynchronous mode. - (+) For the asynchronous mode the parameters below can be configured: - (++) Baud Rate - (++) Word Length - (++) Stop Bit - (++) Parity: If the parity is enabled, then the MSB bit of the data written - in the data register is transmitted but is changed by the parity bit. - (++) Hardware flow control - (++) Receiver/transmitter modes - (++) Over Sampling Method - (++) One-Bit Sampling Method - (+) For the asynchronous mode, the following advanced features can be configured as well: - (++) TX and/or RX pin level inversion - (++) data logical level inversion - (++) RX and TX pins swap - (++) RX overrun detection disabling - (++) DMA disabling on RX error - (++) MSB first on communication line - (++) auto Baud rate detection - [..] - The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API - follow respectively the UART asynchronous, UART Half duplex, UART LIN mode - and UART multiprocessor mode configuration procedures (details for the procedures - are available in reference manual). - -@endverbatim - - Depending on the frame length defined by the M1 and M0 bits (7-bit, - 8-bit or 9-bit), the possible UART formats are listed in the - following table. - - Table 1. UART frame format. - +-----------------------------------------------------------------------+ - | M1 bit | M0 bit | PCE bit | UART frame | - |---------|---------|-----------|---------------------------------------| - | 0 | 0 | 0 | | SB | 8 bit data | STB | | - |---------|---------|-----------|---------------------------------------| - | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | - |---------|---------|-----------|---------------------------------------| - | 0 | 1 | 0 | | SB | 9 bit data | STB | | - |---------|---------|-----------|---------------------------------------| - | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | - |---------|---------|-----------|---------------------------------------| - | 1 | 0 | 0 | | SB | 7 bit data | STB | | - |---------|---------|-----------|---------------------------------------| - | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | - +-----------------------------------------------------------------------+ - - * @{ - */ - -/** - * @brief Initialize the UART mode according to the specified - * parameters in the UART_InitTypeDef and initialize the associated handle. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) -{ - /* Check the UART handle allocation */ - if (huart == NULL) - { - return HAL_ERROR; - } - - if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) - { - /* Check the parameters */ - assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); - } - else - { - /* Check the parameters */ - assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance))); - } - - if (huart->gState == HAL_UART_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - huart->Lock = HAL_UNLOCKED; - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - UART_InitCallbacksToDefault(huart); - - if (huart->MspInitCallback == NULL) - { - huart->MspInitCallback = HAL_UART_MspInit; - } - - /* Init the low level hardware */ - huart->MspInitCallback(huart); -#else - /* Init the low level hardware : GPIO, CLOCK */ - HAL_UART_MspInit(huart); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - - huart->gState = HAL_UART_STATE_BUSY; - - __HAL_UART_DISABLE(huart); - - /* Set the UART Communication parameters */ - if (UART_SetConfig(huart) == HAL_ERROR) - { - return HAL_ERROR; - } - - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) - { - UART_AdvFeatureConfig(huart); - } - - /* In asynchronous mode, the following bits must be kept cleared: - - LINEN and CLKEN bits in the USART_CR2 register, - - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ - CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); - CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); - - __HAL_UART_ENABLE(huart); - - /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ - return (UART_CheckIdleState(huart)); -} - -/** - * @brief Initialize the half-duplex mode according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) -{ - /* Check the UART handle allocation */ - if (huart == NULL) - { - return HAL_ERROR; - } - - /* Check UART instance */ - assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance)); - - if (huart->gState == HAL_UART_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - huart->Lock = HAL_UNLOCKED; - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - UART_InitCallbacksToDefault(huart); - - if (huart->MspInitCallback == NULL) - { - huart->MspInitCallback = HAL_UART_MspInit; - } - - /* Init the low level hardware */ - huart->MspInitCallback(huart); -#else - /* Init the low level hardware : GPIO, CLOCK */ - HAL_UART_MspInit(huart); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - - huart->gState = HAL_UART_STATE_BUSY; - - __HAL_UART_DISABLE(huart); - - /* Set the UART Communication parameters */ - if (UART_SetConfig(huart) == HAL_ERROR) - { - return HAL_ERROR; - } - - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) - { - UART_AdvFeatureConfig(huart); - } - - /* In half-duplex mode, the following bits must be kept cleared: - - LINEN and CLKEN bits in the USART_CR2 register, - - SCEN and IREN bits in the USART_CR3 register.*/ - CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); - CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN)); - - /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ - SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL); - - __HAL_UART_ENABLE(huart); - - /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ - return (UART_CheckIdleState(huart)); -} - - -/** - * @brief Initialize the LIN mode according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle. - * @param huart UART handle. - * @param BreakDetectLength Specifies the LIN break detection length. - * This parameter can be one of the following values: - * @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection - * @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection - * @retval HAL status - */ -HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength) -{ - /* Check the UART handle allocation */ - if (huart == NULL) - { - return HAL_ERROR; - } - - /* Check the LIN UART instance */ - assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); - /* Check the Break detection length parameter */ - assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength)); - - /* LIN mode limited to 16-bit oversampling only */ - if (huart->Init.OverSampling == UART_OVERSAMPLING_8) - { - return HAL_ERROR; - } - /* LIN mode limited to 8-bit data length */ - if (huart->Init.WordLength != UART_WORDLENGTH_8B) - { - return HAL_ERROR; - } - - if (huart->gState == HAL_UART_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - huart->Lock = HAL_UNLOCKED; - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - UART_InitCallbacksToDefault(huart); - - if (huart->MspInitCallback == NULL) - { - huart->MspInitCallback = HAL_UART_MspInit; - } - - /* Init the low level hardware */ - huart->MspInitCallback(huart); -#else - /* Init the low level hardware : GPIO, CLOCK */ - HAL_UART_MspInit(huart); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - - huart->gState = HAL_UART_STATE_BUSY; - - __HAL_UART_DISABLE(huart); - - /* Set the UART Communication parameters */ - if (UART_SetConfig(huart) == HAL_ERROR) - { - return HAL_ERROR; - } - - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) - { - UART_AdvFeatureConfig(huart); - } - - /* In LIN mode, the following bits must be kept cleared: - - LINEN and CLKEN bits in the USART_CR2 register, - - SCEN and IREN bits in the USART_CR3 register.*/ - CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN); - CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN)); - - /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ - SET_BIT(huart->Instance->CR2, USART_CR2_LINEN); - - /* Set the USART LIN Break detection length. */ - MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength); - - __HAL_UART_ENABLE(huart); - - /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ - return (UART_CheckIdleState(huart)); -} - - -/** - * @brief Initialize the multiprocessor mode according to the specified - * parameters in the UART_InitTypeDef and initialize the associated handle. - * @param huart UART handle. - * @param Address UART node address (4-, 6-, 7- or 8-bit long). - * @param WakeUpMethod Specifies the UART wakeup method. - * This parameter can be one of the following values: - * @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection - * @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark - * @note If the user resorts to idle line detection wake up, the Address parameter - * is useless and ignored by the initialization function. - * @note If the user resorts to address mark wake up, the address length detection - * is configured by default to 4 bits only. For the UART to be able to - * manage 6-, 7- or 8-bit long addresses detection, the API - * HAL_MultiProcessorEx_AddressLength_Set() must be called after - * HAL_MultiProcessor_Init(). - * @retval HAL status - */ -HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod) -{ - /* Check the UART handle allocation */ - if (huart == NULL) - { - return HAL_ERROR; - } - - /* Check the wake up method parameter */ - assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod)); - - if (huart->gState == HAL_UART_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - huart->Lock = HAL_UNLOCKED; - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - UART_InitCallbacksToDefault(huart); - - if (huart->MspInitCallback == NULL) - { - huart->MspInitCallback = HAL_UART_MspInit; - } - - /* Init the low level hardware */ - huart->MspInitCallback(huart); -#else - /* Init the low level hardware : GPIO, CLOCK */ - HAL_UART_MspInit(huart); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - - huart->gState = HAL_UART_STATE_BUSY; - - __HAL_UART_DISABLE(huart); - - /* Set the UART Communication parameters */ - if (UART_SetConfig(huart) == HAL_ERROR) - { - return HAL_ERROR; - } - - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) - { - UART_AdvFeatureConfig(huart); - } - - /* In multiprocessor mode, the following bits must be kept cleared: - - LINEN and CLKEN bits in the USART_CR2 register, - - SCEN, HDSEL and IREN bits in the USART_CR3 register. */ - CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); - CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); - - if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK) - { - /* If address mark wake up method is chosen, set the USART address node */ - MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS)); - } - - /* Set the wake up method by setting the WAKE bit in the CR1 register */ - MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod); - - __HAL_UART_ENABLE(huart); - - /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ - return (UART_CheckIdleState(huart)); -} - - -/** - * @brief DeInitialize the UART peripheral. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) -{ - /* Check the UART handle allocation */ - if (huart == NULL) - { - return HAL_ERROR; - } - - /* Check the parameters */ - assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance))); - - huart->gState = HAL_UART_STATE_BUSY; - - __HAL_UART_DISABLE(huart); - - huart->Instance->CR1 = 0x0U; - huart->Instance->CR2 = 0x0U; - huart->Instance->CR3 = 0x0U; - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - if (huart->MspDeInitCallback == NULL) - { - huart->MspDeInitCallback = HAL_UART_MspDeInit; - } - /* DeInit the low level hardware */ - huart->MspDeInitCallback(huart); -#else - /* DeInit the low level hardware */ - HAL_UART_MspDeInit(huart); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->gState = HAL_UART_STATE_RESET; - huart->RxState = HAL_UART_STATE_RESET; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @brief Initialize the UART MSP. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_MspInit can be implemented in the user file - */ -} - -/** - * @brief DeInitialize the UART MSP. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_MspDeInit can be implemented in the user file - */ -} - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) -/** - * @brief Register a User UART Callback - * To be used instead of the weak predefined callback - * @param huart uart handle - * @param CallbackID ID of the callback to be registered - * This parameter can be one of the following values: - * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID - * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID - * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID - * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID - * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID - * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID - * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID - * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID - * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID -#if defined(USART_CR1_FIFOEN) - * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID - * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID -#endif - * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID - * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID - * @param pCallback pointer to the Callback function - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID, - pUART_CallbackTypeDef pCallback) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (pCallback == NULL) - { - huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; - - return HAL_ERROR; - } - - __HAL_LOCK(huart); - - if (huart->gState == HAL_UART_STATE_READY) - { - switch (CallbackID) - { - case HAL_UART_TX_HALFCOMPLETE_CB_ID : - huart->TxHalfCpltCallback = pCallback; - break; - - case HAL_UART_TX_COMPLETE_CB_ID : - huart->TxCpltCallback = pCallback; - break; - - case HAL_UART_RX_HALFCOMPLETE_CB_ID : - huart->RxHalfCpltCallback = pCallback; - break; - - case HAL_UART_RX_COMPLETE_CB_ID : - huart->RxCpltCallback = pCallback; - break; - - case HAL_UART_ERROR_CB_ID : - huart->ErrorCallback = pCallback; - break; - - case HAL_UART_ABORT_COMPLETE_CB_ID : - huart->AbortCpltCallback = pCallback; - break; - - case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID : - huart->AbortTransmitCpltCallback = pCallback; - break; - - case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID : - huart->AbortReceiveCpltCallback = pCallback; - break; - - case HAL_UART_WAKEUP_CB_ID : - huart->WakeupCallback = pCallback; - break; - -#if defined(USART_CR1_FIFOEN) - case HAL_UART_RX_FIFO_FULL_CB_ID : - huart->RxFifoFullCallback = pCallback; - break; - - case HAL_UART_TX_FIFO_EMPTY_CB_ID : - huart->TxFifoEmptyCallback = pCallback; - break; -#endif /* USART_CR1_FIFOEN */ - - case HAL_UART_MSPINIT_CB_ID : - huart->MspInitCallback = pCallback; - break; - - case HAL_UART_MSPDEINIT_CB_ID : - huart->MspDeInitCallback = pCallback; - break; - - default : - huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; - - status = HAL_ERROR; - break; - } - } - else if (huart->gState == HAL_UART_STATE_RESET) - { - switch (CallbackID) - { - case HAL_UART_MSPINIT_CB_ID : - huart->MspInitCallback = pCallback; - break; - - case HAL_UART_MSPDEINIT_CB_ID : - huart->MspDeInitCallback = pCallback; - break; - - default : - huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; - - status = HAL_ERROR; - break; - } - } - else - { - huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; - - status = HAL_ERROR; - } - - __HAL_UNLOCK(huart); - - return status; -} - -/** - * @brief Unregister an UART Callback - * UART callaback is redirected to the weak predefined callback - * @param huart uart handle - * @param CallbackID ID of the callback to be unregistered - * This parameter can be one of the following values: - * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID - * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID - * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID - * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID - * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID - * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID - * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID - * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID - * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID -#if defined(USART_CR1_FIFOEN) - * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID - * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID -#endif - * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID - * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID) -{ - HAL_StatusTypeDef status = HAL_OK; - - __HAL_LOCK(huart); - - if (HAL_UART_STATE_READY == huart->gState) - { - switch (CallbackID) - { - case HAL_UART_TX_HALFCOMPLETE_CB_ID : - huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ - break; - - case HAL_UART_TX_COMPLETE_CB_ID : - huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */ - break; - - case HAL_UART_RX_HALFCOMPLETE_CB_ID : - huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ - break; - - case HAL_UART_RX_COMPLETE_CB_ID : - huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */ - break; - - case HAL_UART_ERROR_CB_ID : - huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */ - break; - - case HAL_UART_ABORT_COMPLETE_CB_ID : - huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ - break; - - case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID : - huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak - AbortTransmitCpltCallback */ - break; - - case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID : - huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak - AbortReceiveCpltCallback */ - break; - - case HAL_UART_WAKEUP_CB_ID : - huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */ - break; - -#if defined(USART_CR1_FIFOEN) - case HAL_UART_RX_FIFO_FULL_CB_ID : - huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ - break; - - case HAL_UART_TX_FIFO_EMPTY_CB_ID : - huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ - break; - -#endif /* USART_CR1_FIFOEN */ - case HAL_UART_MSPINIT_CB_ID : - huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */ - break; - - case HAL_UART_MSPDEINIT_CB_ID : - huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */ - break; - - default : - huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; - - status = HAL_ERROR; - break; - } - } - else if (HAL_UART_STATE_RESET == huart->gState) - { - switch (CallbackID) - { - case HAL_UART_MSPINIT_CB_ID : - huart->MspInitCallback = HAL_UART_MspInit; - break; - - case HAL_UART_MSPDEINIT_CB_ID : - huart->MspDeInitCallback = HAL_UART_MspDeInit; - break; - - default : - huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; - - status = HAL_ERROR; - break; - } - } - else - { - huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; - - status = HAL_ERROR; - } - - __HAL_UNLOCK(huart); - - return status; -} - -/** - * @brief Register a User UART Rx Event Callback - * To be used instead of the weak predefined callback - * @param huart Uart handle - * @param pCallback Pointer to the Rx Event Callback function - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (pCallback == NULL) - { - huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; - - return HAL_ERROR; - } - - /* Process locked */ - __HAL_LOCK(huart); - - if (huart->gState == HAL_UART_STATE_READY) - { - huart->RxEventCallback = pCallback; - } - else - { - huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; - - status = HAL_ERROR; - } - - /* Release Lock */ - __HAL_UNLOCK(huart); - - return status; -} - -/** - * @brief UnRegister the UART Rx Event Callback - * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback - * @param huart Uart handle - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart) -{ - HAL_StatusTypeDef status = HAL_OK; - - /* Process locked */ - __HAL_LOCK(huart); - - if (huart->gState == HAL_UART_STATE_READY) - { - huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */ - } - else - { - huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; - - status = HAL_ERROR; - } - - /* Release Lock */ - __HAL_UNLOCK(huart); - return status; -} - -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - -/** - * @} - */ - -/** @defgroup UART_Exported_Functions_Group2 IO operation functions - * @brief UART Transmit/Receive functions - * -@verbatim - =============================================================================== - ##### IO operation functions ##### - =============================================================================== - This subsection provides a set of functions allowing to manage the UART asynchronous - and Half duplex data transfers. - - (#) There are two mode of transfer: - (+) Blocking mode: The communication is performed in polling mode. - The HAL status of all data processing is returned by the same function - after finishing transfer. - (+) Non-Blocking mode: The communication is performed using Interrupts - or DMA, These API's return the HAL status. - The end of the data processing will be indicated through the - dedicated UART IRQ when using Interrupt mode or the DMA IRQ when - using DMA mode. - The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks - will be executed respectively at the end of the transmit or Receive process - The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected - - (#) Blocking mode API's are : - (+) HAL_UART_Transmit() - (+) HAL_UART_Receive() - - (#) Non-Blocking mode API's with Interrupt are : - (+) HAL_UART_Transmit_IT() - (+) HAL_UART_Receive_IT() - (+) HAL_UART_IRQHandler() - - (#) Non-Blocking mode API's with DMA are : - (+) HAL_UART_Transmit_DMA() - (+) HAL_UART_Receive_DMA() - (+) HAL_UART_DMAPause() - (+) HAL_UART_DMAResume() - (+) HAL_UART_DMAStop() - - (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode: - (+) HAL_UART_TxHalfCpltCallback() - (+) HAL_UART_TxCpltCallback() - (+) HAL_UART_RxHalfCpltCallback() - (+) HAL_UART_RxCpltCallback() - (+) HAL_UART_ErrorCallback() - - (#) Non-Blocking mode transfers could be aborted using Abort API's : - (+) HAL_UART_Abort() - (+) HAL_UART_AbortTransmit() - (+) HAL_UART_AbortReceive() - (+) HAL_UART_Abort_IT() - (+) HAL_UART_AbortTransmit_IT() - (+) HAL_UART_AbortReceive_IT() - - (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided: - (+) HAL_UART_AbortCpltCallback() - (+) HAL_UART_AbortTransmitCpltCallback() - (+) HAL_UART_AbortReceiveCpltCallback() - - (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced - reception services: - (+) HAL_UARTEx_RxEventCallback() - - (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. - Errors are handled as follows : - (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is - to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error - in Interrupt mode reception . - Received character is then retrieved and stored in Rx buffer, Error code is set to allow user - to identify error type, and HAL_UART_ErrorCallback() user callback is executed. - Transfer is kept ongoing on UART side. - If user wants to abort it, Abort services should be called by user. - (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. - This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. - Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() - user callback is executed. - - -@- In the Half duplex communication, it is forbidden to run the transmit - and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful. - -@endverbatim - * @{ - */ - -/** - * @brief Send an amount of data in blocking mode. - * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), - * the sent data is handled as a set of u16. In this case, Size must indicate the number - * of u16 provided through pData. - * @note When FIFO mode is enabled, writing a data in the TDR register adds one - * data to the TXFIFO. Write operations to the TDR register are performed - * when TXFNF flag is set. From hardware perspective, TXFNF flag and - * TXE are mapped on the same bit-field. - * @param huart UART handle. - * @param pData Pointer to data buffer (u8 or u16 data elements). - * @param Size Amount of data elements (u8 or u16) to be sent. - * @param Timeout Timeout duration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ - const uint8_t *pdata8bits; - const uint16_t *pdata16bits; - uint32_t tickstart; - - /* Check that a Tx process is not already ongoing */ - if (huart->gState == HAL_UART_STATE_READY) - { - if ((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - __HAL_LOCK(huart); - - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->gState = HAL_UART_STATE_BUSY_TX; - - /* Init tickstart for timeout management */ - tickstart = HAL_GetTick(); - - huart->TxXferSize = Size; - huart->TxXferCount = Size; - - /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - pdata8bits = NULL; - pdata16bits = (const uint16_t *) pData; - } - else - { - pdata8bits = pData; - pdata16bits = NULL; - } - - __HAL_UNLOCK(huart); - - while (huart->TxXferCount > 0U) - { - if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) - { - return HAL_TIMEOUT; - } - if (pdata8bits == NULL) - { - huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU); - pdata16bits++; - } - else - { - huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU); - pdata8bits++; - } - huart->TxXferCount--; - } - - if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* At end of Tx process, restore huart->gState to Ready */ - huart->gState = HAL_UART_STATE_READY; - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receive an amount of data in blocking mode. - * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), - * the received data is handled as a set of u16. In this case, Size must indicate the number - * of u16 available through pData. - * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO - * is not empty. Read operations from the RDR register are performed when - * RXFNE flag is set. From hardware perspective, RXFNE flag and - * RXNE are mapped on the same bit-field. - * @param huart UART handle. - * @param pData Pointer to data buffer (u8 or u16 data elements). - * @param Size Amount of data elements (u8 or u16) to be received. - * @param Timeout Timeout duration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ - uint8_t *pdata8bits; - uint16_t *pdata16bits; - uint16_t uhMask; - uint32_t tickstart; - - /* Check that a Rx process is not already ongoing */ - if (huart->RxState == HAL_UART_STATE_READY) - { - if ((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - __HAL_LOCK(huart); - - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->RxState = HAL_UART_STATE_BUSY_RX; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* Init tickstart for timeout management */ - tickstart = HAL_GetTick(); - - huart->RxXferSize = Size; - huart->RxXferCount = Size; - - /* Computation of UART mask to apply to RDR register */ - UART_MASK_COMPUTATION(huart); - uhMask = huart->Mask; - - /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - pdata8bits = NULL; - pdata16bits = (uint16_t *) pData; - } - else - { - pdata8bits = pData; - pdata16bits = NULL; - } - - __HAL_UNLOCK(huart); - - /* as long as data have to be received */ - while (huart->RxXferCount > 0U) - { - if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) - { - return HAL_TIMEOUT; - } - if (pdata8bits == NULL) - { - *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask); - pdata16bits++; - } - else - { - *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); - pdata8bits++; - } - huart->RxXferCount--; - } - - /* At end of Rx process, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Send an amount of data in interrupt mode. - * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), - * the sent data is handled as a set of u16. In this case, Size must indicate the number - * of u16 provided through pData. - * @param huart UART handle. - * @param pData Pointer to data buffer (u8 or u16 data elements). - * @param Size Amount of data elements (u8 or u16) to be sent. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) -{ - /* Check that a Tx process is not already ongoing */ - if (huart->gState == HAL_UART_STATE_READY) - { - if ((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - __HAL_LOCK(huart); - - huart->pTxBuffPtr = pData; - huart->TxXferSize = Size; - huart->TxXferCount = Size; - huart->TxISR = NULL; - - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->gState = HAL_UART_STATE_BUSY_TX; - -#if defined(USART_CR1_FIFOEN) - /* Configure Tx interrupt processing */ - if (huart->FifoMode == UART_FIFOMODE_ENABLE) - { - /* Set the Tx ISR function pointer according to the data word length */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - huart->TxISR = UART_TxISR_16BIT_FIFOEN; - } - else - { - huart->TxISR = UART_TxISR_8BIT_FIFOEN; - } - - __HAL_UNLOCK(huart); - - /* Enable the TX FIFO threshold interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); - } - else - { - /* Set the Tx ISR function pointer according to the data word length */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - huart->TxISR = UART_TxISR_16BIT; - } - else - { - huart->TxISR = UART_TxISR_8BIT; - } - - __HAL_UNLOCK(huart); - - /* Enable the Transmit Data Register Empty interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); - } -#else - /* Set the Tx ISR function pointer according to the data word length */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - huart->TxISR = UART_TxISR_16BIT; - } - else - { - huart->TxISR = UART_TxISR_8BIT; - } - - __HAL_UNLOCK(huart); - - /* Enable the Transmit Data Register Empty interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE); -#endif /* USART_CR1_FIFOEN */ - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receive an amount of data in interrupt mode. - * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), - * the received data is handled as a set of u16. In this case, Size must indicate the number - * of u16 available through pData. - * @param huart UART handle. - * @param pData Pointer to data buffer (u8 or u16 data elements). - * @param Size Amount of data elements (u8 or u16) to be received. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) -{ - /* Check that a Rx process is not already ongoing */ - if (huart->RxState == HAL_UART_STATE_READY) - { - if ((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - __HAL_LOCK(huart); - - /* Set Reception type to Standard reception */ - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - if (!(IS_LPUART_INSTANCE(huart->Instance))) - { - /* Check that USART RTOEN bit is set */ - if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) - { - /* Enable the UART Receiver Timeout Interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE); - } - } - - return (UART_Start_Receive_IT(huart, pData, Size)); - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Send an amount of data in DMA mode. - * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), - * the sent data is handled as a set of u16. In this case, Size must indicate the number - * of u16 provided through pData. - * @param huart UART handle. - * @param pData Pointer to data buffer (u8 or u16 data elements). - * @param Size Amount of data elements (u8 or u16) to be sent. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) -{ - /* Check that a Tx process is not already ongoing */ - if (huart->gState == HAL_UART_STATE_READY) - { - if ((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - __HAL_LOCK(huart); - - huart->pTxBuffPtr = pData; - huart->TxXferSize = Size; - huart->TxXferCount = Size; - - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->gState = HAL_UART_STATE_BUSY_TX; - - if (huart->hdmatx != NULL) - { - /* Set the UART DMA transfer complete callback */ - huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt; - - /* Set the UART DMA Half transfer complete callback */ - huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt; - - /* Set the DMA error callback */ - huart->hdmatx->XferErrorCallback = UART_DMAError; - - /* Set the DMA abort callback */ - huart->hdmatx->XferAbortCallback = NULL; - - /* Enable the UART transmit DMA channel */ - if (HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size) != HAL_OK) - { - /* Set error code to DMA */ - huart->ErrorCode = HAL_UART_ERROR_DMA; - - __HAL_UNLOCK(huart); - - /* Restore huart->gState to ready */ - huart->gState = HAL_UART_STATE_READY; - - return HAL_ERROR; - } - } - /* Clear the TC flag in the ICR register */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF); - - __HAL_UNLOCK(huart); - - /* Enable the DMA transfer for transmit request by setting the DMAT bit - in the UART CR3 register */ - ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receive an amount of data in DMA mode. - * @note When the UART parity is enabled (PCE = 1), the received data contain - * the parity bit (MSB position). - * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), - * the received data is handled as a set of u16. In this case, Size must indicate the number - * of u16 available through pData. - * @param huart UART handle. - * @param pData Pointer to data buffer (u8 or u16 data elements). - * @param Size Amount of data elements (u8 or u16) to be received. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) -{ - /* Check that a Rx process is not already ongoing */ - if (huart->RxState == HAL_UART_STATE_READY) - { - if ((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - __HAL_LOCK(huart); - - /* Set Reception type to Standard reception */ - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - if (!(IS_LPUART_INSTANCE(huart->Instance))) - { - /* Check that USART RTOEN bit is set */ - if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) - { - /* Enable the UART Receiver Timeout Interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE); - } - } - - return (UART_Start_Receive_DMA(huart, pData, Size)); - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Pause the DMA Transfer. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) -{ - const HAL_UART_StateTypeDef gstate = huart->gState; - const HAL_UART_StateTypeDef rxstate = huart->RxState; - - __HAL_LOCK(huart); - - if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && - (gstate == HAL_UART_STATE_BUSY_TX)) - { - /* Disable the UART DMA Tx request */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); - } - if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && - (rxstate == HAL_UART_STATE_BUSY_RX)) - { - /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); - - /* Disable the UART DMA Rx request */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); - } - - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @brief Resume the DMA Transfer. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) -{ - __HAL_LOCK(huart); - - if (huart->gState == HAL_UART_STATE_BUSY_TX) - { - /* Enable the UART DMA Tx request */ - ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); - } - if (huart->RxState == HAL_UART_STATE_BUSY_RX) - { - /* Clear the Overrun flag before resuming the Rx transfer */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); - - /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */ - if (huart->Init.Parity != UART_PARITY_NONE) - { - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); - } - ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); - - /* Enable the UART DMA Rx request */ - ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); - } - - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @brief Stop the DMA Transfer. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) -{ - /* The Lock is not implemented on this API to allow the user application - to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() / - HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback: - indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete - interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of - the stream and the corresponding call back is executed. */ - - const HAL_UART_StateTypeDef gstate = huart->gState; - const HAL_UART_StateTypeDef rxstate = huart->RxState; - - /* Stop UART DMA Tx request if ongoing */ - if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && - (gstate == HAL_UART_STATE_BUSY_TX)) - { - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); - - /* Abort the UART DMA Tx channel */ - if (huart->hdmatx != NULL) - { - if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) - { - if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) - { - /* Set error code to DMA */ - huart->ErrorCode = HAL_UART_ERROR_DMA; - - return HAL_TIMEOUT; - } - } - } - - UART_EndTxTransfer(huart); - } - - /* Stop UART DMA Rx request if ongoing */ - if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && - (rxstate == HAL_UART_STATE_BUSY_RX)) - { - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); - - /* Abort the UART DMA Rx channel */ - if (huart->hdmarx != NULL) - { - if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) - { - if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) - { - /* Set error code to DMA */ - huart->ErrorCode = HAL_UART_ERROR_DMA; - - return HAL_TIMEOUT; - } - } - } - - UART_EndRxTransfer(huart); - } - - return HAL_OK; -} - -/** - * @brief Abort ongoing transfers (blocking mode). - * @param huart UART handle. - * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. - * This procedure performs following operations : - * - Disable UART Interrupts (Tx and Rx) - * - Disable the DMA transfer in the peripheral register (if enabled) - * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) - * - Set handle State to READY - * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart) -{ -#if defined(USART_CR1_FIFOEN) - /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | - USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE); -#else - /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); -#endif /* USART_CR1_FIFOEN */ - - /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); - } - - /* Abort the UART DMA Tx channel if enabled */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) - { - /* Disable the UART DMA Tx request if enabled */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); - - /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ - if (huart->hdmatx != NULL) - { - /* Set the UART DMA Abort callback to Null. - No call back execution at end of DMA abort procedure */ - huart->hdmatx->XferAbortCallback = NULL; - - if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) - { - if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) - { - /* Set error code to DMA */ - huart->ErrorCode = HAL_UART_ERROR_DMA; - - return HAL_TIMEOUT; - } - } - } - } - - /* Abort the UART DMA Rx channel if enabled */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) - { - /* Disable the UART DMA Rx request if enabled */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); - - /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ - if (huart->hdmarx != NULL) - { - /* Set the UART DMA Abort callback to Null. - No call back execution at end of DMA abort procedure */ - huart->hdmarx->XferAbortCallback = NULL; - - if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) - { - if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) - { - /* Set error code to DMA */ - huart->ErrorCode = HAL_UART_ERROR_DMA; - - return HAL_TIMEOUT; - } - } - } - } - - /* Reset Tx and Rx transfer counters */ - huart->TxXferCount = 0U; - huart->RxXferCount = 0U; - - /* Clear the Error flags in the ICR register */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); - -#if defined(USART_CR1_FIFOEN) - /* Flush the whole TX FIFO (if needed) */ - if (huart->FifoMode == UART_FIFOMODE_ENABLE) - { - __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); - } -#endif /* USART_CR1_FIFOEN */ - - /* Discard the received data */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - - /* Restore huart->gState and huart->RxState to Ready */ - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - huart->ErrorCode = HAL_UART_ERROR_NONE; - - return HAL_OK; -} - -/** - * @brief Abort ongoing Transmit transfer (blocking mode). - * @param huart UART handle. - * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. - * This procedure performs following operations : - * - Disable UART Interrupts (Tx) - * - Disable the DMA transfer in the peripheral register (if enabled) - * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) - * - Set handle State to READY - * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart) -{ -#if defined(USART_CR1_FIFOEN) - /* Disable TCIE, TXEIE and TXFTIE interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); -#else - /* Disable TXEIE and TCIE interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); -#endif /* USART_CR1_FIFOEN */ - - /* Abort the UART DMA Tx channel if enabled */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) - { - /* Disable the UART DMA Tx request if enabled */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); - - /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ - if (huart->hdmatx != NULL) - { - /* Set the UART DMA Abort callback to Null. - No call back execution at end of DMA abort procedure */ - huart->hdmatx->XferAbortCallback = NULL; - - if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) - { - if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) - { - /* Set error code to DMA */ - huart->ErrorCode = HAL_UART_ERROR_DMA; - - return HAL_TIMEOUT; - } - } - } - } - - /* Reset Tx transfer counter */ - huart->TxXferCount = 0U; - -#if defined(USART_CR1_FIFOEN) - /* Flush the whole TX FIFO (if needed) */ - if (huart->FifoMode == UART_FIFOMODE_ENABLE) - { - __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); - } -#endif /* USART_CR1_FIFOEN */ - - /* Restore huart->gState to Ready */ - huart->gState = HAL_UART_STATE_READY; - - return HAL_OK; -} - -/** - * @brief Abort ongoing Receive transfer (blocking mode). - * @param huart UART handle. - * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. - * This procedure performs following operations : - * - Disable UART Interrupts (Rx) - * - Disable the DMA transfer in the peripheral register (if enabled) - * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) - * - Set handle State to READY - * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart) -{ -#if defined(USART_CR1_FIFOEN) - /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE); -#else - /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); -#endif /* USART_CR1_FIFOEN */ - - /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); - } - - /* Abort the UART DMA Rx channel if enabled */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) - { - /* Disable the UART DMA Rx request if enabled */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); - - /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ - if (huart->hdmarx != NULL) - { - /* Set the UART DMA Abort callback to Null. - No call back execution at end of DMA abort procedure */ - huart->hdmarx->XferAbortCallback = NULL; - - if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) - { - if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) - { - /* Set error code to DMA */ - huart->ErrorCode = HAL_UART_ERROR_DMA; - - return HAL_TIMEOUT; - } - } - } - } - - /* Reset Rx transfer counter */ - huart->RxXferCount = 0U; - - /* Clear the Error flags in the ICR register */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); - - /* Discard the received data */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - - /* Restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - return HAL_OK; -} - -/** - * @brief Abort ongoing transfers (Interrupt mode). - * @param huart UART handle. - * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. - * This procedure performs following operations : - * - Disable UART Interrupts (Tx and Rx) - * - Disable the DMA transfer in the peripheral register (if enabled) - * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) - * - Set handle State to READY - * - At abort completion, call user abort complete callback - * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be - * considered as completed only when user abort complete callback is executed (not when exiting function). - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) -{ - uint32_t abortcplt = 1U; - - /* Disable interrupts */ -#if defined(USART_CR1_FIFOEN) - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | - USART_CR1_TXEIE_TXFNFIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE)); -#else - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); -#endif /* USART_CR1_FIFOEN */ - - /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); - } - - /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised - before any call to DMA Abort functions */ - /* DMA Tx Handle is valid */ - if (huart->hdmatx != NULL) - { - /* Set DMA Abort Complete callback if UART DMA Tx request if enabled. - Otherwise, set it to NULL */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) - { - huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback; - } - else - { - huart->hdmatx->XferAbortCallback = NULL; - } - } - /* DMA Rx Handle is valid */ - if (huart->hdmarx != NULL) - { - /* Set DMA Abort Complete callback if UART DMA Rx request if enabled. - Otherwise, set it to NULL */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) - { - huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback; - } - else - { - huart->hdmarx->XferAbortCallback = NULL; - } - } - - /* Abort the UART DMA Tx channel if enabled */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) - { - /* Disable DMA Tx at UART level */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); - - /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ - if (huart->hdmatx != NULL) - { - /* UART Tx DMA Abort callback has already been initialised : - will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ - - /* Abort DMA TX */ - if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) - { - huart->hdmatx->XferAbortCallback = NULL; - } - else - { - abortcplt = 0U; - } - } - } - - /* Abort the UART DMA Rx channel if enabled */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) - { - /* Disable the UART DMA Rx request if enabled */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); - - /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ - if (huart->hdmarx != NULL) - { - /* UART Rx DMA Abort callback has already been initialised : - will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ - - /* Abort DMA RX */ - if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) - { - huart->hdmarx->XferAbortCallback = NULL; - abortcplt = 1U; - } - else - { - abortcplt = 0U; - } - } - } - - /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ - if (abortcplt == 1U) - { - /* Reset Tx and Rx transfer counters */ - huart->TxXferCount = 0U; - huart->RxXferCount = 0U; - - /* Clear ISR function pointers */ - huart->RxISR = NULL; - huart->TxISR = NULL; - - /* Reset errorCode */ - huart->ErrorCode = HAL_UART_ERROR_NONE; - - /* Clear the Error flags in the ICR register */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); - -#if defined(USART_CR1_FIFOEN) - /* Flush the whole TX FIFO (if needed) */ - if (huart->FifoMode == UART_FIFOMODE_ENABLE) - { - __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); - } -#endif /* USART_CR1_FIFOEN */ - - /* Discard the received data */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - - /* Restore huart->gState and huart->RxState to Ready */ - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* As no DMA to be aborted, call directly user Abort complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Abort complete callback */ - huart->AbortCpltCallback(huart); -#else - /* Call legacy weak Abort complete callback */ - HAL_UART_AbortCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - - return HAL_OK; -} - -/** - * @brief Abort ongoing Transmit transfer (Interrupt mode). - * @param huart UART handle. - * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. - * This procedure performs following operations : - * - Disable UART Interrupts (Tx) - * - Disable the DMA transfer in the peripheral register (if enabled) - * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) - * - Set handle State to READY - * - At abort completion, call user abort complete callback - * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be - * considered as completed only when user abort complete callback is executed (not when exiting function). - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart) -{ - /* Disable interrupts */ -#if defined(USART_CR1_FIFOEN) - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); -#else - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); -#endif /* USART_CR1_FIFOEN */ - - /* Abort the UART DMA Tx channel if enabled */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) - { - /* Disable the UART DMA Tx request if enabled */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); - - /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ - if (huart->hdmatx != NULL) - { - /* Set the UART DMA Abort callback : - will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ - huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback; - - /* Abort DMA TX */ - if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) - { - /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */ - huart->hdmatx->XferAbortCallback(huart->hdmatx); - } - } - else - { - /* Reset Tx transfer counter */ - huart->TxXferCount = 0U; - - /* Clear TxISR function pointers */ - huart->TxISR = NULL; - - /* Restore huart->gState to Ready */ - huart->gState = HAL_UART_STATE_READY; - - /* As no DMA to be aborted, call directly user Abort complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Abort Transmit Complete Callback */ - huart->AbortTransmitCpltCallback(huart); -#else - /* Call legacy weak Abort Transmit Complete Callback */ - HAL_UART_AbortTransmitCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - } - else - { - /* Reset Tx transfer counter */ - huart->TxXferCount = 0U; - - /* Clear TxISR function pointers */ - huart->TxISR = NULL; - -#if defined(USART_CR1_FIFOEN) - /* Flush the whole TX FIFO (if needed) */ - if (huart->FifoMode == UART_FIFOMODE_ENABLE) - { - __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); - } -#endif /* USART_CR1_FIFOEN */ - - /* Restore huart->gState to Ready */ - huart->gState = HAL_UART_STATE_READY; - - /* As no DMA to be aborted, call directly user Abort complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Abort Transmit Complete Callback */ - huart->AbortTransmitCpltCallback(huart); -#else - /* Call legacy weak Abort Transmit Complete Callback */ - HAL_UART_AbortTransmitCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - - return HAL_OK; -} - -/** - * @brief Abort ongoing Receive transfer (Interrupt mode). - * @param huart UART handle. - * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. - * This procedure performs following operations : - * - Disable UART Interrupts (Rx) - * - Disable the DMA transfer in the peripheral register (if enabled) - * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) - * - Set handle State to READY - * - At abort completion, call user abort complete callback - * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be - * considered as completed only when user abort complete callback is executed (not when exiting function). - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart) -{ - /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ -#if defined(USART_CR1_FIFOEN) - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); -#else - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); -#endif /* USART_CR1_FIFOEN */ - - /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); - } - - /* Abort the UART DMA Rx channel if enabled */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) - { - /* Disable the UART DMA Rx request if enabled */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); - - /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ - if (huart->hdmarx != NULL) - { - /* Set the UART DMA Abort callback : - will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ - huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback; - - /* Abort DMA RX */ - if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) - { - /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ - huart->hdmarx->XferAbortCallback(huart->hdmarx); - } - } - else - { - /* Reset Rx transfer counter */ - huart->RxXferCount = 0U; - - /* Clear RxISR function pointer */ - huart->pRxBuffPtr = NULL; - - /* Clear the Error flags in the ICR register */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); - - /* Discard the received data */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - - /* Restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* As no DMA to be aborted, call directly user Abort complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Abort Receive Complete Callback */ - huart->AbortReceiveCpltCallback(huart); -#else - /* Call legacy weak Abort Receive Complete Callback */ - HAL_UART_AbortReceiveCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - } - else - { - /* Reset Rx transfer counter */ - huart->RxXferCount = 0U; - - /* Clear RxISR function pointer */ - huart->pRxBuffPtr = NULL; - - /* Clear the Error flags in the ICR register */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); - - /* Restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* As no DMA to be aborted, call directly user Abort complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Abort Receive Complete Callback */ - huart->AbortReceiveCpltCallback(huart); -#else - /* Call legacy weak Abort Receive Complete Callback */ - HAL_UART_AbortReceiveCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - - return HAL_OK; -} - -/** - * @brief Handle UART interrupt request. - * @param huart UART handle. - * @retval None - */ -void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) -{ - uint32_t isrflags = READ_REG(huart->Instance->ISR); - uint32_t cr1its = READ_REG(huart->Instance->CR1); - uint32_t cr3its = READ_REG(huart->Instance->CR3); - - uint32_t errorflags; - uint32_t errorcode; - - /* If no error occurs */ - errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF)); - if (errorflags == 0U) - { - /* UART in mode Receiver ---------------------------------------------------*/ -#if defined(USART_CR1_FIFOEN) - if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) - && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) - || ((cr3its & USART_CR3_RXFTIE) != 0U))) -#else - if (((isrflags & USART_ISR_RXNE) != 0U) - && ((cr1its & USART_CR1_RXNEIE) != 0U)) -#endif /* USART_CR1_FIFOEN */ - { - if (huart->RxISR != NULL) - { - huart->RxISR(huart); - } - return; - } - } - - /* If some errors occur */ -#if defined(USART_CR1_FIFOEN) - if ((errorflags != 0U) - && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U) - || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U)))) -#else - if ((errorflags != 0U) - && (((cr3its & USART_CR3_EIE) != 0U) - || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U))) -#endif /* USART_CR1_FIFOEN */ - { - /* UART parity error interrupt occurred -------------------------------------*/ - if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); - - huart->ErrorCode |= HAL_UART_ERROR_PE; - } - - /* UART frame error interrupt occurred --------------------------------------*/ - if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); - - huart->ErrorCode |= HAL_UART_ERROR_FE; - } - - /* UART noise error interrupt occurred --------------------------------------*/ - if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); - - huart->ErrorCode |= HAL_UART_ERROR_NE; - } - - /* UART Over-Run interrupt occurred -----------------------------------------*/ -#if defined(USART_CR1_FIFOEN) - if (((isrflags & USART_ISR_ORE) != 0U) - && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) || - ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U))) -#else - if (((isrflags & USART_ISR_ORE) != 0U) - && (((cr1its & USART_CR1_RXNEIE) != 0U) || - ((cr3its & USART_CR3_EIE) != 0U))) -#endif /* USART_CR1_FIFOEN */ - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); - - huart->ErrorCode |= HAL_UART_ERROR_ORE; - } - - /* UART Receiver Timeout interrupt occurred ---------------------------------*/ - if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF); - - huart->ErrorCode |= HAL_UART_ERROR_RTO; - } - - /* Call UART Error Call back function if need be ----------------------------*/ - if (huart->ErrorCode != HAL_UART_ERROR_NONE) - { - /* UART in mode Receiver --------------------------------------------------*/ -#if defined(USART_CR1_FIFOEN) - if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) - && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) - || ((cr3its & USART_CR3_RXFTIE) != 0U))) -#else - if (((isrflags & USART_ISR_RXNE) != 0U) - && ((cr1its & USART_CR1_RXNEIE) != 0U)) -#endif /* USART_CR1_FIFOEN */ - { - if (huart->RxISR != NULL) - { - huart->RxISR(huart); - } - } - - /* If Error is to be considered as blocking : - - Receiver Timeout error in Reception - - Overrun error in Reception - - any error occurs in DMA mode reception - */ - errorcode = huart->ErrorCode; - if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) || - ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U)) - { - /* Blocking error : transfer is aborted - Set the UART state ready to be able to start again the process, - Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ - UART_EndRxTransfer(huart); - - /* Abort the UART DMA Rx channel if enabled */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) - { - /* Disable the UART DMA Rx request if enabled */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); - - /* Abort the UART DMA Rx channel */ - if (huart->hdmarx != NULL) - { - /* Set the UART DMA Abort callback : - will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */ - huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError; - - /* Abort DMA RX */ - if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) - { - /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ - huart->hdmarx->XferAbortCallback(huart->hdmarx); - } - } - else - { - /* Call user error callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered error callback*/ - huart->ErrorCallback(huart); -#else - /*Call legacy weak error callback*/ - HAL_UART_ErrorCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - - } - } - else - { - /* Call user error callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered error callback*/ - huart->ErrorCallback(huart); -#else - /*Call legacy weak error callback*/ - HAL_UART_ErrorCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - } - else - { - /* Non Blocking error : transfer could go on. - Error is notified to user through user error callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered error callback*/ - huart->ErrorCallback(huart); -#else - /*Call legacy weak error callback*/ - HAL_UART_ErrorCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - huart->ErrorCode = HAL_UART_ERROR_NONE; - } - } - return; - - } /* End if some error occurs */ - - /* Check current reception Mode : - If Reception till IDLE event has been selected : */ - if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - && ((isrflags & USART_ISR_IDLE) != 0U) - && ((cr1its & USART_ISR_IDLE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); - - /* Check if DMA mode is enabled in UART */ - if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) - { - /* DMA mode enabled */ - /* Check received length : If all expected data are received, do nothing, - (DMA cplt callback will be called). - Otherwise, if at least one data has already been received, IDLE event is to be notified to user */ - uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx); - if ((nb_remaining_rx_data > 0U) - && (nb_remaining_rx_data < huart->RxXferSize)) - { - /* Reception is not complete */ - huart->RxXferCount = nb_remaining_rx_data; - - /* In Normal mode, end DMA xfer and HAL UART Rx process*/ - if (HAL_IS_BIT_CLR(huart->hdmarx->Instance->CCR, DMA_CCR_CIRC)) - { - /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); - - /* Disable the DMA transfer for the receiver request by resetting the DMAR bit - in the UART CR3 register */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); - - /* At end of Rx process, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); - - /* Last bytes received, so no need as the abort is immediate */ - (void)HAL_DMA_Abort(huart->hdmarx); - } -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx Event callback*/ - huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); -#else - /*Call legacy weak Rx Event callback*/ - HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - return; - } - else - { - /* DMA mode not enabled */ - /* Check received length : If all expected data are received, do nothing. - Otherwise, if at least one data has already been received, IDLE event is to be notified to user */ - uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount; - if ((huart->RxXferCount > 0U) - && (nb_rx_data > 0U)) - { -#if defined(USART_CR1_FIFOEN) - /* Disable the UART Parity Error Interrupt and RXNE interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); - - /* Disable the UART Error Interrupt:(Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); -#else - /* Disable the UART Parity Error Interrupt and RXNE interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); - - /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); -#endif /* USART_CR1_FIFOEN */ - - /* Rx process is completed, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* Clear RxISR function pointer */ - huart->RxISR = NULL; - - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxEventCallback(huart, nb_rx_data); -#else - /*Call legacy weak Rx Event callback*/ - HAL_UARTEx_RxEventCallback(huart, nb_rx_data); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - return; - } - } - - /* UART wakeup from Stop mode interrupt occurred ---------------------------*/ - if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF); - - /* UART Rx state is not reset as a reception process might be ongoing. - If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */ - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Wakeup Callback */ - huart->WakeupCallback(huart); -#else - /* Call legacy weak Wakeup Callback */ - HAL_UARTEx_WakeupCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - return; - } - - /* UART in mode Transmitter ------------------------------------------------*/ -#if defined(USART_CR1_FIFOEN) - if (((isrflags & USART_ISR_TXE_TXFNF) != 0U) - && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U) - || ((cr3its & USART_CR3_TXFTIE) != 0U))) -#else - if (((isrflags & USART_ISR_TXE) != 0U) - && ((cr1its & USART_CR1_TXEIE) != 0U)) -#endif /* USART_CR1_FIFOEN */ - { - if (huart->TxISR != NULL) - { - huart->TxISR(huart); - } - return; - } - - /* UART in mode Transmitter (transmission end) -----------------------------*/ - if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U)) - { - UART_EndTransmit_IT(huart); - return; - } - -#if defined(USART_CR1_FIFOEN) - /* UART TX Fifo Empty occurred ----------------------------------------------*/ - if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U)) - { -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Tx Fifo Empty Callback */ - huart->TxFifoEmptyCallback(huart); -#else - /* Call legacy weak Tx Fifo Empty Callback */ - HAL_UARTEx_TxFifoEmptyCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - return; - } - - /* UART RX Fifo Full occurred ----------------------------------------------*/ - if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U)) - { -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Rx Fifo Full Callback */ - huart->RxFifoFullCallback(huart); -#else - /* Call legacy weak Rx Fifo Full Callback */ - HAL_UARTEx_RxFifoFullCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - return; - } -#endif /* USART_CR1_FIFOEN */ -} - -/** - * @brief Tx Transfer completed callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_TxCpltCallback can be implemented in the user file. - */ -} - -/** - * @brief Tx Half Transfer completed callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE: This function should not be modified, when the callback is needed, - the HAL_UART_TxHalfCpltCallback can be implemented in the user file. - */ -} - -/** - * @brief Rx Transfer completed callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_RxCpltCallback can be implemented in the user file. - */ -} - -/** - * @brief Rx Half Transfer completed callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE: This function should not be modified, when the callback is needed, - the HAL_UART_RxHalfCpltCallback can be implemented in the user file. - */ -} - -/** - * @brief UART error callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_ErrorCallback can be implemented in the user file. - */ -} - -/** - * @brief UART Abort Complete callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_AbortCpltCallback can be implemented in the user file. - */ -} - -/** - * @brief UART Abort Complete callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file. - */ -} - -/** - * @brief UART Abort Receive Complete callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file. - */ -} - -/** - * @brief Reception Event Callback (Rx event notification called after use of advanced reception service). - * @param huart UART handle - * @param Size Number of data available in application reception buffer (indicates a position in - * reception buffer until which, data are available) - * @retval None - */ -__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - UNUSED(Size); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UARTEx_RxEventCallback can be implemented in the user file. - */ -} - -/** - * @} - */ - -/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions - * @brief UART control functions - * -@verbatim - =============================================================================== - ##### Peripheral Control functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to control the UART. - (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly - (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature - (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature - (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode - (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode - (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode - (+) UART_SetConfig() API configures the UART peripheral - (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features - (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization - (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter - (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver - (+) HAL_LIN_SendBreak() API transmits the break characters -@endverbatim - * @{ - */ - -/** - * @brief Update on the fly the receiver timeout value in RTOR register. - * @param huart Pointer to a UART_HandleTypeDef structure that contains - * the configuration information for the specified UART module. - * @param TimeoutValue receiver timeout value in number of baud blocks. The timeout - * value must be less or equal to 0x0FFFFFFFF. - * @retval None - */ -void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue) -{ - if (!(IS_LPUART_INSTANCE(huart->Instance))) - { - assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue)); - MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue); - } -} - -/** - * @brief Enable the UART receiver timeout feature. - * @param huart Pointer to a UART_HandleTypeDef structure that contains - * the configuration information for the specified UART module. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart) -{ - if (!(IS_LPUART_INSTANCE(huart->Instance))) - { - if (huart->gState == HAL_UART_STATE_READY) - { - /* Process Locked */ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Set the USART RTOEN bit */ - SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN); - - huart->gState = HAL_UART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Disable the UART receiver timeout feature. - * @param huart Pointer to a UART_HandleTypeDef structure that contains - * the configuration information for the specified UART module. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart) -{ - if (!(IS_LPUART_INSTANCE(huart->Instance))) - { - if (huart->gState == HAL_UART_STATE_READY) - { - /* Process Locked */ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Clear the USART RTOEN bit */ - CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN); - - huart->gState = HAL_UART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Enable UART in mute mode (does not mean UART enters mute mode; - * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called). - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart) -{ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Enable USART mute mode by setting the MME bit in the CR1 register */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_MME); - - huart->gState = HAL_UART_STATE_READY; - - return (UART_CheckIdleState(huart)); -} - -/** - * @brief Disable UART mute mode (does not mean the UART actually exits mute mode - * as it may not have been in mute mode at this very moment). - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart) -{ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Disable USART mute mode by clearing the MME bit in the CR1 register */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME); - - huart->gState = HAL_UART_STATE_READY; - - return (UART_CheckIdleState(huart)); -} - -/** - * @brief Enter UART mute mode (means UART actually enters mute mode). - * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called. - * @param huart UART handle. - * @retval None - */ -void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart) -{ - __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST); -} - -/** - * @brief Enable the UART transmitter and disable the UART receiver. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) -{ - __HAL_LOCK(huart); - huart->gState = HAL_UART_STATE_BUSY; - - /* Clear TE and RE bits */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); - - /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TE); - - huart->gState = HAL_UART_STATE_READY; - - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @brief Enable the UART receiver and disable the UART transmitter. - * @param huart UART handle. - * @retval HAL status. - */ -HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) -{ - __HAL_LOCK(huart); - huart->gState = HAL_UART_STATE_BUSY; - - /* Clear TE and RE bits */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); - - /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RE); - - huart->gState = HAL_UART_STATE_READY; - - __HAL_UNLOCK(huart); - - return HAL_OK; -} - - -/** - * @brief Transmit break characters. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart) -{ - /* Check the parameters */ - assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); - - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Send break characters */ - __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST); - - huart->gState = HAL_UART_STATE_READY; - - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @} - */ - -/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions - * @brief UART Peripheral State functions - * -@verbatim - ============================================================================== - ##### Peripheral State and Error functions ##### - ============================================================================== - [..] - This subsection provides functions allowing to : - (+) Return the UART handle state. - (+) Return the UART handle error code - -@endverbatim - * @{ - */ - -/** - * @brief Return the UART handle state. - * @param huart Pointer to a UART_HandleTypeDef structure that contains - * the configuration information for the specified UART. - * @retval HAL state - */ -HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart) -{ - uint32_t temp1; - uint32_t temp2; - temp1 = huart->gState; - temp2 = huart->RxState; - - return (HAL_UART_StateTypeDef)(temp1 | temp2); -} - -/** - * @brief Return the UART handle error code. - * @param huart Pointer to a UART_HandleTypeDef structure that contains - * the configuration information for the specified UART. - * @retval UART Error Code - */ -uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart) -{ - return huart->ErrorCode; -} -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup UART_Private_Functions UART Private Functions - * @{ - */ - -/** - * @brief Initialize the callbacks to their default values. - * @param huart UART handle. - * @retval none - */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) -void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart) -{ - /* Init the UART Callback settings */ - huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ - huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */ - huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ - huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */ - huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */ - huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ - huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */ - huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */ - huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */ -#if defined(USART_CR1_FIFOEN) - huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ - huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ -#endif /* USART_CR1_FIFOEN */ - huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */ - -} -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - -/** - * @brief Configure the UART peripheral. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) -{ - uint32_t tmpreg; - uint16_t brrtemp; - UART_ClockSourceTypeDef clocksource; - uint32_t usartdiv; - HAL_StatusTypeDef ret = HAL_OK; -#if defined(USART_PRESC_PRESCALER) - uint32_t lpuart_ker_ck_pres; -#endif /* USART_PRESC_PRESCALER */ - uint32_t pclk; - - /* Check the parameters */ - assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); - assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); - if (UART_INSTANCE_LOWPOWER(huart)) - { - assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits)); - } - else - { - assert_param(IS_UART_STOPBITS(huart->Init.StopBits)); - assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling)); - } - - assert_param(IS_UART_PARITY(huart->Init.Parity)); - assert_param(IS_UART_MODE(huart->Init.Mode)); - assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); - assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); -#if defined(USART_PRESC_PRESCALER) - assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler)); -#endif /* USART_PRESC_PRESCALER */ - - /*-------------------------- USART CR1 Configuration -----------------------*/ - /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure - * the UART Word Length, Parity, Mode and oversampling: - * set the M bits according to huart->Init.WordLength value - * set PCE and PS bits according to huart->Init.Parity value - * set TE and RE bits according to huart->Init.Mode value - * set OVER8 bit according to huart->Init.OverSampling value */ - tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ; - MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg); - - /*-------------------------- USART CR2 Configuration -----------------------*/ - /* Configure the UART Stop Bits: Set STOP[13:12] bits according - * to huart->Init.StopBits value */ - MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits); - - /*-------------------------- USART CR3 Configuration -----------------------*/ - /* Configure - * - UART HardWare Flow Control: set CTSE and RTSE bits according - * to huart->Init.HwFlowCtl value - * - one-bit sampling method versus three samples' majority rule according - * to huart->Init.OneBitSampling (not applicable to LPUART) */ - tmpreg = (uint32_t)huart->Init.HwFlowCtl; - - if (!(UART_INSTANCE_LOWPOWER(huart))) - { - tmpreg |= huart->Init.OneBitSampling; - } - MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg); - -#if defined(USART_PRESC_PRESCALER) - /*-------------------------- USART PRESC Configuration -----------------------*/ - /* Configure - * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */ - MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler); -#endif /* USART_PRESC_PRESCALER */ - - /*-------------------------- USART BRR Configuration -----------------------*/ - UART_GETCLOCKSOURCE(huart, clocksource); - - /* Check LPUART instance */ - if (UART_INSTANCE_LOWPOWER(huart)) - { - /* Retrieve frequency clock */ - switch (clocksource) - { - case UART_CLOCKSOURCE_PCLK1: - pclk = HAL_RCC_GetPCLK1Freq(); - break; - case UART_CLOCKSOURCE_HSI: - pclk = (uint32_t) HSI_VALUE; - break; - case UART_CLOCKSOURCE_SYSCLK: - pclk = HAL_RCC_GetSysClockFreq(); - break; - case UART_CLOCKSOURCE_LSE: - pclk = (uint32_t) LSE_VALUE; - break; - default: - pclk = 0U; - ret = HAL_ERROR; - break; - } - - /* If proper clock source reported */ - if (pclk != 0U) - { -#if defined(USART_PRESC_PRESCALER) - /* Compute clock after Prescaler */ - lpuart_ker_ck_pres = (pclk / UARTPrescTable[huart->Init.ClockPrescaler]); - - /* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */ - if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) || - (lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate))) - { - ret = HAL_ERROR; - } - else - { - /* Check computed UsartDiv value is in allocated range - (it is forbidden to write values lower than 0x300 in the LPUART_BRR register) */ - usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); - if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX)) - { - huart->Instance->BRR = usartdiv; - } - else - { - ret = HAL_ERROR; - } - } /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) || - (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */ -#else - /* No Prescaler applicable */ - /* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */ - if ((pclk < (3U * huart->Init.BaudRate)) || - (pclk > (4096U * huart->Init.BaudRate))) - { - ret = HAL_ERROR; - } - else - { - usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate)); - if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX)) - { - huart->Instance->BRR = usartdiv; - } - else - { - ret = HAL_ERROR; - } - } /* if ( (pclk < (3 * huart->Init.BaudRate) ) || (pclk > (4096 * huart->Init.BaudRate) )) */ -#endif /* USART_PRESC_PRESCALER */ - } /* if (pclk != 0) */ - } - /* Check UART Over Sampling to set Baud Rate Register */ - else if (huart->Init.OverSampling == UART_OVERSAMPLING_8) - { - switch (clocksource) - { - case UART_CLOCKSOURCE_PCLK1: - pclk = HAL_RCC_GetPCLK1Freq(); - break; - case UART_CLOCKSOURCE_PCLK2: - pclk = HAL_RCC_GetPCLK2Freq(); - break; - case UART_CLOCKSOURCE_HSI: - pclk = (uint32_t) HSI_VALUE; - break; - case UART_CLOCKSOURCE_SYSCLK: - pclk = HAL_RCC_GetSysClockFreq(); - break; - case UART_CLOCKSOURCE_LSE: - pclk = (uint32_t) LSE_VALUE; - break; - default: - pclk = 0U; - ret = HAL_ERROR; - break; - } - - /* USARTDIV must be greater than or equal to 0d16 */ - if (pclk != 0U) - { -#if defined(USART_PRESC_PRESCALER) - usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); -#else - usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate)); -#endif /* USART_PRESC_PRESCALER */ - if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX)) - { - brrtemp = (uint16_t)(usartdiv & 0xFFF0U); - brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); - huart->Instance->BRR = brrtemp; - } - else - { - ret = HAL_ERROR; - } - } - } - else - { - switch (clocksource) - { - case UART_CLOCKSOURCE_PCLK1: - pclk = HAL_RCC_GetPCLK1Freq(); - break; - case UART_CLOCKSOURCE_PCLK2: - pclk = HAL_RCC_GetPCLK2Freq(); - break; - case UART_CLOCKSOURCE_HSI: - pclk = (uint32_t) HSI_VALUE; - break; - case UART_CLOCKSOURCE_SYSCLK: - pclk = HAL_RCC_GetSysClockFreq(); - break; - case UART_CLOCKSOURCE_LSE: - pclk = (uint32_t) LSE_VALUE; - break; - default: - pclk = 0U; - ret = HAL_ERROR; - break; - } - - if (pclk != 0U) - { - /* USARTDIV must be greater than or equal to 0d16 */ -#if defined(USART_PRESC_PRESCALER) - usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); -#else - usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate)); -#endif /* USART_PRESC_PRESCALER */ - if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX)) - { - huart->Instance->BRR = (uint16_t)usartdiv; - } - else - { - ret = HAL_ERROR; - } - } - } - -#if defined(USART_CR1_FIFOEN) - /* Initialize the number of data to process during RX/TX ISR execution */ - huart->NbTxDataToProcess = 1; - huart->NbRxDataToProcess = 1; -#endif /* USART_CR1_FIFOEN */ - - /* Clear ISR function pointers */ - huart->RxISR = NULL; - huart->TxISR = NULL; - - return ret; -} - -/** - * @brief Configure the UART peripheral advanced features. - * @param huart UART handle. - * @retval None - */ -void UART_AdvFeatureConfig(UART_HandleTypeDef *huart) -{ - /* Check whether the set of advanced features to configure is properly set */ - assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit)); - - /* if required, configure TX pin active level inversion */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT)) - { - assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert); - } - - /* if required, configure RX pin active level inversion */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT)) - { - assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert); - } - - /* if required, configure data inversion */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT)) - { - assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert); - } - - /* if required, configure RX/TX pins swap */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT)) - { - assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap); - } - - /* if required, configure RX overrun detection disabling */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT)) - { - assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable)); - MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable); - } - - /* if required, configure DMA disabling on reception error */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT)) - { - assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError)); - MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError); - } - - /* if required, configure auto Baud rate detection scheme */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) - { - assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance)); - assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable); - /* set auto Baudrate detection parameters if detection is enabled */ - if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) - { - assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); - } - } - - /* if required, configure MSB first on communication line */ - if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT)) - { - assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst)); - MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst); - } -} - -/** - * @brief Check the UART Idle State. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) -{ - uint32_t tickstart; - - /* Initialize the UART ErrorCode */ - huart->ErrorCode = HAL_UART_ERROR_NONE; - - /* Init tickstart for timeout management */ - tickstart = HAL_GetTick(); - - /* Check if the Transmitter is enabled */ - if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) - { - /* Wait until TEACK flag is set */ - if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) - { - /* Timeout occurred */ - return HAL_TIMEOUT; - } - } - - /* Check if the Receiver is enabled */ - if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) - { - /* Wait until REACK flag is set */ - if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) - { - /* Timeout occurred */ - return HAL_TIMEOUT; - } - } - - /* Initialize the UART State */ - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @brief This function handles UART Communication Timeout. It waits - * until a flag is no longer in the specified status. - * @param huart UART handle. - * @param Flag Specifies the UART flag to check - * @param Status The actual Flag status (SET or RESET) - * @param Tickstart Tick start value - * @param Timeout Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, - uint32_t Tickstart, uint32_t Timeout) -{ - /* Wait until flag is set */ - while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status) - { - /* Check for the Timeout */ - if (Timeout != HAL_MAX_DELAY) - { - if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) - { - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) - interrupts for the interrupt process */ -#if defined(USART_CR1_FIFOEN) - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | - USART_CR1_TXEIE_TXFNFIE)); -#else - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); -#endif /* USART_CR1_FIFOEN */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); - - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - - __HAL_UNLOCK(huart); - - return HAL_TIMEOUT; - } - - if (READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U) - { - if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET) - { - /* Clear Receiver Timeout flag*/ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF); - - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) - interrupts for the interrupt process */ -#if defined(USART_CR1_FIFOEN) - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | - USART_CR1_TXEIE_TXFNFIE)); -#else - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); -#endif /* USART_CR1_FIFOEN */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); - - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - huart->ErrorCode = HAL_UART_ERROR_RTO; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_TIMEOUT; - } - } - } - } - return HAL_OK; -} - -/** - * @brief Start Receive operation in interrupt mode. - * @note This function could be called by all HAL UART API providing reception in Interrupt mode. - * @note When calling this function, parameters validity is considered as already checked, - * i.e. Rx State, buffer address, ... - * UART Handle is assumed as Locked. - * @param huart UART handle. - * @param pData Pointer to data buffer (u8 or u16 data elements). - * @param Size Amount of data elements (u8 or u16) to be received. - * @retval HAL status - */ -HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) -{ - huart->pRxBuffPtr = pData; - huart->RxXferSize = Size; - huart->RxXferCount = Size; - huart->RxISR = NULL; - - /* Computation of UART mask to apply to RDR register */ - UART_MASK_COMPUTATION(huart); - - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->RxState = HAL_UART_STATE_BUSY_RX; - - /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); - -#if defined(USART_CR1_FIFOEN) - /* Configure Rx interrupt processing */ - if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess)) - { - /* Set the Rx ISR function pointer according to the data word length */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - huart->RxISR = UART_RxISR_16BIT_FIFOEN; - } - else - { - huart->RxISR = UART_RxISR_8BIT_FIFOEN; - } - - __HAL_UNLOCK(huart); - - /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */ - if (huart->Init.Parity != UART_PARITY_NONE) - { - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); - } - ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); - } - else - { - /* Set the Rx ISR function pointer according to the data word length */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - huart->RxISR = UART_RxISR_16BIT; - } - else - { - huart->RxISR = UART_RxISR_8BIT; - } - - __HAL_UNLOCK(huart); - - /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */ - if (huart->Init.Parity != UART_PARITY_NONE) - { - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); - } - else - { - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); - } - } -#else - /* Set the Rx ISR function pointer according to the data word length */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - huart->RxISR = UART_RxISR_16BIT; - } - else - { - huart->RxISR = UART_RxISR_8BIT; - } - - __HAL_UNLOCK(huart); - - /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */ - if (huart->Init.Parity != UART_PARITY_NONE) - { - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); - } - else - { - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE); - } -#endif /* USART_CR1_FIFOEN */ - return HAL_OK; -} - -/** - * @brief Start Receive operation in DMA mode. - * @note This function could be called by all HAL UART API providing reception in DMA mode. - * @note When calling this function, parameters validity is considered as already checked, - * i.e. Rx State, buffer address, ... - * UART Handle is assumed as Locked. - * @param huart UART handle. - * @param pData Pointer to data buffer (u8 or u16 data elements). - * @param Size Amount of data elements (u8 or u16) to be received. - * @retval HAL status - */ -HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) -{ - huart->pRxBuffPtr = pData; - huart->RxXferSize = Size; - - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->RxState = HAL_UART_STATE_BUSY_RX; - - if (huart->hdmarx != NULL) - { - /* Set the UART DMA transfer complete callback */ - huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt; - - /* Set the UART DMA Half transfer complete callback */ - huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt; - - /* Set the DMA error callback */ - huart->hdmarx->XferErrorCallback = UART_DMAError; - - /* Set the DMA abort callback */ - huart->hdmarx->XferAbortCallback = NULL; - - /* Enable the DMA channel */ - if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK) - { - /* Set error code to DMA */ - huart->ErrorCode = HAL_UART_ERROR_DMA; - - __HAL_UNLOCK(huart); - - /* Restore huart->RxState to ready */ - huart->RxState = HAL_UART_STATE_READY; - - return HAL_ERROR; - } - } - __HAL_UNLOCK(huart); - - /* Enable the UART Parity Error Interrupt */ - if (huart->Init.Parity != UART_PARITY_NONE) - { - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); - } - - /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); - - /* Enable the DMA transfer for the receiver request by setting the DMAR bit - in the UART CR3 register */ - ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); - - return HAL_OK; -} - - -/** - * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion). - * @param huart UART handle. - * @retval None - */ -static void UART_EndTxTransfer(UART_HandleTypeDef *huart) -{ -#if defined(USART_CR1_FIFOEN) - /* Disable TXEIE, TCIE, TXFT interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE)); -#else - /* Disable TXEIE and TCIE interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); -#endif /* USART_CR1_FIFOEN */ - - /* At end of Tx process, restore huart->gState to Ready */ - huart->gState = HAL_UART_STATE_READY; -} - - -/** - * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). - * @param huart UART handle. - * @retval None - */ -static void UART_EndRxTransfer(UART_HandleTypeDef *huart) -{ - /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ -#if defined(USART_CR1_FIFOEN) - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); -#else - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); -#endif /* USART_CR1_FIFOEN */ - - /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); - } - - /* At end of Rx process, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* Reset RxIsr function pointer */ - huart->RxISR = NULL; -} - - -/** - * @brief DMA UART transmit process complete callback. - * @param hdma DMA handle. - * @retval None - */ -static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); - - /* DMA Normal mode */ - if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC)) - { - huart->TxXferCount = 0U; - - /* Disable the DMA transfer for transmit request by resetting the DMAT bit - in the UART CR3 register */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); - - /* Enable the UART Transmit Complete Interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); - } - /* DMA Circular mode */ - else - { -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Tx complete callback*/ - huart->TxCpltCallback(huart); -#else - /*Call legacy weak Tx complete callback*/ - HAL_UART_TxCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } -} - -/** - * @brief DMA UART transmit process half complete callback. - * @param hdma DMA handle. - * @retval None - */ -static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Tx Half complete callback*/ - huart->TxHalfCpltCallback(huart); -#else - /*Call legacy weak Tx Half complete callback*/ - HAL_UART_TxHalfCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ -} - -/** - * @brief DMA UART receive process complete callback. - * @param hdma DMA handle. - * @retval None - */ -static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); - - /* DMA Normal mode */ - if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC)) - { - huart->RxXferCount = 0U; - - /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); - - /* Disable the DMA transfer for the receiver request by resetting the DMAR bit - in the UART CR3 register */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); - - /* At end of Rx process, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - - /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); - } - } - - /* Check current reception Mode : - If Reception till IDLE event has been selected : use Rx Event callback */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx Event callback*/ - huart->RxEventCallback(huart, huart->RxXferSize); -#else - /*Call legacy weak Rx Event callback*/ - HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - else - { - /* In other cases : use Rx Complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxCpltCallback(huart); -#else - /*Call legacy weak Rx complete callback*/ - HAL_UART_RxCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } -} - -/** - * @brief DMA UART receive process half complete callback. - * @param hdma DMA handle. - * @retval None - */ -static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); - - /* Check current reception Mode : - If Reception till IDLE event has been selected : use Rx Event callback */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx Event callback*/ - huart->RxEventCallback(huart, huart->RxXferSize / 2U); -#else - /*Call legacy weak Rx Event callback*/ - HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - else - { - /* In other cases : use Rx Half Complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx Half complete callback*/ - huart->RxHalfCpltCallback(huart); -#else - /*Call legacy weak Rx Half complete callback*/ - HAL_UART_RxHalfCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } -} - -/** - * @brief DMA UART communication error callback. - * @param hdma DMA handle. - * @retval None - */ -static void UART_DMAError(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); - - const HAL_UART_StateTypeDef gstate = huart->gState; - const HAL_UART_StateTypeDef rxstate = huart->RxState; - - /* Stop UART DMA Tx request if ongoing */ - if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && - (gstate == HAL_UART_STATE_BUSY_TX)) - { - huart->TxXferCount = 0U; - UART_EndTxTransfer(huart); - } - - /* Stop UART DMA Rx request if ongoing */ - if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && - (rxstate == HAL_UART_STATE_BUSY_RX)) - { - huart->RxXferCount = 0U; - UART_EndRxTransfer(huart); - } - - huart->ErrorCode |= HAL_UART_ERROR_DMA; - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered error callback*/ - huart->ErrorCallback(huart); -#else - /*Call legacy weak error callback*/ - HAL_UART_ErrorCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ -} - -/** - * @brief DMA UART communication abort callback, when initiated by HAL services on Error - * (To be called at end of DMA Abort procedure following error occurrence). - * @param hdma DMA handle. - * @retval None - */ -static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); - huart->RxXferCount = 0U; - huart->TxXferCount = 0U; - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered error callback*/ - huart->ErrorCallback(huart); -#else - /*Call legacy weak error callback*/ - HAL_UART_ErrorCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ -} - -/** - * @brief DMA UART Tx communication abort callback, when initiated by user - * (To be called at end of DMA Tx Abort procedure following user abort request). - * @note When this callback is executed, User Abort complete call back is called only if no - * Abort still ongoing for Rx DMA Handle. - * @param hdma DMA handle. - * @retval None - */ -static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); - - huart->hdmatx->XferAbortCallback = NULL; - - /* Check if an Abort process is still ongoing */ - if (huart->hdmarx != NULL) - { - if (huart->hdmarx->XferAbortCallback != NULL) - { - return; - } - } - - /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ - huart->TxXferCount = 0U; - huart->RxXferCount = 0U; - - /* Reset errorCode */ - huart->ErrorCode = HAL_UART_ERROR_NONE; - - /* Clear the Error flags in the ICR register */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); - -#if defined(USART_CR1_FIFOEN) - /* Flush the whole TX FIFO (if needed) */ - if (huart->FifoMode == UART_FIFOMODE_ENABLE) - { - __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); - } -#endif /* USART_CR1_FIFOEN */ - - /* Restore huart->gState and huart->RxState to Ready */ - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* Call user Abort complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Abort complete callback */ - huart->AbortCpltCallback(huart); -#else - /* Call legacy weak Abort complete callback */ - HAL_UART_AbortCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ -} - - -/** - * @brief DMA UART Rx communication abort callback, when initiated by user - * (To be called at end of DMA Rx Abort procedure following user abort request). - * @note When this callback is executed, User Abort complete call back is called only if no - * Abort still ongoing for Tx DMA Handle. - * @param hdma DMA handle. - * @retval None - */ -static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); - - huart->hdmarx->XferAbortCallback = NULL; - - /* Check if an Abort process is still ongoing */ - if (huart->hdmatx != NULL) - { - if (huart->hdmatx->XferAbortCallback != NULL) - { - return; - } - } - - /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ - huart->TxXferCount = 0U; - huart->RxXferCount = 0U; - - /* Reset errorCode */ - huart->ErrorCode = HAL_UART_ERROR_NONE; - - /* Clear the Error flags in the ICR register */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); - - /* Discard the received data */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - - /* Restore huart->gState and huart->RxState to Ready */ - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* Call user Abort complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Abort complete callback */ - huart->AbortCpltCallback(huart); -#else - /* Call legacy weak Abort complete callback */ - HAL_UART_AbortCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ -} - - -/** - * @brief DMA UART Tx communication abort callback, when initiated by user by a call to - * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer) - * (This callback is executed at end of DMA Tx Abort procedure following user abort request, - * and leads to user Tx Abort Complete callback execution). - * @param hdma DMA handle. - * @retval None - */ -static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); - - huart->TxXferCount = 0U; - -#if defined(USART_CR1_FIFOEN) - /* Flush the whole TX FIFO (if needed) */ - if (huart->FifoMode == UART_FIFOMODE_ENABLE) - { - __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); - } -#endif /* USART_CR1_FIFOEN */ - - /* Restore huart->gState to Ready */ - huart->gState = HAL_UART_STATE_READY; - - /* Call user Abort complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Abort Transmit Complete Callback */ - huart->AbortTransmitCpltCallback(huart); -#else - /* Call legacy weak Abort Transmit Complete Callback */ - HAL_UART_AbortTransmitCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ -} - -/** - * @brief DMA UART Rx communication abort callback, when initiated by user by a call to - * HAL_UART_AbortReceive_IT API (Abort only Rx transfer) - * (This callback is executed at end of DMA Rx Abort procedure following user abort request, - * and leads to user Rx Abort Complete callback execution). - * @param hdma DMA handle. - * @retval None - */ -static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; - - huart->RxXferCount = 0U; - - /* Clear the Error flags in the ICR register */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); - - /* Discard the received data */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - - /* Restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* Call user Abort complete callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /* Call registered Abort Receive Complete Callback */ - huart->AbortReceiveCpltCallback(huart); -#else - /* Call legacy weak Abort Receive Complete Callback */ - HAL_UART_AbortReceiveCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ -} - -/** - * @brief TX interrupt handler for 7 or 8 bits data word length . - * @note Function is called under interruption only, once - * interruptions have been enabled by HAL_UART_Transmit_IT(). - * @param huart UART handle. - * @retval None - */ -static void UART_TxISR_8BIT(UART_HandleTypeDef *huart) -{ - /* Check that a Tx process is ongoing */ - if (huart->gState == HAL_UART_STATE_BUSY_TX) - { - if (huart->TxXferCount == 0U) - { - /* Disable the UART Transmit Data Register Empty Interrupt */ -#if defined(USART_CR1_FIFOEN) - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); -#else - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE); -#endif /* USART_CR1_FIFOEN */ - - /* Enable the UART Transmit Complete Interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); - } - else - { - huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF); - huart->pTxBuffPtr++; - huart->TxXferCount--; - } - } -} - -/** - * @brief TX interrupt handler for 9 bits data word length. - * @note Function is called under interruption only, once - * interruptions have been enabled by HAL_UART_Transmit_IT(). - * @param huart UART handle. - * @retval None - */ -static void UART_TxISR_16BIT(UART_HandleTypeDef *huart) -{ - const uint16_t *tmp; - - /* Check that a Tx process is ongoing */ - if (huart->gState == HAL_UART_STATE_BUSY_TX) - { - if (huart->TxXferCount == 0U) - { - /* Disable the UART Transmit Data Register Empty Interrupt */ -#if defined(USART_CR1_FIFOEN) - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); -#else - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE); -#endif /* USART_CR1_FIFOEN */ - - /* Enable the UART Transmit Complete Interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); - } - else - { - tmp = (const uint16_t *) huart->pTxBuffPtr; - huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL); - huart->pTxBuffPtr += 2U; - huart->TxXferCount--; - } - } -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief TX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled. - * @note Function is called under interruption only, once - * interruptions have been enabled by HAL_UART_Transmit_IT(). - * @param huart UART handle. - * @retval None - */ -static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) -{ - uint16_t nb_tx_data; - - /* Check that a Tx process is ongoing */ - if (huart->gState == HAL_UART_STATE_BUSY_TX) - { - for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--) - { - if (huart->TxXferCount == 0U) - { - /* Disable the TX FIFO threshold interrupt */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); - - /* Enable the UART Transmit Complete Interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); - - break; /* force exit loop */ - } - else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U) - { - huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF); - huart->pTxBuffPtr++; - huart->TxXferCount--; - } - else - { - /* Nothing to do */ - } - } - } -} - -/** - * @brief TX interrupt handler for 9 bits data word length and FIFO mode is enabled. - * @note Function is called under interruption only, once - * interruptions have been enabled by HAL_UART_Transmit_IT(). - * @param huart UART handle. - * @retval None - */ -static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) -{ - const uint16_t *tmp; - uint16_t nb_tx_data; - - /* Check that a Tx process is ongoing */ - if (huart->gState == HAL_UART_STATE_BUSY_TX) - { - for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--) - { - if (huart->TxXferCount == 0U) - { - /* Disable the TX FIFO threshold interrupt */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); - - /* Enable the UART Transmit Complete Interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); - - break; /* force exit loop */ - } - else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U) - { - tmp = (const uint16_t *) huart->pTxBuffPtr; - huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL); - huart->pTxBuffPtr += 2U; - huart->TxXferCount--; - } - else - { - /* Nothing to do */ - } - } - } -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @brief Wrap up transmission in non-blocking mode. - * @param huart pointer to a UART_HandleTypeDef structure that contains - * the configuration information for the specified UART module. - * @retval None - */ -static void UART_EndTransmit_IT(UART_HandleTypeDef *huart) -{ - /* Disable the UART Transmit Complete Interrupt */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE); - - /* Tx process is ended, restore huart->gState to Ready */ - huart->gState = HAL_UART_STATE_READY; - - /* Cleat TxISR function pointer */ - huart->TxISR = NULL; - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Tx complete callback*/ - huart->TxCpltCallback(huart); -#else - /*Call legacy weak Tx complete callback*/ - HAL_UART_TxCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ -} - -/** - * @brief RX interrupt handler for 7 or 8 bits data word length . - * @param huart UART handle. - * @retval None - */ -static void UART_RxISR_8BIT(UART_HandleTypeDef *huart) -{ - uint16_t uhMask = huart->Mask; - uint16_t uhdata; - - /* Check that a Rx process is ongoing */ - if (huart->RxState == HAL_UART_STATE_BUSY_RX) - { - uhdata = (uint16_t) READ_REG(huart->Instance->RDR); - *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask); - huart->pRxBuffPtr++; - huart->RxXferCount--; - - if (huart->RxXferCount == 0U) - { - /* Disable the UART Parity Error Interrupt and RXNE interrupts */ -#if defined(USART_CR1_FIFOEN) - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); -#else - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); -#endif /* USART_CR1_FIFOEN */ - - /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); - - /* Rx process is completed, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - - /* Clear RxISR function pointer */ - huart->RxISR = NULL; - - /* Check current reception Mode : - If Reception till IDLE event has been selected : */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - /* Set reception type to Standard */ - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* Disable IDLE interrupt */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); - - if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) - { - /* Clear IDLE Flag */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); - } -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx Event callback*/ - huart->RxEventCallback(huart, huart->RxXferSize); -#else - /*Call legacy weak Rx Event callback*/ - HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - else - { - /* Standard reception API called */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxCpltCallback(huart); -#else - /*Call legacy weak Rx complete callback*/ - HAL_UART_RxCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - } - } - else - { - /* Clear RXNE interrupt flag */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - } -} - -/** - * @brief RX interrupt handler for 9 bits data word length . - * @note Function is called under interruption only, once - * interruptions have been enabled by HAL_UART_Receive_IT() - * @param huart UART handle. - * @retval None - */ -static void UART_RxISR_16BIT(UART_HandleTypeDef *huart) -{ - uint16_t *tmp; - uint16_t uhMask = huart->Mask; - uint16_t uhdata; - - /* Check that a Rx process is ongoing */ - if (huart->RxState == HAL_UART_STATE_BUSY_RX) - { - uhdata = (uint16_t) READ_REG(huart->Instance->RDR); - tmp = (uint16_t *) huart->pRxBuffPtr ; - *tmp = (uint16_t)(uhdata & uhMask); - huart->pRxBuffPtr += 2U; - huart->RxXferCount--; - - if (huart->RxXferCount == 0U) - { - /* Disable the UART Parity Error Interrupt and RXNE interrupt*/ -#if defined(USART_CR1_FIFOEN) - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); -#else - ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); -#endif /* USART_CR1_FIFOEN */ - - /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); - - /* Rx process is completed, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - - /* Clear RxISR function pointer */ - huart->RxISR = NULL; - - /* Check current reception Mode : - If Reception till IDLE event has been selected : */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - /* Set reception type to Standard */ - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* Disable IDLE interrupt */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); - - if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) - { - /* Clear IDLE Flag */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); - } -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx Event callback*/ - huart->RxEventCallback(huart, huart->RxXferSize); -#else - /*Call legacy weak Rx Event callback*/ - HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - else - { - /* Standard reception API called */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxCpltCallback(huart); -#else - /*Call legacy weak Rx complete callback*/ - HAL_UART_RxCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - } - } - else - { - /* Clear RXNE interrupt flag */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - } -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief RX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled. - * @note Function is called under interruption only, once - * interruptions have been enabled by HAL_UART_Receive_IT() - * @param huart UART handle. - * @retval None - */ -static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) -{ - uint16_t uhMask = huart->Mask; - uint16_t uhdata; - uint16_t nb_rx_data; - uint16_t rxdatacount; - uint32_t isrflags = READ_REG(huart->Instance->ISR); - uint32_t cr1its = READ_REG(huart->Instance->CR1); - uint32_t cr3its = READ_REG(huart->Instance->CR3); - - /* Check that a Rx process is ongoing */ - if (huart->RxState == HAL_UART_STATE_BUSY_RX) - { - nb_rx_data = huart->NbRxDataToProcess; - while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U)) - { - uhdata = (uint16_t) READ_REG(huart->Instance->RDR); - *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask); - huart->pRxBuffPtr++; - huart->RxXferCount--; - isrflags = READ_REG(huart->Instance->ISR); - - /* If some non blocking errors occurred */ - if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U) - { - /* UART parity error interrupt occurred -------------------------------------*/ - if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); - - huart->ErrorCode |= HAL_UART_ERROR_PE; - } - - /* UART frame error interrupt occurred --------------------------------------*/ - if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); - - huart->ErrorCode |= HAL_UART_ERROR_FE; - } - - /* UART noise error interrupt occurred --------------------------------------*/ - if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); - - huart->ErrorCode |= HAL_UART_ERROR_NE; - } - - /* Call UART Error Call back function if need be ----------------------------*/ - if (huart->ErrorCode != HAL_UART_ERROR_NONE) - { - /* Non Blocking error : transfer could go on. - Error is notified to user through user error callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered error callback*/ - huart->ErrorCallback(huart); -#else - /*Call legacy weak error callback*/ - HAL_UART_ErrorCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - huart->ErrorCode = HAL_UART_ERROR_NONE; - } - } - - if (huart->RxXferCount == 0U) - { - /* Disable the UART Parity Error Interrupt and RXFT interrupt*/ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); - - /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) - and RX FIFO Threshold interrupt */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); - - /* Rx process is completed, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - - /* Clear RxISR function pointer */ - huart->RxISR = NULL; - - /* Check current reception Mode : - If Reception till IDLE event has been selected : */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - /* Set reception type to Standard */ - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* Disable IDLE interrupt */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); - - if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) - { - /* Clear IDLE Flag */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); - } -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx Event callback*/ - huart->RxEventCallback(huart, huart->RxXferSize); -#else - /*Call legacy weak Rx Event callback*/ - HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - else - { - /* Standard reception API called */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxCpltCallback(huart); -#else - /*Call legacy weak Rx complete callback*/ - HAL_UART_RxCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - } - } - - /* When remaining number of bytes to receive is less than the RX FIFO - threshold, next incoming frames are processed as if FIFO mode was - disabled (i.e. one interrupt per received frame). - */ - rxdatacount = huart->RxXferCount; - if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess)) - { - /* Disable the UART RXFT interrupt*/ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); - - /* Update the RxISR function pointer */ - huart->RxISR = UART_RxISR_8BIT; - - /* Enable the UART Data Register Not Empty interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); - } - } - else - { - /* Clear RXNE interrupt flag */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - } -} - -/** - * @brief RX interrupt handler for 9 bits data word length and FIFO mode is enabled. - * @note Function is called under interruption only, once - * interruptions have been enabled by HAL_UART_Receive_IT() - * @param huart UART handle. - * @retval None - */ -static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) -{ - uint16_t *tmp; - uint16_t uhMask = huart->Mask; - uint16_t uhdata; - uint16_t nb_rx_data; - uint16_t rxdatacount; - uint32_t isrflags = READ_REG(huart->Instance->ISR); - uint32_t cr1its = READ_REG(huart->Instance->CR1); - uint32_t cr3its = READ_REG(huart->Instance->CR3); - - /* Check that a Rx process is ongoing */ - if (huart->RxState == HAL_UART_STATE_BUSY_RX) - { - nb_rx_data = huart->NbRxDataToProcess; - while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U)) - { - uhdata = (uint16_t) READ_REG(huart->Instance->RDR); - tmp = (uint16_t *) huart->pRxBuffPtr ; - *tmp = (uint16_t)(uhdata & uhMask); - huart->pRxBuffPtr += 2U; - huart->RxXferCount--; - isrflags = READ_REG(huart->Instance->ISR); - - /* If some non blocking errors occurred */ - if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U) - { - /* UART parity error interrupt occurred -------------------------------------*/ - if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); - - huart->ErrorCode |= HAL_UART_ERROR_PE; - } - - /* UART frame error interrupt occurred --------------------------------------*/ - if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); - - huart->ErrorCode |= HAL_UART_ERROR_FE; - } - - /* UART noise error interrupt occurred --------------------------------------*/ - if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); - - huart->ErrorCode |= HAL_UART_ERROR_NE; - } - - /* Call UART Error Call back function if need be ----------------------------*/ - if (huart->ErrorCode != HAL_UART_ERROR_NONE) - { - /* Non Blocking error : transfer could go on. - Error is notified to user through user error callback */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered error callback*/ - huart->ErrorCallback(huart); -#else - /*Call legacy weak error callback*/ - HAL_UART_ErrorCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - huart->ErrorCode = HAL_UART_ERROR_NONE; - } - } - - if (huart->RxXferCount == 0U) - { - /* Disable the UART Parity Error Interrupt and RXFT interrupt*/ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); - - /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) - and RX FIFO Threshold interrupt */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); - - /* Rx process is completed, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - - /* Clear RxISR function pointer */ - huart->RxISR = NULL; - - /* Check current reception Mode : - If Reception till IDLE event has been selected : */ - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - /* Set reception type to Standard */ - huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; - - /* Disable IDLE interrupt */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); - - if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) - { - /* Clear IDLE Flag */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); - } -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx Event callback*/ - huart->RxEventCallback(huart, huart->RxXferSize); -#else - /*Call legacy weak Rx Event callback*/ - HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - else - { - /* Standard reception API called */ -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - /*Call registered Rx complete callback*/ - huart->RxCpltCallback(huart); -#else - /*Call legacy weak Rx complete callback*/ - HAL_UART_RxCpltCallback(huart); -#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ - } - } - } - - /* When remaining number of bytes to receive is less than the RX FIFO - threshold, next incoming frames are processed as if FIFO mode was - disabled (i.e. one interrupt per received frame). - */ - rxdatacount = huart->RxXferCount; - if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess)) - { - /* Disable the UART RXFT interrupt*/ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); - - /* Update the RxISR function pointer */ - huart->RxISR = UART_RxISR_16BIT; - - /* Enable the UART Data Register Not Empty interrupt */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); - } - } - else - { - /* Clear RXNE interrupt flag */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - } -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @} - */ - -#endif /* HAL_UART_MODULE_ENABLED */ -/** - * @} - */ - -/** - * @} - */ - diff --git a/Firmware/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c b/Firmware/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c deleted file mode 100644 index e509676..0000000 --- a/Firmware/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c +++ /dev/null @@ -1,1074 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l4xx_hal_uart_ex.c - * @author MCD Application Team - * @brief Extended UART HAL module driver. - * This file provides firmware functions to manage the following extended - * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). - * + Initialization and de-initialization functions - * + Peripheral Control functions - * - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - @verbatim - ============================================================================== - ##### UART peripheral extended features ##### - ============================================================================== - - (#) Declare a UART_HandleTypeDef handle structure. - - (#) For the UART RS485 Driver Enable mode, initialize the UART registers - by calling the HAL_RS485Ex_Init() API. - - (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming. - - -@- When UART operates in FIFO mode, FIFO mode must be enabled prior - starting RX/TX transfers. Also RX/TX FIFO thresholds must be - configured prior starting RX/TX transfers. - - @endverbatim - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l4xx_hal.h" - -/** @addtogroup STM32L4xx_HAL_Driver - * @{ - */ - -/** @defgroup UARTEx UARTEx - * @brief UART Extended HAL module driver - * @{ - */ - -#ifdef HAL_UART_MODULE_ENABLED - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#if defined(USART_CR1_FIFOEN) -/** @defgroup UARTEX_Private_Constants UARTEx Private Constants - * @{ - */ -/* UART RX FIFO depth */ -#define RX_FIFO_DEPTH 8U - -/* UART TX FIFO depth */ -#define TX_FIFO_DEPTH 8U -/** - * @} - */ -#endif /* USART_CR1_FIFOEN */ - -/* Private macros ------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/** @defgroup UARTEx_Private_Functions UARTEx Private Functions - * @{ - */ -static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection); -#if defined(USART_CR1_FIFOEN) -static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart); -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ - -/* Exported functions --------------------------------------------------------*/ - -/** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions - * @{ - */ - -/** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Extended Initialization and Configuration Functions - * -@verbatim -=============================================================================== - ##### Initialization and Configuration functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to initialize the USARTx or the UARTy - in asynchronous mode. - (+) For the asynchronous mode the parameters below can be configured: - (++) Baud Rate - (++) Word Length - (++) Stop Bit - (++) Parity: If the parity is enabled, then the MSB bit of the data written - in the data register is transmitted but is changed by the parity bit. - (++) Hardware flow control - (++) Receiver/transmitter modes - (++) Over Sampling Method - (++) One-Bit Sampling Method - (+) For the asynchronous mode, the following advanced features can be configured as well: - (++) TX and/or RX pin level inversion - (++) data logical level inversion - (++) RX and TX pins swap - (++) RX overrun detection disabling - (++) DMA disabling on RX error - (++) MSB first on communication line - (++) auto Baud rate detection - [..] - The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration - procedures (details for the procedures are available in reference manual). - -@endverbatim - - Depending on the frame length defined by the M1 and M0 bits (7-bit, - 8-bit or 9-bit), the possible UART formats are listed in the - following table. - - Table 1. UART frame format. - +-----------------------------------------------------------------------+ - | M1 bit | M0 bit | PCE bit | UART frame | - |---------|---------|-----------|---------------------------------------| - | 0 | 0 | 0 | | SB | 8 bit data | STB | | - |---------|---------|-----------|---------------------------------------| - | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | - |---------|---------|-----------|---------------------------------------| - | 0 | 1 | 0 | | SB | 9 bit data | STB | | - |---------|---------|-----------|---------------------------------------| - | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | - |---------|---------|-----------|---------------------------------------| - | 1 | 0 | 0 | | SB | 7 bit data | STB | | - |---------|---------|-----------|---------------------------------------| - | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | - +-----------------------------------------------------------------------+ - - * @{ - */ - -/** - * @brief Initialize the RS485 Driver enable feature according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle. - * @param huart UART handle. - * @param Polarity Select the driver enable polarity. - * This parameter can be one of the following values: - * @arg @ref UART_DE_POLARITY_HIGH DE signal is active high - * @arg @ref UART_DE_POLARITY_LOW DE signal is active low - * @param AssertionTime Driver Enable assertion time: - * 5-bit value defining the time between the activation of the DE (Driver Enable) - * signal and the beginning of the start bit. It is expressed in sample time - * units (1/8 or 1/16 bit time, depending on the oversampling rate) - * @param DeassertionTime Driver Enable deassertion time: - * 5-bit value defining the time between the end of the last stop bit, in a - * transmitted message, and the de-activation of the DE (Driver Enable) signal. - * It is expressed in sample time units (1/8 or 1/16 bit time, depending on the - * oversampling rate). - * @retval HAL status - */ -HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, - uint32_t DeassertionTime) -{ - uint32_t temp; - - /* Check the UART handle allocation */ - if (huart == NULL) - { - return HAL_ERROR; - } - /* Check the Driver Enable UART instance */ - assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance)); - - /* Check the Driver Enable polarity */ - assert_param(IS_UART_DE_POLARITY(Polarity)); - - /* Check the Driver Enable assertion time */ - assert_param(IS_UART_ASSERTIONTIME(AssertionTime)); - - /* Check the Driver Enable deassertion time */ - assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime)); - - if (huart->gState == HAL_UART_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - huart->Lock = HAL_UNLOCKED; - -#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) - UART_InitCallbacksToDefault(huart); - - if (huart->MspInitCallback == NULL) - { - huart->MspInitCallback = HAL_UART_MspInit; - } - - /* Init the low level hardware */ - huart->MspInitCallback(huart); -#else - /* Init the low level hardware : GPIO, CLOCK, CORTEX */ - HAL_UART_MspInit(huart); -#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ - } - - huart->gState = HAL_UART_STATE_BUSY; - - /* Disable the Peripheral */ - __HAL_UART_DISABLE(huart); - - /* Set the UART Communication parameters */ - if (UART_SetConfig(huart) == HAL_ERROR) - { - return HAL_ERROR; - } - - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) - { - UART_AdvFeatureConfig(huart); - } - - /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */ - SET_BIT(huart->Instance->CR3, USART_CR3_DEM); - - /* Set the Driver Enable polarity */ - MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity); - - /* Set the Driver Enable assertion and deassertion times */ - temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS); - temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS); - MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp); - - /* Enable the Peripheral */ - __HAL_UART_ENABLE(huart); - - /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ - return (UART_CheckIdleState(huart)); -} - -/** - * @} - */ - -/** @defgroup UARTEx_Exported_Functions_Group2 IO operation functions - * @brief Extended functions - * -@verbatim - =============================================================================== - ##### IO operation functions ##### - =============================================================================== - This subsection provides a set of Wakeup and FIFO mode related callback functions. - - (#) Wakeup from Stop mode Callback: - (+) HAL_UARTEx_WakeupCallback() - - (#) TX/RX Fifos Callbacks: - (+) HAL_UARTEx_RxFifoFullCallback() - (+) HAL_UARTEx_TxFifoEmptyCallback() - -@endverbatim - * @{ - */ - -/** - * @brief UART wakeup from Stop mode callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UARTEx_WakeupCallback can be implemented in the user file. - */ -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief UART RX Fifo full callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UARTEx_RxFifoFullCallback can be implemented in the user file. - */ -} - -/** - * @brief UART TX Fifo empty callback. - * @param huart UART handle. - * @retval None - */ -__weak void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(huart); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UARTEx_TxFifoEmptyCallback can be implemented in the user file. - */ -} -#endif /* USART_CR1_FIFOEN */ - -/** - * @} - */ - -/** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions - * @brief Extended Peripheral Control functions - * -@verbatim - =============================================================================== - ##### Peripheral Control functions ##### - =============================================================================== - [..] This section provides the following functions: - (+) HAL_UARTEx_EnableClockStopMode() API enables the UART clock (HSI or LSE only) during stop mode - (+) HAL_UARTEx_DisableClockStopMode() API disables the above functionality - (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address - detection length to more than 4 bits for multiprocessor address mark wake up. - (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode - trigger: address match, Start Bit detection or RXNE bit status. - (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode - (+) HAL_UARTEx_DisableStopMode() API disables the above functionality - (+) HAL_UARTEx_EnableFifoMode() API enables the FIFO mode - (+) HAL_UARTEx_DisableFifoMode() API disables the FIFO mode - (+) HAL_UARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold - (+) HAL_UARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold - - [..] This subsection also provides a set of additional functions providing enhanced reception - services to user. (For example, these functions allow application to handle use cases - where number of data to be received is unknown). - - (#) Compared to standard reception services which only consider number of received - data elements as reception completion criteria, these functions also consider additional events - as triggers for updating reception status to caller : - (+) Detection of inactivity period (RX line has not been active for a given period). - (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state) - for 1 frame time, after last received byte. - (++) RX inactivity detected by RTO, i.e. line has been in idle state - for a programmable time, after last received byte. - (+) Detection that a specific character has been received. - - (#) There are two mode of transfer: - (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received, - or till IDLE event occurs. Reception is handled only during function execution. - When function exits, no data reception could occur. HAL status and number of actually received data elements, - are returned by function after finishing transfer. - (+) Non-Blocking mode: The reception is performed using Interrupts or DMA. - These API's return the HAL status. - The end of the data processing will be indicated through the - dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode. - The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process - The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected. - - (#) Blocking mode API: - (+) HAL_UARTEx_ReceiveToIdle() - - (#) Non-Blocking mode API with Interrupt: - (+) HAL_UARTEx_ReceiveToIdle_IT() - - (#) Non-Blocking mode API with DMA: - (+) HAL_UARTEx_ReceiveToIdle_DMA() - -@endverbatim - * @{ - */ - -#if defined(USART_CR3_UCESM) -/** - * @brief Keep UART Clock enabled when in Stop Mode. - * @note When the USART clock source is configured to be LSE or HSI, it is possible to keep enabled - * this clock during STOP mode by setting the UCESM bit in USART_CR3 control register. - * @note When LPUART is used to wakeup from stop with LSE is selected as LPUART clock source, - * and desired baud rate is 9600 baud, the bit UCESM bit in LPUART_CR3 control register must be set. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart) -{ - /* Process Locked */ - __HAL_LOCK(huart); - - /* Set UCESM bit */ - ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_UCESM); - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @brief Disable UART Clock when in Stop Mode. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart) -{ - /* Process Locked */ - __HAL_LOCK(huart); - - /* Clear UCESM bit */ - ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_UCESM); - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -#endif /* USART_CR3_UCESM */ -/** - * @brief By default in multiprocessor mode, when the wake up method is set - * to address mark, the UART handles only 4-bit long addresses detection; - * this API allows to enable longer addresses detection (6-, 7- or 8-bit - * long). - * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode, - * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode. - * @param huart UART handle. - * @param AddressLength This parameter can be one of the following values: - * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address - * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address - * @retval HAL status - */ -HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength) -{ - /* Check the UART handle allocation */ - if (huart == NULL) - { - return HAL_ERROR; - } - - /* Check the address length parameter */ - assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength)); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Disable the Peripheral */ - __HAL_UART_DISABLE(huart); - - /* Set the address length */ - MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength); - - /* Enable the Peripheral */ - __HAL_UART_ENABLE(huart); - - /* TEACK and/or REACK to check before moving huart->gState to Ready */ - return (UART_CheckIdleState(huart)); -} - -/** - * @brief Set Wakeup from Stop mode interrupt flag selection. - * @note It is the application responsibility to enable the interrupt used as - * usart_wkup interrupt source before entering low-power mode. - * @param huart UART handle. - * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status. - * This parameter can be one of the following values: - * @arg @ref UART_WAKEUP_ON_ADDRESS - * @arg @ref UART_WAKEUP_ON_STARTBIT - * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) -{ - HAL_StatusTypeDef status = HAL_OK; - uint32_t tickstart; - - /* check the wake-up from stop mode UART instance */ - assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance)); - /* check the wake-up selection parameter */ - assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent)); - - /* Process Locked */ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Disable the Peripheral */ - __HAL_UART_DISABLE(huart); - - /* Set the wake-up selection scheme */ - MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent); - - if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS) - { - UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection); - } - - /* Enable the Peripheral */ - __HAL_UART_ENABLE(huart); - - /* Init tickstart for timeout management */ - tickstart = HAL_GetTick(); - - /* Wait until REACK flag is set */ - if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) - { - status = HAL_TIMEOUT; - } - else - { - /* Initialize the UART State */ - huart->gState = HAL_UART_STATE_READY; - } - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return status; -} - -/** - * @brief Enable UART Stop Mode. - * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart) -{ - /* Process Locked */ - __HAL_LOCK(huart); - - /* Set UESM bit */ - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_UESM); - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @brief Disable UART Stop Mode. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart) -{ - /* Process Locked */ - __HAL_LOCK(huart); - - /* Clear UESM bit */ - ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM); - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Enable the FIFO mode. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart) -{ - uint32_t tmpcr1; - - /* Check parameters */ - assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); - - /* Process Locked */ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Save actual UART configuration */ - tmpcr1 = READ_REG(huart->Instance->CR1); - - /* Disable UART */ - __HAL_UART_DISABLE(huart); - - /* Enable FIFO mode */ - SET_BIT(tmpcr1, USART_CR1_FIFOEN); - huart->FifoMode = UART_FIFOMODE_ENABLE; - - /* Restore UART configuration */ - WRITE_REG(huart->Instance->CR1, tmpcr1); - - /* Determine the number of data to process during RX/TX ISR execution */ - UARTEx_SetNbDataToProcess(huart); - - huart->gState = HAL_UART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @brief Disable the FIFO mode. - * @param huart UART handle. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart) -{ - uint32_t tmpcr1; - - /* Check parameters */ - assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); - - /* Process Locked */ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Save actual UART configuration */ - tmpcr1 = READ_REG(huart->Instance->CR1); - - /* Disable UART */ - __HAL_UART_DISABLE(huart); - - /* Enable FIFO mode */ - CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN); - huart->FifoMode = UART_FIFOMODE_DISABLE; - - /* Restore UART configuration */ - WRITE_REG(huart->Instance->CR1, tmpcr1); - - huart->gState = HAL_UART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @brief Set the TXFIFO threshold. - * @param huart UART handle. - * @param Threshold TX FIFO threshold value - * This parameter can be one of the following values: - * @arg @ref UART_TXFIFO_THRESHOLD_1_8 - * @arg @ref UART_TXFIFO_THRESHOLD_1_4 - * @arg @ref UART_TXFIFO_THRESHOLD_1_2 - * @arg @ref UART_TXFIFO_THRESHOLD_3_4 - * @arg @ref UART_TXFIFO_THRESHOLD_7_8 - * @arg @ref UART_TXFIFO_THRESHOLD_8_8 - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold) -{ - uint32_t tmpcr1; - - /* Check parameters */ - assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); - assert_param(IS_UART_TXFIFO_THRESHOLD(Threshold)); - - /* Process Locked */ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Save actual UART configuration */ - tmpcr1 = READ_REG(huart->Instance->CR1); - - /* Disable UART */ - __HAL_UART_DISABLE(huart); - - /* Update TX threshold configuration */ - MODIFY_REG(huart->Instance->CR3, USART_CR3_TXFTCFG, Threshold); - - /* Determine the number of data to process during RX/TX ISR execution */ - UARTEx_SetNbDataToProcess(huart); - - /* Restore UART configuration */ - WRITE_REG(huart->Instance->CR1, tmpcr1); - - huart->gState = HAL_UART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -/** - * @brief Set the RXFIFO threshold. - * @param huart UART handle. - * @param Threshold RX FIFO threshold value - * This parameter can be one of the following values: - * @arg @ref UART_RXFIFO_THRESHOLD_1_8 - * @arg @ref UART_RXFIFO_THRESHOLD_1_4 - * @arg @ref UART_RXFIFO_THRESHOLD_1_2 - * @arg @ref UART_RXFIFO_THRESHOLD_3_4 - * @arg @ref UART_RXFIFO_THRESHOLD_7_8 - * @arg @ref UART_RXFIFO_THRESHOLD_8_8 - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold) -{ - uint32_t tmpcr1; - - /* Check the parameters */ - assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); - assert_param(IS_UART_RXFIFO_THRESHOLD(Threshold)); - - /* Process Locked */ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Save actual UART configuration */ - tmpcr1 = READ_REG(huart->Instance->CR1); - - /* Disable UART */ - __HAL_UART_DISABLE(huart); - - /* Update RX threshold configuration */ - MODIFY_REG(huart->Instance->CR3, USART_CR3_RXFTCFG, Threshold); - - /* Determine the number of data to process during RX/TX ISR execution */ - UARTEx_SetNbDataToProcess(huart); - - /* Restore UART configuration */ - WRITE_REG(huart->Instance->CR1, tmpcr1); - - huart->gState = HAL_UART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; -} - -#endif /* USART_CR1_FIFOEN */ -/** - * @brief Receive an amount of data in blocking mode till either the expected number of data - * is received or an IDLE event occurs. - * @note HAL_OK is returned if reception is completed (expected number of data has been received) - * or if reception is stopped after IDLE event (less than the expected number of data has been received) - * In this case, RxLen output parameter indicates number of data available in reception buffer. - * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), - * the received data is handled as a set of uint16_t. In this case, Size must indicate the number - * of uint16_t available through pData. - * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO - * is not empty. Read operations from the RDR register are performed when - * RXFNE flag is set. From hardware perspective, RXFNE flag and - * RXNE are mapped on the same bit-field. - * @param huart UART handle. - * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). - * @param Size Amount of data elements (uint8_t or uint16_t) to be received. - * @param RxLen Number of data elements finally received - * (could be lower than Size, in case reception ends on IDLE event) - * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence). - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, - uint32_t Timeout) -{ - uint8_t *pdata8bits; - uint16_t *pdata16bits; - uint16_t uhMask; - uint32_t tickstart; - - /* Check that a Rx process is not already ongoing */ - if (huart->RxState == HAL_UART_STATE_READY) - { - if ((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - __HAL_LOCK(huart); - - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->RxState = HAL_UART_STATE_BUSY_RX; - huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; - - /* Init tickstart for timeout management */ - tickstart = HAL_GetTick(); - - huart->RxXferSize = Size; - huart->RxXferCount = Size; - - /* Computation of UART mask to apply to RDR register */ - UART_MASK_COMPUTATION(huart); - uhMask = huart->Mask; - - /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - pdata8bits = NULL; - pdata16bits = (uint16_t *) pData; - } - else - { - pdata8bits = pData; - pdata16bits = NULL; - } - - __HAL_UNLOCK(huart); - - /* Initialize output number of received elements */ - *RxLen = 0U; - - /* as long as data have to be received */ - while (huart->RxXferCount > 0U) - { - /* Check if IDLE flag is set */ - if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) - { - /* Clear IDLE flag in ISR */ - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); - - /* If Set, but no data ever received, clear flag without exiting loop */ - /* If Set, and data has already been received, this means Idle Event is valid : End reception */ - if (*RxLen > 0U) - { - huart->RxState = HAL_UART_STATE_READY; - - return HAL_OK; - } - } - - /* Check if RXNE flag is set */ - if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE)) - { - if (pdata8bits == NULL) - { - *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask); - pdata16bits++; - } - else - { - *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); - pdata8bits++; - } - /* Increment number of received elements */ - *RxLen += 1U; - huart->RxXferCount--; - } - - /* Check for the Timeout */ - if (Timeout != HAL_MAX_DELAY) - { - if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) - { - huart->RxState = HAL_UART_STATE_READY; - - return HAL_TIMEOUT; - } - } - } - - /* Set number of received elements in output parameter : RxLen */ - *RxLen = huart->RxXferSize - huart->RxXferCount; - /* At end of Rx process, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receive an amount of data in interrupt mode till either the expected number of data - * is received or an IDLE event occurs. - * @note Reception is initiated by this function call. Further progress of reception is achieved thanks - * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating - * number of received data elements. - * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), - * the received data is handled as a set of uint16_t. In this case, Size must indicate the number - * of uint16_t available through pData. - * @param huart UART handle. - * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). - * @param Size Amount of data elements (uint8_t or uint16_t) to be received. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) -{ - HAL_StatusTypeDef status; - - /* Check that a Rx process is not already ongoing */ - if (huart->RxState == HAL_UART_STATE_READY) - { - if ((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - __HAL_LOCK(huart); - - /* Set Reception type to reception till IDLE Event*/ - huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; - - status = UART_Start_Receive_IT(huart, pData, Size); - - /* Check Rx process has been successfully started */ - if (status == HAL_OK) - { - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); - } - else - { - /* In case of errors already pending when reception is started, - Interrupts may have already been raised and lead to reception abortion. - (Overrun error for instance). - In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */ - status = HAL_ERROR; - } - } - - return status; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receive an amount of data in DMA mode till either the expected number - * of data is received or an IDLE event occurs. - * @note Reception is initiated by this function call. Further progress of reception is achieved thanks - * to DMA services, transferring automatically received data elements in user reception buffer and - * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider - * reception phase as ended. In all cases, callback execution will indicate number of received data elements. - * @note When the UART parity is enabled (PCE = 1), the received data contain - * the parity bit (MSB position). - * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), - * the received data is handled as a set of uint16_t. In this case, Size must indicate the number - * of uint16_t available through pData. - * @param huart UART handle. - * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). - * @param Size Amount of data elements (uint8_t or uint16_t) to be received. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) -{ - HAL_StatusTypeDef status; - - /* Check that a Rx process is not already ongoing */ - if (huart->RxState == HAL_UART_STATE_READY) - { - if ((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - __HAL_LOCK(huart); - - /* Set Reception type to reception till IDLE Event*/ - huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; - - status = UART_Start_Receive_DMA(huart, pData, Size); - - /* Check Rx process has been successfully started */ - if (status == HAL_OK) - { - if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) - { - __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); - ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); - } - else - { - /* In case of errors already pending when reception is started, - Interrupts may have already been raised and lead to reception abortion. - (Overrun error for instance). - In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */ - status = HAL_ERROR; - } - } - - return status; - } - else - { - return HAL_BUSY; - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** @addtogroup UARTEx_Private_Functions - * @{ - */ - -/** - * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection. - * @param huart UART handle. - * @param WakeUpSelection UART wake up from stop mode parameters. - * @retval None - */ -static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) -{ - assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength)); - - /* Set the USART address length */ - MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength); - - /* Set the USART address node */ - MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS)); -} - -#if defined(USART_CR1_FIFOEN) -/** - * @brief Calculate the number of data to process in RX/TX ISR. - * @note The RX FIFO depth and the TX FIFO depth is extracted from - * the UART configuration registers. - * @param huart UART handle. - * @retval None - */ -static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart) -{ - uint8_t rx_fifo_depth; - uint8_t tx_fifo_depth; - uint8_t rx_fifo_threshold; - uint8_t tx_fifo_threshold; - static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U}; - static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U}; - - if (huart->FifoMode == UART_FIFOMODE_DISABLE) - { - huart->NbTxDataToProcess = 1U; - huart->NbRxDataToProcess = 1U; - } - else - { - rx_fifo_depth = RX_FIFO_DEPTH; - tx_fifo_depth = TX_FIFO_DEPTH; - rx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos); - tx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos); - huart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) / - (uint16_t)denominator[tx_fifo_threshold]; - huart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) / - (uint16_t)denominator[rx_fifo_threshold]; - } -} -#endif /* USART_CR1_FIFOEN */ -/** - * @} - */ - -#endif /* HAL_UART_MODULE_ENABLED */ - -/** - * @} - */ - -/** - * @} - */ - diff --git a/Firmware/Probe.ioc b/Firmware/Probe.ioc index 2a3c9ef..6cbe75d 100644 --- a/Firmware/Probe.ioc +++ b/Firmware/Probe.ioc @@ -35,21 +35,22 @@ Mcu.IP2=NVIC Mcu.IP3=RCC Mcu.IP4=SPI1 Mcu.IP5=SYS -Mcu.IP6=USART2 +Mcu.IP6=TIM15 Mcu.IP7=USB Mcu.IPNb=8 Mcu.Name=STM32L432K(B-C)Ux Mcu.Package=UFQFPN32 Mcu.Pin0=PC14-OSC32_IN (PC14) Mcu.Pin1=PC15-OSC32_OUT (PC15) -Mcu.Pin10=PA10 -Mcu.Pin11=PA11 -Mcu.Pin12=PA12 -Mcu.Pin13=PA13 (JTMS-SWDIO) -Mcu.Pin14=PA14 (JTCK-SWCLK) -Mcu.Pin15=PA15 (JTDI) +Mcu.Pin10=PA9 +Mcu.Pin11=PA10 +Mcu.Pin12=PA11 +Mcu.Pin13=PA12 +Mcu.Pin14=PA13 (JTMS-SWDIO) +Mcu.Pin15=PA14 (JTCK-SWCLK) Mcu.Pin16=PB3 (JTDO-TRACESWO) Mcu.Pin17=VP_SYS_VS_Systick +Mcu.Pin18=VP_TIM15_VS_ClockSourceINT Mcu.Pin2=PA0 Mcu.Pin3=PA1 Mcu.Pin4=PA2 @@ -57,8 +58,8 @@ Mcu.Pin5=PA5 Mcu.Pin6=PA6 Mcu.Pin7=PA7 Mcu.Pin8=PB0 -Mcu.Pin9=PA9 -Mcu.PinsNb=18 +Mcu.Pin9=PA8 +Mcu.PinsNb=19 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32L432KCUx @@ -77,7 +78,6 @@ NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SPI1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SysTick_IRQn=true\:0\:0\:true\:false\:true\:true\:true\:false -NVIC.USART2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.USB_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false PA0.GPIOParameters=GPIO_Label @@ -105,16 +105,8 @@ PA14\ (JTCK-SWCLK).GPIO_Label=SWCLK PA14\ (JTCK-SWCLK).Locked=true PA14\ (JTCK-SWCLK).Mode=Serial_Wire PA14\ (JTCK-SWCLK).Signal=SYS_JTCK-SWCLK -PA15\ (JTDI).GPIOParameters=GPIO_Label -PA15\ (JTDI).GPIO_Label=VCP_RX -PA15\ (JTDI).Locked=true -PA15\ (JTDI).Mode=Asynchronous -PA15\ (JTDI).Signal=USART2_RX -PA2.GPIOParameters=GPIO_Label -PA2.GPIO_Label=VCP_TX PA2.Locked=true -PA2.Mode=Asynchronous -PA2.Signal=USART2_TX +PA2.Signal=S_TIM15_CH1 PA5.Locked=true PA5.Mode=Full_Duplex_Master PA5.Signal=SPI1_SCK @@ -122,6 +114,10 @@ PA6.Mode=Full_Duplex_Master PA6.Signal=SPI1_MISO PA7.Mode=Full_Duplex_Master PA7.Signal=SPI1_MOSI +PA8.GPIOParameters=GPIO_Label +PA8.GPIO_Label=VSET_LED +PA8.Locked=true +PA8.Signal=GPIO_Output PA9.Mode=I2C PA9.Signal=I2C1_SCL PB0.GPIOParameters=GPIO_Label @@ -167,7 +163,7 @@ ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=Makefile ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true,5-MX_SPI1_Init-SPI1-false-HAL-true,6-MX_I2C1_Init-I2C1-false-HAL-true,7-MX_USB_PCD_Init-USB-false-HAL-true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_SPI1_Init-SPI1-false-HAL-true,5-MX_I2C1_Init-I2C1-false-HAL-true,6-MX_USB_PCD_Init-USB-false-HAL-true RCC.48CLKFreq_Value=24000000 RCC.ADCFreq_Value=64000000 RCC.AHBFreq_Value=80000000 @@ -227,6 +223,8 @@ RCC.VCOInputFreq_Value=16000000 RCC.VCOOutputFreq_Value=160000000 RCC.VCOSAI1OutputFreq_Value=128000000 RCC.WatchDogFreq_Value=32000 +SH.S_TIM15_CH1.0=TIM15_CH1,PWM Generation1 CH1 +SH.S_TIM15_CH1.ConfNb=1 SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32 SPI1.CalculateBaudRate=2.5 MBits/s SPI1.DataSize=SPI_DATASIZE_8BIT @@ -235,9 +233,14 @@ SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRate SPI1.Mode=SPI_MODE_MASTER SPI1.NSSPMode=SPI_NSS_PULSE_DISABLE SPI1.VirtualType=VM_MASTER -USART2.IPParameters=VirtualMode-Asynchronous -USART2.VirtualMode-Asynchronous=VM_ASYNC +TIM15.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 +TIM15.IPParameters=Channel-PWM Generation1 CH1,Prescaler,Pulse-PWM Generation1 CH1,Period +TIM15.Period=1000 +TIM15.Prescaler=40 +TIM15.Pulse-PWM\ Generation1\ CH1=500 VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_TIM15_VS_ClockSourceINT.Mode=Internal +VP_TIM15_VS_ClockSourceINT.Signal=TIM15_VS_ClockSourceINT board=NUCLEO-L432KC boardIOC=true diff --git a/HW/Probe.kicad_pcb b/HW/Probe.kicad_pcb index ac72485..f30d1b5 100644 --- a/HW/Probe.kicad_pcb +++ b/HW/Probe.kicad_pcb @@ -4505,6 +4505,7 @@ (xy 56.678023 90.855289) (xy 56.727368 90.850972) (xy 56.738176 90.8505) + (xy 56.743709 90.8505) (xy 80.63777 90.8505) (xy 80.685223 90.859939) (xy 80.725451 90.886819) diff --git a/HW/Probe.kicad_prl b/HW/Probe.kicad_prl index f06f820..7c52f67 100644 --- a/HW/Probe.kicad_prl +++ b/HW/Probe.kicad_prl @@ -1,6 +1,6 @@ { "board": { - "active_layer": 0, + "active_layer": 36, "active_layer_preset": "All Layers", "auto_track_width": true, "hidden_netclasses": [], diff --git a/Probe_Assembled.jpg b/Probe_Assembled.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cb12aa77e2a16f940d876172a3accaea2c5ed692 GIT binary patch literal 40257 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 literal 0 HcmV?d00001 diff --git a/Probe_Render.png b/Probe_Render.png new file mode 100644 index 0000000000000000000000000000000000000000..4dcb3b82ed4775181fb047c982d132406810f527 GIT binary patch literal 140379 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 Ji@Ry)^FN=gczpl> literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 6194c29..468e351 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,60 @@ # Profilometer Probe -## Firmware for profilometer probe - -### Build -- Build using Makefile inside Firmware folder -- Flash onto hardware using flash option for make command `$ make flash` +![alt text](https://github.com/aprochazka/ProfilometerProbe/blob/main/Probe_Render.png?raw=true) +![alt text](https://github.com/aprochazka/ProfilometerProbe/blob/main/Probe_Assembled.png?raw=true) -### Supported HW: -- Nucleo L432KC -- Arducam 5MP Plus +## Hardware +### Models -### HW Setup +- All 3D printable models are located inside Models folder +- Models are designed to be printed with standard 2mm layer height +- When slicing be sure to print outer walls first to make print more accurate -Before running code, connect camera module to microcontroler through pins described in .ioc file (open with STM32CubeMX) or in table below. +### Components -| Name | Nucleo L432KC | Arducam 5MP Plus | -| ----------- | ------------- | ---------------- | -| SPI SCLK | A4 | SCK | -| SPI MISO | A5 | MISO | -| SPI MOSI | A6 | MOSI | -| SPI CS | D3 | CS | -| I2C SCL | D1 | SCL | -| I2C SDA | D0 | SDA | +- Development board: Nucleo L432KC +- Camera: ArduCam mini 5MP Plus +- Distance sensor: Pimoroni LV53L1X +- Complete list of components and connectors for probe can be found inside HW/Parts.md -You can connect optional Debug LED to A1 pin in Nucleo board. +## Firmware for profilometer probe #### Probe design block Scheme ![alt text](https://github.com/aprochazka/ProfilometerProbe/blob/main/deviceScheme.png?raw=true) -### Current State +### Build + +- Build using Makefile inside Firmware folder (dependency: arm-none-eabi) +- Flash onto hardware using flash option for make command `$ make flash` + +### Usage -- Sends test JPEG image sequence through USB CDC +- Connect probe to pc using usb c cable and firmware will start sending sending data automatically -### Test Current State +### Documentation -- Tested on: Arch Linux +- Create documentation using 'doc' option of Makefile '$ make doc' + +## Software for receiving data + +### Build -- Inside Receiver folder build using Makefile +- Build using Makefile inside Receiver folder -- Code counts with CDC device on /dev/ttyACM2 (can be changed in code) +### Usage -- Run with sudo permission, so that serial port is openable +- Has to be run with sudo permissions to correctly access USB CDC port. +- '$ sudo ./main -p [-s Save received jpeg to files] [-r Print raw received CDC data to standard output]' +- Prefer running with optional -s command for ability to inspect already captured images -### Test Script Usage - outdated +### Documentation -- Build test app using provided Makefile and then run the executable +- Create documentation using 'doc' option of Makefile '$ make doc' -- App will then start saving files received by uart to filesystem +### TODO -### In progress +- Process image and filter only laser line from it +- Use precessed data to determine depth or height of irregularities diff --git a/Receiver/.vscode/settings.json b/Receiver/.vscode/settings.json index 7bcfee6..8fc42e7 100644 --- a/Receiver/.vscode/settings.json +++ b/Receiver/.vscode/settings.json @@ -58,6 +58,7 @@ "stop_token": "cpp", "streambuf": "cpp", "cinttypes": "cpp", - "typeinfo": "cpp" + "typeinfo": "cpp", + "fstream": "cpp" } } \ No newline at end of file diff --git a/Receiver/Displayer.cpp b/Receiver/Displayer.cpp index f3ca6ca..2e13a56 100644 --- a/Receiver/Displayer.cpp +++ b/Receiver/Displayer.cpp @@ -1,3 +1,12 @@ +/** + * @file Displayer.cpp + * @brief Source file for the Displayer class. + * @author Adam Prochazka + * + * This file contains the implementation of the Displayer class which is responsible for + * rendering the images received from the Receiver class. + */ + #include "main.hpp" #include "Displayer.hpp" @@ -8,10 +17,9 @@ int Displayer::createWindow() { return 1; } - window = SDL_CreateWindow("Image Viewer", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_SHOWN); + window = SDL_CreateWindow("Profilometer View", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_SHOWN); if (!window) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create window: %s", SDL_GetError()); - //SDL_Quit(); return 1; } @@ -23,18 +31,15 @@ int Displayer::renderWindow(){ if (!renderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create renderer: %s", SDL_GetError()); - //SDL_DestroyWindow(window); - //SDL_Quit(); return 1; } return 0; } -#define PRINT_BUFFER 0 -int Displayer::imageFromVector(std::vector* img){ - #if PRINT_BUFFER +int Displayer::imageFromVector(std::vector* img, bool printRaw){ + if(printRaw){ std::cout << "______________" << std::endl; for(int i = 0; i<(int)(img)->size(); i++) @@ -44,7 +49,7 @@ int Displayer::imageFromVector(std::vector* img){ std::cout << std::endl; std::cout << "______________" << std::endl; - #endif + } imageRwops = SDL_RWFromMem(img->data(), img->size()); return 0; @@ -52,12 +57,10 @@ int Displayer::imageFromVector(std::vector* img){ int Displayer::createImageSurface(){ imageSurface = IMG_Load_RW(imageRwops, 0); + if (!imageSurface) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load image: %s", IMG_GetError()); - //SDL_DestroyRenderer(renderer); - //SDL_DestroyWindow(window); - //SDL_Quit(); - //return 1; + return 1; } return 0; @@ -106,13 +109,12 @@ int Displayer::windowDestroy(){ return 0; } -int Displayer::windowLoop(){ - bool quit = false; - while (!quit) { +int Displayer::windowLoop(bool *q){ + while (!(*q)) { SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { - quit = true; + *q = true; } } @@ -145,8 +147,8 @@ int Displayer::windowLoop(){ } -int Displayer::vectorToTexture(std::vector* img){ - imageFromVector(img); +int Displayer::vectorToTexture(std::vector* img, bool printRaw){ + imageFromVector(img, printRaw); createImageSurface(); textureFromSurface(); @@ -165,5 +167,6 @@ int Displayer::flipThroughTextures(){ flipIdx++; flipIdx%=2; } + return 0; } diff --git a/Receiver/Displayer.hpp b/Receiver/Displayer.hpp index a8f13c7..0032549 100644 --- a/Receiver/Displayer.hpp +++ b/Receiver/Displayer.hpp @@ -1,5 +1,19 @@ +/** + * @file Displayer.hpp + * @brief Header file for the Displayer class. + * @author Adam Prochazka + * + * This file contains the declaration of the Displayer class which is responsible for + * rendering the images received from the Receiver class. + */ + #include "main.hpp" #define DISPLAYER_HPP + +/*! + * \class Displayer + * \brief This class is responsible for displaying image data to user, that includes storing image bytes inside buffer, creating textures from those bytes, rendering UI and updating UI. + */ class Displayer { private: SDL_Window* window; @@ -16,19 +30,63 @@ class Displayer { std::mutex currentTextureIndexMutex; public: + /*! + * \brief Create the main SDL window. + * \return 0 on success, 1 on failure. + */ int createWindow(); + + /*! + * \brief Render the main SDL window. + * \return 0 on success, 1 on failure. + */ int renderWindow(); - int imageFromVector(std::vector* img); + /*! + * \brief Copy image data from a vector to an SDL_RWops structure. + * \param[in] img A pointer to the vector containing the image data. + * @param printRaw Bool that indicates weather received byte data should be printed to std::out (for debug). + * \return 0. + */ + int imageFromVector(std::vector* img, bool printRaw = false); + + /*! + * \brief Create an SDL_Surface from the SDL_RWops structure containing image data. + * \return 0 on success, 1 on failure. + */ int createImageSurface(); + + /*! + * \brief Create an SDL_Texture from an SDL_Surface and store it to last recently used texture buffer. + * \return 0 on success, 1 on failure. + */ int textureFromSurface(); - int vectorToTexture(std::vector* img); + /*! + * \brief Convert a vector of image data to an SDL_Texture and store it to laset recently used texture buffer. + * \param[in] img A pointer to the vector containing the image data. + * @param printRaw Bool that indicates weather received byte data should be printed to std::out (for debug). + * \return 0. + */ + int vectorToTexture(std::vector* img, bool printRaw = false); + /*! + * \brief Destroy the main SDL window, SDL renderer and SDL textures stored in buffers. + * \return 0 on success, 1 on failure. + */ int windowDestroy(); - int windowLoop(); + /*! + * \brief Run the main window loop, refresh currently rendered texture buffer with newest one from texture buffers. + * \return 0. + */ + int windowLoop(bool *q); + + /*! + * \brief Test function to see if rendering works by infinitelly flipping between two predefined textures. + * \return 0. + */ int flipThroughTextures(); }; diff --git a/Receiver/Doxyfile b/Receiver/Doxyfile new file mode 100644 index 0000000..5f5d020 --- /dev/null +++ b/Receiver/Doxyfile @@ -0,0 +1,2763 @@ +# Doxyfile 1.9.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "Receiver" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = "doc" + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN Use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0. and GITHUB Use the lower case version of title +# with any whitespace replaced by '-' and punctations characters removed.. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. + +CASE_SENSE_NAMES = SYSTEM + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.l \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f18 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# ANamespace::AClass, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /