diff --git a/.cubemx_survival_baseline.json b/.cubemx_survival_baseline.json index f76f10be..2b783116 100644 --- a/.cubemx_survival_baseline.json +++ b/.cubemx_survival_baseline.json @@ -5,18 +5,21 @@ "fault-handlers-3": "1dfa875a1b75bea4", "fault-handler-enable": "be87fcd3a7926138", "hardfault-report-impl": "7a4d1c2b4a4b6fee", - "stack-overflow-check": "4548c9c6ef1b2409", - "malloc-failed-hook": "4548c9c6ef1b2409", + "stack-overflow-check": "d4735e3a265e16ee", + "malloc-failed-hook": "6b86b273ff34fce1", "assert-not-deadloop": "d4a00718ab2bd071", - "assert-impl": "b7fd1fadb4522edf", - "stack-overflow-hook-impl": "b7fd1fadb4522edf", + "assert-impl": "908de37a05c944ce", + "stack-overflow-hook-impl": "a006edbd30d2c4d7", + "malloc-failed-hook-impl": "fcd7250e5cd6403b", + "stack-overflow-hook-helper": "cacd9fd028be9b5b", "watchdog-module": "58f95a6cb88e6925", "reset-cause-latch": "52fc71acbb0f1aed", "iwdg-hal-driver": "4b902875a84554e9", - "hal-iwdg-enabled": "c8c9b916b05464b9", + "hal-iwdg-enabled": "1a8ed6cff34f7ba6", "ioc-keepusercode": "b5bea41b6c623f7c", "ioc-iwdg-present": "d3a6e667048c95db", - "ioc-task-stacks": "3262f737d92dcbee" + "ioc-task-stacks": "3262f737d92dcbee", + "adc1-hal-enabled": "1a8ed6cff34f7ba6" }, "_note": "CubeMX 存活审计基线;改动用 --write 重建" } diff --git a/.mxproject b/.mxproject index 4c585c40..17527ba2 100644 --- a/.mxproject +++ b/.mxproject @@ -1,13 +1,13 @@ [PreviousLibFiles] -LibFiles=Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_tim.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_tim_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ramfunc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal.h;Drivers\STM32F4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_def.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_i2c.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_i2c.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_i2c_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_iwdg.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_iwdg.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_spi.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_spi.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_uart.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_usart.h;Middlewares\Third_Party\FreeRTOS\Source\include\croutine.h;Middlewares\Third_Party\FreeRTOS\Source\include\deprecated_definitions.h;Middlewares\Third_Party\FreeRTOS\Source\include\event_groups.h;Middlewares\Third_Party\FreeRTOS\Source\include\FreeRTOS.h;Middlewares\Third_Party\FreeRTOS\Source\include\list.h;Middlewares\Third_Party\FreeRTOS\Source\include\message_buffer.h;Middlewares\Third_Party\FreeRTOS\Source\include\mpu_prototypes.h;Middlewares\Third_Party\FreeRTOS\Source\include\mpu_wrappers.h;Middlewares\Third_Party\FreeRTOS\Source\include\portable.h;Middlewares\Third_Party\FreeRTOS\Source\include\projdefs.h;Middlewares\Third_Party\FreeRTOS\Source\include\queue.h;Middlewares\Third_Party\FreeRTOS\Source\include\semphr.h;Middlewares\Third_Party\FreeRTOS\Source\include\stack_macros.h;Middlewares\Third_Party\FreeRTOS\Source\include\StackMacros.h;Middlewares\Third_Party\FreeRTOS\Source\include\stream_buffer.h;Middlewares\Third_Party\FreeRTOS\Source\include\task.h;Middlewares\Third_Party\FreeRTOS\Source\include\timers.h;Middlewares\Third_Party\FreeRTOS\Source\include\atomic.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\freertos_mpool.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\freertos_os2.h;Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\portmacro.h;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_iwdg.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_spi.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c;Middlewares\Third_Party\FreeRTOS\Source\croutine.c;Middlewares\Third_Party\FreeRTOS\Source\event_groups.c;Middlewares\Third_Party\FreeRTOS\Source\list.c;Middlewares\Third_Party\FreeRTOS\Source\queue.c;Middlewares\Third_Party\FreeRTOS\Source\stream_buffer.c;Middlewares\Third_Party\FreeRTOS\Source\tasks.c;Middlewares\Third_Party\FreeRTOS\Source\timers.c;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.c;Middlewares\Third_Party\FreeRTOS\Source\portable\MemMang\heap_4.c;Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\port.c;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_tim.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_tim_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ramfunc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal.h;Drivers\STM32F4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_def.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_i2c.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_i2c.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_i2c_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_iwdg.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_iwdg.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_spi.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_spi.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_uart.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_usart.h;Middlewares\Third_Party\FreeRTOS\Source\include\croutine.h;Middlewares\Third_Party\FreeRTOS\Source\include\deprecated_definitions.h;Middlewares\Third_Party\FreeRTOS\Source\include\event_groups.h;Middlewares\Third_Party\FreeRTOS\Source\include\FreeRTOS.h;Middlewares\Third_Party\FreeRTOS\Source\include\list.h;Middlewares\Third_Party\FreeRTOS\Source\include\message_buffer.h;Middlewares\Third_Party\FreeRTOS\Source\include\mpu_prototypes.h;Middlewares\Third_Party\FreeRTOS\Source\include\mpu_wrappers.h;Middlewares\Third_Party\FreeRTOS\Source\include\portable.h;Middlewares\Third_Party\FreeRTOS\Source\include\projdefs.h;Middlewares\Third_Party\FreeRTOS\Source\include\queue.h;Middlewares\Third_Party\FreeRTOS\Source\include\semphr.h;Middlewares\Third_Party\FreeRTOS\Source\include\stack_macros.h;Middlewares\Third_Party\FreeRTOS\Source\include\StackMacros.h;Middlewares\Third_Party\FreeRTOS\Source\include\stream_buffer.h;Middlewares\Third_Party\FreeRTOS\Source\include\task.h;Middlewares\Third_Party\FreeRTOS\Source\include\timers.h;Middlewares\Third_Party\FreeRTOS\Source\include\atomic.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\freertos_mpool.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\freertos_os2.h;Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\portmacro.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f407xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;Drivers\CMSIS\Include\cachel1_armv7.h;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm55.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_cm85.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\core_starmc1.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\pac_armv81.h;Drivers\CMSIS\Include\pmu_armv8.h;Drivers\CMSIS\Include\tz_context.h; +LibFiles=Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_tim.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_tim_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_adc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_adc_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_adc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ramfunc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal.h;Drivers\STM32F4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_def.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_i2c.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_i2c.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_i2c_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_iwdg.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_iwdg.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_spi.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_spi.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_uart.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_usart.h;Middlewares\Third_Party\FreeRTOS\Source\include\croutine.h;Middlewares\Third_Party\FreeRTOS\Source\include\deprecated_definitions.h;Middlewares\Third_Party\FreeRTOS\Source\include\event_groups.h;Middlewares\Third_Party\FreeRTOS\Source\include\FreeRTOS.h;Middlewares\Third_Party\FreeRTOS\Source\include\list.h;Middlewares\Third_Party\FreeRTOS\Source\include\message_buffer.h;Middlewares\Third_Party\FreeRTOS\Source\include\mpu_prototypes.h;Middlewares\Third_Party\FreeRTOS\Source\include\mpu_wrappers.h;Middlewares\Third_Party\FreeRTOS\Source\include\portable.h;Middlewares\Third_Party\FreeRTOS\Source\include\projdefs.h;Middlewares\Third_Party\FreeRTOS\Source\include\queue.h;Middlewares\Third_Party\FreeRTOS\Source\include\semphr.h;Middlewares\Third_Party\FreeRTOS\Source\include\stack_macros.h;Middlewares\Third_Party\FreeRTOS\Source\include\StackMacros.h;Middlewares\Third_Party\FreeRTOS\Source\include\stream_buffer.h;Middlewares\Third_Party\FreeRTOS\Source\include\task.h;Middlewares\Third_Party\FreeRTOS\Source\include\timers.h;Middlewares\Third_Party\FreeRTOS\Source\include\atomic.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\freertos_mpool.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\freertos_os2.h;Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\portmacro.h;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_adc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_adc_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c_ex.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_iwdg.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_spi.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c;Middlewares\Third_Party\FreeRTOS\Source\croutine.c;Middlewares\Third_Party\FreeRTOS\Source\event_groups.c;Middlewares\Third_Party\FreeRTOS\Source\list.c;Middlewares\Third_Party\FreeRTOS\Source\queue.c;Middlewares\Third_Party\FreeRTOS\Source\stream_buffer.c;Middlewares\Third_Party\FreeRTOS\Source\tasks.c;Middlewares\Third_Party\FreeRTOS\Source\timers.c;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.c;Middlewares\Third_Party\FreeRTOS\Source\portable\MemMang\heap_4.c;Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\port.c;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_tim.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_tim_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_adc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_adc_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_adc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_rcc_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_flash_ramfunc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_gpio_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_pwr_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal.h;Drivers\STM32F4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_def.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_i2c.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_i2c.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_i2c_ex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_iwdg.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_iwdg.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_spi.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_spi.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_uart.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_usart.h;Middlewares\Third_Party\FreeRTOS\Source\include\croutine.h;Middlewares\Third_Party\FreeRTOS\Source\include\deprecated_definitions.h;Middlewares\Third_Party\FreeRTOS\Source\include\event_groups.h;Middlewares\Third_Party\FreeRTOS\Source\include\FreeRTOS.h;Middlewares\Third_Party\FreeRTOS\Source\include\list.h;Middlewares\Third_Party\FreeRTOS\Source\include\message_buffer.h;Middlewares\Third_Party\FreeRTOS\Source\include\mpu_prototypes.h;Middlewares\Third_Party\FreeRTOS\Source\include\mpu_wrappers.h;Middlewares\Third_Party\FreeRTOS\Source\include\portable.h;Middlewares\Third_Party\FreeRTOS\Source\include\projdefs.h;Middlewares\Third_Party\FreeRTOS\Source\include\queue.h;Middlewares\Third_Party\FreeRTOS\Source\include\semphr.h;Middlewares\Third_Party\FreeRTOS\Source\include\stack_macros.h;Middlewares\Third_Party\FreeRTOS\Source\include\StackMacros.h;Middlewares\Third_Party\FreeRTOS\Source\include\stream_buffer.h;Middlewares\Third_Party\FreeRTOS\Source\include\task.h;Middlewares\Third_Party\FreeRTOS\Source\include\timers.h;Middlewares\Third_Party\FreeRTOS\Source\include\atomic.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\freertos_mpool.h;Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\freertos_os2.h;Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\portmacro.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f407xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;Drivers\CMSIS\Include\cachel1_armv7.h;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm55.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_cm85.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\core_starmc1.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\pac_armv81.h;Drivers\CMSIS\Include\pmu_armv8.h;Drivers\CMSIS\Include\tz_context.h; [PreviousUsedKeilFiles] -SourceFiles=..\Src\main.c;..\Src\gpio.c;..\Src\freertos.c;..\Src\dma.c;..\Src\i2c.c;..\Src\iwdg.c;..\Src\spi.c;..\Src\usart.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;..\Src\stm32f4xx_hal_timebase_tim.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_iwdg.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_spi.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c;..\Middlewares\Third_Party\FreeRTOS\Source\croutine.c;..\Middlewares\Third_Party\FreeRTOS\Source\event_groups.c;..\Middlewares\Third_Party\FreeRTOS\Source\list.c;..\Middlewares\Third_Party\FreeRTOS\Source\queue.c;..\Middlewares\Third_Party\FreeRTOS\Source\stream_buffer.c;..\Middlewares\Third_Party\FreeRTOS\Source\tasks.c;..\Middlewares\Third_Party\FreeRTOS\Source\timers.c;..\Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.c;..\Middlewares\Third_Party\FreeRTOS\Source\portable\MemMang\heap_4.c;..\Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\port.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_iwdg.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_spi.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c;..\Middlewares\Third_Party\FreeRTOS\Source\croutine.c;..\Middlewares\Third_Party\FreeRTOS\Source\event_groups.c;..\Middlewares\Third_Party\FreeRTOS\Source\list.c;..\Middlewares\Third_Party\FreeRTOS\Source\queue.c;..\Middlewares\Third_Party\FreeRTOS\Source\stream_buffer.c;..\Middlewares\Third_Party\FreeRTOS\Source\tasks.c;..\Middlewares\Third_Party\FreeRTOS\Source\timers.c;..\Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.c;..\Middlewares\Third_Party\FreeRTOS\Source\portable\MemMang\heap_4.c;..\Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\port.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;;; +SourceFiles=..\Src\main.c;..\Src\gpio.c;..\Src\freertos.c;..\Src\adc.c;..\Src\dma.c;..\Src\i2c.c;..\Src\iwdg.c;..\Src\spi.c;..\Src\usart.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;..\Src\stm32f4xx_hal_timebase_tim.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_adc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_adc_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_iwdg.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_spi.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c;..\Middlewares\Third_Party\FreeRTOS\Source\croutine.c;..\Middlewares\Third_Party\FreeRTOS\Source\event_groups.c;..\Middlewares\Third_Party\FreeRTOS\Source\list.c;..\Middlewares\Third_Party\FreeRTOS\Source\queue.c;..\Middlewares\Third_Party\FreeRTOS\Source\stream_buffer.c;..\Middlewares\Third_Party\FreeRTOS\Source\tasks.c;..\Middlewares\Third_Party\FreeRTOS\Source\timers.c;..\Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.c;..\Middlewares\Third_Party\FreeRTOS\Source\portable\MemMang\heap_4.c;..\Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\port.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_tim_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_adc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_adc_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rcc_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_flash_ramfunc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pwr_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_cortex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_exti.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_i2c_ex.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_iwdg.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_spi.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c;..\Middlewares\Third_Party\FreeRTOS\Source\croutine.c;..\Middlewares\Third_Party\FreeRTOS\Source\event_groups.c;..\Middlewares\Third_Party\FreeRTOS\Source\list.c;..\Middlewares\Third_Party\FreeRTOS\Source\queue.c;..\Middlewares\Third_Party\FreeRTOS\Source\stream_buffer.c;..\Middlewares\Third_Party\FreeRTOS\Source\tasks.c;..\Middlewares\Third_Party\FreeRTOS\Source\timers.c;..\Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.c;..\Middlewares\Third_Party\FreeRTOS\Source\portable\MemMang\heap_4.c;..\Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\port.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;;; HeaderPath=..\Drivers\STM32F4xx_HAL_Driver\Inc;..\Drivers\STM32F4xx_HAL_Driver\Inc\Legacy;..\Middlewares\Third_Party\FreeRTOS\Source\include;..\Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2;..\Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F;..\Drivers\CMSIS\Device\ST\STM32F4xx\Include;..\Drivers\CMSIS\Include;..\Inc; CDefines=USE_HAL_DRIVER;STM32F407xx;USE_HAL_DRIVER;USE_HAL_DRIVER; [PreviousGenFiles] HeaderPath=..\Inc -HeaderFiles=gpio.h;FreeRTOSConfig.h;dma.h;i2c.h;iwdg.h;spi.h;usart.h;stm32f4xx_it.h;stm32f4xx_hal_conf.h;main.h; +HeaderFiles=gpio.h;FreeRTOSConfig.h;adc.h;dma.h;i2c.h;iwdg.h;spi.h;usart.h;stm32f4xx_it.h;stm32f4xx_hal_conf.h;main.h; SourcePath=..\Src -SourceFiles=gpio.c;freertos.c;dma.c;i2c.c;iwdg.c;spi.c;usart.c;stm32f4xx_it.c;stm32f4xx_hal_msp.c;stm32f4xx_hal_timebase_tim.c;main.c; +SourceFiles=gpio.c;freertos.c;adc.c;dma.c;i2c.c;iwdg.c;spi.c;usart.c;stm32f4xx_it.c;stm32f4xx_hal_msp.c;stm32f4xx_hal_timebase_tim.c;main.c; diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d8d4b8e0..ace93544 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,15 +16,26 @@ repos: rev: v5.0.0 hooks: - id: trailing-whitespace - # 排除第三方库(CubeMX 重生成会带回行尾空白,避免每次重生成产生提交抖动); - # 自研代码(Drivers/BSP、Src、Inc、App 等)不受影响 - exclude: | + # 豁免 **CubeMX / Keil 生成的文件**(锚名 cubemx-generated,end-of-file-fixer 复用): + # 这类文件的内容事实源是 `.ioc` 与工具链,每次重生成都按工具自己的风格写回 + # (行尾空白、文件末尾不带换行)。2026-10-09 实测:每次重生成后 `Src/`/`Inc/` + # 下 10+ 个文件各被补 1 行末尾空行,纯属提交抖动。 + # ⚠ 只豁免**改写型**钩子(trailing-whitespace / end-of-file-fixer); + # cppcheck / 乱码 / 存活审计 / 任务表 / 内存数字等**只读检查**仍覆盖 + # `Src/`、`Inc/`——`cubemx-survival` 必须能看到这些文件。 + exclude: &cubemx-generated | (?x)^( + Src/.*\.(c|h)$| + Inc/.*\.(c|h)$| Drivers/CMSIS/| Drivers/STM32F4xx_HAL_Driver/| - Middlewares/ + Middlewares/| + MDK-ARM/.*\.(uvprojx|uvoptx|sct|map)$| + \.mxproject$| + .*\.ioc$ ) - id: end-of-file-fixer + exclude: *cubemx-generated - id: check-added-large-files - id: check-merge-conflict - id: check-yaml diff --git a/AGENTS.md b/AGENTS.md index 6f68e328..00471199 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,7 +30,7 @@ STM32F407ZGTx @168MHz(HSE 8MHz → PLL M=4/N=168/P=2);**仅 Keil MDK-ARM v ## 提交门禁(pre-commit) - 任一失败即拦截:cppcheck(warning/performance/portability/style)+ C 代码规范机械检查 + U+FFFD 乱码检查 + gitlint;范围仅项目代码(第三方 `Lib/`/`Middlewares/`/CMSIS/HAL/`lftpd`/`dhara`/`MDK-ARM`/`test/` 排除;规范检查另排除 CubeMX 生成的 `Src/`/`Inc/`) -- trailing-whitespace 钩子另排除 `Drivers/CMSIS/`、`Drivers/STM32F4xx_HAL_Driver/`、`Middlewares/`(2026-09-20:CubeMX 6.18 重生成带回行尾空白,每次重生成产生提交抖动;`Drivers/BSP/` 自研代码仍受检) +- **改写型钩子(`trailing-whitespace` + `end-of-file-fixer`)豁免 CubeMX/Keil 生成文件**(2026-10-09 定;配置里 YAML 锚点 `&cubemx-generated` 两处共用):`Src/*.{c,h}`、`Inc/*.{c,h}`、`Drivers/CMSIS/`、`Drivers/STM32F4xx_HAL_Driver/`、`Middlewares/`、`MDK-ARM/*.{uvprojx,uvoptx,sct,map}`、`.mxproject`、`*.ioc`——这类文件每次重生成按工具自己的风格写回(实测每次 10+ 个文件各被补 1 行末尾空行),改写只会制造提交抖动。⚠ **只读检查不受影响**:`cppcheck` / 乱码 / `cubemx-survival` / `task-table` / `mem-numbers` 仍覆盖 `Src/`、`Inc/`;`App/`、`Drivers/BSP/` 自研代码仍受改写型钩子检查 - 提交信息:**单行中文标题 <100 字符**(gitlint),UTF-8 无 BOM + `git commit -F <文件>`(防终端转码破坏) - 代码规范 V1.0:小写下划线命名(`g_`/`s_`/`p_`/`a_` 前缀)、头文件保护宏 `XXX_H`、常量在右、文件头模块注释块 → `docs/代码规范/` - 全库扫描 `pre-commit run --all-files`;详见 `docs/代码规范/pre-commit使用说明.md` @@ -39,7 +39,7 @@ STM32F407ZGTx @168MHz(HSE 8MHz → PLL M=4/N=168/P=2);**仅 Keil MDK-ARM v ## 平台约束 - `Inc/`/`Src/` 中 CubeMX 生成文件带 `USER CODE BEGIN/END` 标记:自定义代码**只写标记区之间**;`Drivers/BSP/` 为纯手工代码 -- **CubeMX 重生成会覆盖标记区之外的一切**(`.ioc` 的 `KeepUserCode=true` **只**保护 `USER CODE` 区;2026-09-29 两次重生成各覆盖 4~5 处定制,其中 P1 两处**不报编译错**、只在真出故障时暴露)。防止定制丢失按三层优先级:**L1 写进 `.ioc`**(凡 CubeMX 界面能表达的配置,如任务栈/优先级/队列/事件组/堆大小/IWDG 参数——权限最高,重生成只会照写)→ **L2 搬进 `USER CODE` 区**(**只信 CubeMX 当前模板真实生成的区名**,优先文件头 `USER CODE BEGIN 0` 这类从未变过的标准位)→ **L3 审计兜底**。**每次重生成后立刻跑 `python scripts/check_cubemx_survival.py`**(已挂 pre-commit `cubemx-survival` 钩子;改动 `.ioc`/`Src/`/`Inc/`/`task_watchdog`/`.uvprojx` 触发)——清单 18 项 + 哈希基线漂移检测,直接列出"被覆盖了哪几处"。⚠️ **不要依赖"自造标记区"**:2026-09-29 实测 CubeMX **换了一代中断函数模板**(旧 `HardFault_Handler`/`HardFault_Report` 自造区 → 新函数体内 `HardFault_IRQn 0`/`W1_HardFault_IRQn 0`),旧区**连同内容一起消失**(看起来仍像"遵守了规则")。**生成区内无标记位可用的改动只能 L3 兜底**(如 `Src/iwdg.c` 的 `HAL_IWDG_Init()` 调用、4 个 Fault Handler 本体——本代模板整函数重写),一律加锚点注释(`IWDG-DEFER-START-ANCHOR` / `HARD-FAULT-ANCHOR` / `MEMFAULT-ANCHOR` / `BUSFAULT-ANCHOR` / `USAGEFAULT-ANCHOR`)供审计检出。方法论详见 `docs/子系统设计/看门狗设计说明.md` §10.1/§10.2 +- **CubeMX 重生成会覆盖标记区之外的一切**(`.ioc` 的 `KeepUserCode=true` **只**保护 `USER CODE` 区;2026-09-29 两次重生成各覆盖 4~5 处定制,其中 P1 两处**不报编译错**、只在真出故障时暴露)。防止定制丢失按三层优先级:**L1 写进 `.ioc`**(凡 CubeMX 界面能表达的配置,如任务栈/优先级/队列/事件组/堆大小/IWDG 参数——权限最高,重生成只会照写)→ **L2 搬进 `USER CODE` 区**(**只信 CubeMX 当前模板真实生成的区名**,优先文件头 `USER CODE BEGIN 0` 这类从未变过的标准位)→ **L3 审计兜底**。**每次重生成后立刻跑 `python scripts/check_cubemx_survival.py`**(已挂 pre-commit `cubemx-survival` 钩子;改动 `.ioc`/`Src/`/`Inc/`/`task_watchdog`/`.uvprojx` 触发)——清单 21 项 + 哈希基线漂移检测,直接列出"被覆盖了哪几处"。**2026-10-09 第三次重生成(启用 ADC1)补充**:`Inc/FreeRTOSConfig.h` 的自造 `FREE_RTOS_CONFIG_HARDENING` 区**第二次**被抹 → 已改走 **L1**:`configCHECK_FOR_STACK_OVERFLOW=2` / `configUSE_MALLOC_FAILED_HOOK=1` 在 GUI 的 **FreeRTOS → Config parameters → Hook function related definitions** 里设(写进 `.ioc` 由模板生成,永不再丢;教训:**别凭印象断言"界面里没有该项"**,先翻标签页或查 `db/mcu/IP/*_Modes.xml`)。⚠️ 启用后 CubeMX 会在 `Src/freertos.c` 生成 `USER CODE BEGIN 4 / 5` 区(默认内容是**空桩**)——**钩子实现必须整体写进这两个区**(原先在 `USER CODE Application` 区的实现要搬走,否则同名函数两处定义 = **编译错**;配套 helper `hook_ptr_ok()` 须在钩子之前 → 放 `USER CODE BEGIN PD` 区)。审计项 `stack-overflow-hook-impl` / `malloc-failed-hook-impl` / `stack-overflow-hook-helper` 分别校验 4 / 5 / PD 三个区。⚠️ **不要依赖"自造标记区"**:2026-09-29 实测 CubeMX **换了一代中断函数模板**(旧 `HardFault_Handler`/`HardFault_Report` 自造区 → 新函数体内 `HardFault_IRQn 0`/`W1_HardFault_IRQn 0`),旧区**连同内容一起消失**(看起来仍像"遵守了规则")。**生成区内无标记位可用的改动只能 L3 兜底**(如 `Src/iwdg.c` 的 `HAL_IWDG_Init()` 调用、4 个 Fault Handler 本体——本代模板整函数重写),一律加锚点注释(`IWDG-DEFER-START-ANCHOR` / `HARD-FAULT-ANCHOR` / `MEMFAULT-ANCHOR` / `BUSFAULT-ANCHOR` / `USAGEFAULT-ANCHOR`)供审计检出。方法论详见 `docs/子系统设计/看门狗设计说明.md` §10.1/§10.2 - **4 个 Cortex-M4 Fault 全部采集现场**(2026-09-29):`HardFault` / `MemManage` / `BusFault` / `UsageFault` 均为手工 `__asm` Handler(取 MSP/PSP 帧指针)→ `B` 到 per-fault C 入口 `fault_entry_{hard,mem,bus,usage}`(各自带故障名)→ `hard_fault_report(tag, frame)` 打 `[ERR] PC/LR/xPSR/R0-R3/CFSR/HFSR[/BFAR][/MMFAR]` 后 `NVIC_SystemReset()`。**后三者默认禁用**(复位后 `SHCSR` 只开 HardFault),不使能就会被**升级成 HardFault**、日志看不出根因 → `fault_handler_enable()`(`Src/stm32f4xx_it.c` 的 `USER CODE BEGIN 1` 区)在 `app_main_init()` **第一行**调用。**刻意不启用** `CCR.UNALIGN_TRP` / `CCR.DIV_0_TRP`(会把普通 bug 升级成死机)。⚠️ **ARMCC `__asm` 取不到 C 的数据符号**(`ADR r1, xxx_tag` 报 `A1516E: Bad symbol`,去 static 也无效)且无法传字符串参数 → 故障名必须由 C 侧 per-fault 入口带上,不要在 `__asm` 里取 C 变量 - **`SHCSR` 的 Fault 使能位无法在 CubeMX 配置**(2026-10-01 查模板源码证实):CubeMX 对 System Exception **只生成优先级(且仅当优先级 ≠ 0),从不生成使能代码**——`tpl_main_c.ftl` 的 `MX_NVIC_Init()` 用 `[#if vector.systemHandler=="false"]` 挡住 `HAL_NVIC_EnableIRQ`,而 `NVIC-STM32F417_Modes.xml` 里 `MemoryManagement/BusFault/UsageFault_IRQn` 都标 `Y`(=systemHandler);**全部模板中 `SHCSR` 只出现 1 次**且是 MPU 清理的 `&= ~MEMFAULTENA`(禁用),无任何 `|=` 置位;MPU 路径也堵死(`.ioc` 无 MPU,且 `HAL_MPU_Enable` 只置 `MEMFAULTENA` 一位)。⚠️ **`.ioc` 的 `NVIC.MemoryManagement_IRQn=true` 不代表已使能**(第 1 段只是"向量在 NVIC 表里可见")——别误以为勾了 Enabled 就等于开了故障。结论:只能手工写(现放 `USER CODE BEGIN 1` 区,属 L2,重生成不丢)+ 审计项 `fault-handler-enable` 兜底 - **`MDK-ARM/*.uvprojx` 每次 `@build` 后被 Keil UV4 自动改写,改动一律不入库**(2026-09-29 实测):UV4 构建时会把工程 XML 归一化成它本机风格的旧式写法(`` → ``、XML 声明加 `standalone="no"`),并把 `PackID` 降到**本机装的 DFP 版本**(本机实测 `3.1.1` → `3.0.0`,属**降级**)。这些差异是环境相关的,提交后会把别人的 Pack 版本也一起改掉。**判断方法**:`git diff MDK-ARM/STM32F407-Demo.uvprojx` 里若只见 XML 格式/`PackID` 差异而**无源文件挂载增删** → `git checkout -- MDK-ARM/STM32F407-Demo.uvprojx` 丢弃。只有真的新增/删除源文件(`grep 文件名` 计数变化)才提交 diff --git a/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h b/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h new file mode 100644 index 00000000..c79a073e --- /dev/null +++ b/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h @@ -0,0 +1,898 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_adc.h + * @author MCD Application Team + * @brief Header file containing functions prototypes of ADC HAL library. + ****************************************************************************** + * @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 __STM32F4xx_ADC_H +#define __STM32F4xx_ADC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/* Include low level driver */ +#include "stm32f4xx_ll_adc.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup ADC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ADC_Exported_Types ADC Exported Types + * @{ + */ + +/** + * @brief Structure definition of ADC and regular group initialization + * @note Parameters of this structure are shared within 2 scopes: + * - Scope entire ADC (affects regular and injected groups): ClockPrescaler, Resolution, ScanConvMode, DataAlign, ScanConvMode, EOCSelection, LowPowerAutoWait, LowPowerAutoPowerOff, ChannelsBank. + * - Scope regular group: ContinuousConvMode, NbrOfConversion, DiscontinuousConvMode, NbrOfDiscConversion, ExternalTrigConvEdge, ExternalTrigConv. + * @note The setting of these parameters with function HAL_ADC_Init() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters: ADC disabled + * - For all parameters except 'Resolution', 'ScanConvMode', 'DiscontinuousConvMode', 'NbrOfDiscConversion' : ADC enabled without conversion on going on regular group. + * - For parameters 'ExternalTrigConv' and 'ExternalTrigConvEdge': ADC enabled, even with conversion on going. + * If ADC is not in the appropriate state to modify some parameters, these parameters setting is bypassed + * without error reporting (as it can be the expected behaviour in case of intended action to update another parameter (which fulfills the ADC state condition) on the fly). + */ +typedef struct +{ + uint32_t ClockPrescaler; /*!< Select ADC clock prescaler. The clock is common for + all the ADCs. + This parameter can be a value of @ref ADC_ClockPrescaler */ + uint32_t Resolution; /*!< Configures the ADC resolution. + This parameter can be a value of @ref ADC_Resolution */ + uint32_t DataAlign; /*!< Specifies ADC data alignment to right (MSB on register bit 11 and LSB on register bit 0) (default setting) + or to left (if regular group: MSB on register bit 15 and LSB on register bit 4, if injected group (MSB kept as signed value due to potential negative value after offset application): MSB on register bit 14 and LSB on register bit 3). + This parameter can be a value of @ref ADC_Data_align */ + uint32_t ScanConvMode; /*!< Configures the sequencer of regular and injected groups. + This parameter can be associated to parameter 'DiscontinuousConvMode' to have main sequence subdivided in successive parts. + If disabled: Conversion is performed in single mode (one channel converted, the one defined in rank 1). + Parameters 'NbrOfConversion' and 'InjectedNbrOfConversion' are discarded (equivalent to set to 1). + If enabled: Conversions are performed in sequence mode (multiple ranks defined by 'NbrOfConversion'/'InjectedNbrOfConversion' and each channel rank). + Scan direction is upward: from rank1 to rank 'n'. + This parameter can be set to ENABLE or DISABLE */ + uint32_t EOCSelection; /*!< Specifies what EOC (End Of Conversion) flag is used for conversion by polling and interruption: end of conversion of each rank or complete sequence. + This parameter can be a value of @ref ADC_EOCSelection. + Note: For injected group, end of conversion (flag&IT) is raised only at the end of the sequence. + Therefore, if end of conversion is set to end of each conversion, injected group should not be used with interruption (HAL_ADCEx_InjectedStart_IT) + or polling (HAL_ADCEx_InjectedStart and HAL_ADCEx_InjectedPollForConversion). By the way, polling is still possible since driver will use an estimated timing for end of injected conversion. + Note: If overrun feature is intended to be used, use ADC in mode 'interruption' (function HAL_ADC_Start_IT() ) with parameter EOCSelection set to end of each conversion or in mode 'transfer by DMA' (function HAL_ADC_Start_DMA()). + If overrun feature is intended to be bypassed, use ADC in mode 'polling' or 'interruption' with parameter EOCSelection must be set to end of sequence */ + FunctionalState ContinuousConvMode; /*!< Specifies whether the conversion is performed in single mode (one conversion) or continuous mode for regular group, + after the selected trigger occurred (software start or external trigger). + This parameter can be set to ENABLE or DISABLE. */ + uint32_t NbrOfConversion; /*!< Specifies the number of ranks that will be converted within the regular group sequencer. + To use regular group sequencer and convert several ranks, parameter 'ScanConvMode' must be enabled. + This parameter must be a number between Min_Data = 1 and Max_Data = 16. */ + FunctionalState DiscontinuousConvMode; /*!< Specifies whether the conversions sequence of regular group is performed in Complete-sequence/Discontinuous-sequence (main sequence subdivided in successive parts). + Discontinuous mode is used only if sequencer is enabled (parameter 'ScanConvMode'). If sequencer is disabled, this parameter is discarded. + Discontinuous mode can be enabled only if continuous mode is disabled. If continuous mode is enabled, this parameter setting is discarded. + This parameter can be set to ENABLE or DISABLE. */ + uint32_t NbrOfDiscConversion; /*!< Specifies the number of discontinuous conversions in which the main sequence of regular group (parameter NbrOfConversion) will be subdivided. + If parameter 'DiscontinuousConvMode' is disabled, this parameter is discarded. + This parameter must be a number between Min_Data = 1 and Max_Data = 8. */ + uint32_t ExternalTrigConv; /*!< Selects the external event used to trigger the conversion start of regular group. + If set to ADC_SOFTWARE_START, external triggers are disabled. + If set to external trigger source, triggering is on event rising edge by default. + This parameter can be a value of @ref ADC_External_trigger_Source_Regular */ + uint32_t ExternalTrigConvEdge; /*!< Selects the external trigger edge of regular group. + If trigger is set to ADC_SOFTWARE_START, this parameter is discarded. + This parameter can be a value of @ref ADC_External_trigger_edge_Regular */ + FunctionalState DMAContinuousRequests; /*!< Specifies whether the DMA requests are performed in one shot mode (DMA transfer stop when number of conversions is reached) + or in Continuous mode (DMA transfer unlimited, whatever number of conversions). + Note: In continuous mode, DMA must be configured in circular mode. Otherwise an overrun will be triggered when DMA buffer maximum pointer is reached. + Note: This parameter must be modified when no conversion is on going on both regular and injected groups (ADC disabled, or ADC enabled without continuous mode or external trigger that could launch a conversion). + This parameter can be set to ENABLE or DISABLE. */ +} ADC_InitTypeDef; + + + +/** + * @brief Structure definition of ADC channel for regular group + * @note The setting of these parameters with function HAL_ADC_ConfigChannel() is conditioned to ADC state. + * ADC can be either disabled or enabled without conversion on going on regular group. + */ +typedef struct +{ + uint32_t Channel; /*!< Specifies the channel to configure into ADC regular group. + This parameter can be a value of @ref ADC_channels */ + uint32_t Rank; /*!< Specifies the rank in the regular group sequencer. + This parameter must be a number between Min_Data = 1 and Max_Data = 16 */ + uint32_t SamplingTime; /*!< Sampling time value to be set for the selected channel. + Unit: ADC clock cycles + Conversion time is the addition of sampling time and processing time (12 ADC clock cycles at ADC resolution 12 bits, 11 cycles at 10 bits, 9 cycles at 8 bits, 7 cycles at 6 bits). + This parameter can be a value of @ref ADC_sampling_times + Caution: This parameter updates the parameter property of the channel, that can be used into regular and/or injected groups. + If this same channel has been previously configured in the other group (regular/injected), it will be updated to last setting. + Note: In case of usage of internal measurement channels (VrefInt/Vbat/TempSensor), + sampling time constraints must be respected (sampling time can be adjusted in function of ADC clock frequency and sampling time setting) + Refer to device datasheet for timings values, parameters TS_vrefint, TS_temp (values rough order: 4us min). */ + uint32_t Offset; /*!< Reserved for future use, can be set to 0 */ +} ADC_ChannelConfTypeDef; + +/** + * @brief ADC Configuration multi-mode structure definition + */ +typedef struct +{ + uint32_t WatchdogMode; /*!< Configures the ADC analog watchdog mode. + This parameter can be a value of @ref ADC_analog_watchdog_selection */ + uint32_t HighThreshold; /*!< Configures the ADC analog watchdog High threshold value. + This parameter must be a 12-bit value. */ + uint32_t LowThreshold; /*!< Configures the ADC analog watchdog High threshold value. + This parameter must be a 12-bit value. */ + uint32_t Channel; /*!< Configures ADC channel for the analog watchdog. + This parameter has an effect only if watchdog mode is configured on single channel + This parameter can be a value of @ref ADC_channels */ + FunctionalState ITMode; /*!< Specifies whether the analog watchdog is configured + is interrupt mode or in polling mode. + This parameter can be set to ENABLE or DISABLE */ + uint32_t WatchdogNumber; /*!< Reserved for future use, can be set to 0 */ +} ADC_AnalogWDGConfTypeDef; + +/** + * @brief HAL ADC state machine: ADC states definition (bitfields) + */ +/* States of ADC global scope */ +#define HAL_ADC_STATE_RESET 0x00000000U /*!< ADC not yet initialized or disabled */ +#define HAL_ADC_STATE_READY 0x00000001U /*!< ADC peripheral ready for use */ +#define HAL_ADC_STATE_BUSY_INTERNAL 0x00000002U /*!< ADC is busy to internal process (initialization, calibration) */ +#define HAL_ADC_STATE_TIMEOUT 0x00000004U /*!< TimeOut occurrence */ + +/* States of ADC errors */ +#define HAL_ADC_STATE_ERROR_INTERNAL 0x00000010U /*!< Internal error occurrence */ +#define HAL_ADC_STATE_ERROR_CONFIG 0x00000020U /*!< Configuration error occurrence */ +#define HAL_ADC_STATE_ERROR_DMA 0x00000040U /*!< DMA error occurrence */ + +/* States of ADC group regular */ +#define HAL_ADC_STATE_REG_BUSY 0x00000100U /*!< A conversion on group regular is ongoing or can occur (either by continuous mode, + external trigger, low power auto power-on (if feature available), multimode ADC master control (if feature available)) */ +#define HAL_ADC_STATE_REG_EOC 0x00000200U /*!< Conversion data available on group regular */ +#define HAL_ADC_STATE_REG_OVR 0x00000400U /*!< Overrun occurrence */ + +/* States of ADC group injected */ +#define HAL_ADC_STATE_INJ_BUSY 0x00001000U /*!< A conversion on group injected is ongoing or can occur (either by auto-injection mode, + external trigger, low power auto power-on (if feature available), multimode ADC master control (if feature available)) */ +#define HAL_ADC_STATE_INJ_EOC 0x00002000U /*!< Conversion data available on group injected */ + +/* States of ADC analog watchdogs */ +#define HAL_ADC_STATE_AWD1 0x00010000U /*!< Out-of-window occurrence of analog watchdog 1 */ +#define HAL_ADC_STATE_AWD2 0x00020000U /*!< Not available on STM32F4 device: Out-of-window occurrence of analog watchdog 2 */ +#define HAL_ADC_STATE_AWD3 0x00040000U /*!< Not available on STM32F4 device: Out-of-window occurrence of analog watchdog 3 */ + +/* States of ADC multi-mode */ +#define HAL_ADC_STATE_MULTIMODE_SLAVE 0x00100000U /*!< Not available on STM32F4 device: ADC in multimode slave state, controlled by another ADC master ( */ + + +/** + * @brief ADC handle Structure definition + */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +typedef struct __ADC_HandleTypeDef +#else +typedef struct +#endif +{ + ADC_TypeDef *Instance; /*!< Register base address */ + + ADC_InitTypeDef Init; /*!< ADC required parameters */ + + __IO uint32_t NbrOfCurrentConversionRank; /*!< ADC number of current conversion rank */ + + DMA_HandleTypeDef *DMA_Handle; /*!< Pointer DMA Handler */ + + HAL_LockTypeDef Lock; /*!< ADC locking object */ + + __IO uint32_t State; /*!< ADC communication state */ + + __IO uint32_t ErrorCode; /*!< ADC Error code */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + void (* ConvCpltCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC conversion complete callback */ + void (* ConvHalfCpltCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC conversion DMA half-transfer callback */ + void (* LevelOutOfWindowCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC analog watchdog 1 callback */ + void (* ErrorCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC error callback */ + void (* InjectedConvCpltCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC group injected conversion complete callback */ + void (* MspInitCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC Msp Init callback */ + void (* MspDeInitCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC Msp DeInit callback */ +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ +} ADC_HandleTypeDef; + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +/** + * @brief HAL ADC Callback ID enumeration definition + */ +typedef enum +{ + HAL_ADC_CONVERSION_COMPLETE_CB_ID = 0x00U, /*!< ADC conversion complete callback ID */ + HAL_ADC_CONVERSION_HALF_CB_ID = 0x01U, /*!< ADC conversion DMA half-transfer callback ID */ + HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID = 0x02U, /*!< ADC analog watchdog 1 callback ID */ + HAL_ADC_ERROR_CB_ID = 0x03U, /*!< ADC error callback ID */ + HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID = 0x04U, /*!< ADC group injected conversion complete callback ID */ + HAL_ADC_MSPINIT_CB_ID = 0x05U, /*!< ADC Msp Init callback ID */ + HAL_ADC_MSPDEINIT_CB_ID = 0x06U /*!< ADC Msp DeInit callback ID */ +} HAL_ADC_CallbackIDTypeDef; + +/** + * @brief HAL ADC Callback pointer definition + */ +typedef void (*pADC_CallbackTypeDef)(ADC_HandleTypeDef *hadc); /*!< pointer to a ADC callback function */ + +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ADC_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup ADC_Error_Code ADC Error Code + * @{ + */ +#define HAL_ADC_ERROR_NONE 0x00U /*!< No error */ +#define HAL_ADC_ERROR_INTERNAL 0x01U /*!< ADC IP internal error: if problem of clocking, + enable/disable, erroneous state */ +#define HAL_ADC_ERROR_OVR 0x02U /*!< Overrun error */ +#define HAL_ADC_ERROR_DMA 0x04U /*!< DMA transfer error */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +#define HAL_ADC_ERROR_INVALID_CALLBACK (0x10U) /*!< Invalid Callback error */ +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ +/** + * @} + */ + + +/** @defgroup ADC_ClockPrescaler ADC Clock Prescaler + * @{ + */ +#define ADC_CLOCK_SYNC_PCLK_DIV2 0x00000000U +#define ADC_CLOCK_SYNC_PCLK_DIV4 ((uint32_t)ADC_CCR_ADCPRE_0) +#define ADC_CLOCK_SYNC_PCLK_DIV6 ((uint32_t)ADC_CCR_ADCPRE_1) +#define ADC_CLOCK_SYNC_PCLK_DIV8 ((uint32_t)ADC_CCR_ADCPRE) +/** + * @} + */ + +/** @defgroup ADC_delay_between_2_sampling_phases ADC Delay Between 2 Sampling Phases + * @{ + */ +#define ADC_TWOSAMPLINGDELAY_5CYCLES 0x00000000U +#define ADC_TWOSAMPLINGDELAY_6CYCLES ((uint32_t)ADC_CCR_DELAY_0) +#define ADC_TWOSAMPLINGDELAY_7CYCLES ((uint32_t)ADC_CCR_DELAY_1) +#define ADC_TWOSAMPLINGDELAY_8CYCLES ((uint32_t)(ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_9CYCLES ((uint32_t)ADC_CCR_DELAY_2) +#define ADC_TWOSAMPLINGDELAY_10CYCLES ((uint32_t)(ADC_CCR_DELAY_2 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_11CYCLES ((uint32_t)(ADC_CCR_DELAY_2 | ADC_CCR_DELAY_1)) +#define ADC_TWOSAMPLINGDELAY_12CYCLES ((uint32_t)(ADC_CCR_DELAY_2 | ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_13CYCLES ((uint32_t)ADC_CCR_DELAY_3) +#define ADC_TWOSAMPLINGDELAY_14CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_15CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_1)) +#define ADC_TWOSAMPLINGDELAY_16CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_17CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_2)) +#define ADC_TWOSAMPLINGDELAY_18CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_2 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_19CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_2 | ADC_CCR_DELAY_1)) +#define ADC_TWOSAMPLINGDELAY_20CYCLES ((uint32_t)ADC_CCR_DELAY) +/** + * @} + */ + +/** @defgroup ADC_Resolution ADC Resolution + * @{ + */ +#define ADC_RESOLUTION_12B 0x00000000U +#define ADC_RESOLUTION_10B ((uint32_t)ADC_CR1_RES_0) +#define ADC_RESOLUTION_8B ((uint32_t)ADC_CR1_RES_1) +#define ADC_RESOLUTION_6B ((uint32_t)ADC_CR1_RES) +/** + * @} + */ + +/** @defgroup ADC_External_trigger_edge_Regular ADC External Trigger Edge Regular + * @{ + */ +#define ADC_EXTERNALTRIGCONVEDGE_NONE 0x00000000U +#define ADC_EXTERNALTRIGCONVEDGE_RISING ((uint32_t)ADC_CR2_EXTEN_0) +#define ADC_EXTERNALTRIGCONVEDGE_FALLING ((uint32_t)ADC_CR2_EXTEN_1) +#define ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING ((uint32_t)ADC_CR2_EXTEN) +/** + * @} + */ + +/** @defgroup ADC_External_trigger_Source_Regular ADC External Trigger Source Regular + * @{ + */ +/* Note: Parameter ADC_SOFTWARE_START is a software parameter used for */ +/* compatibility with other STM32 devices. */ +#define ADC_EXTERNALTRIGCONV_T1_CC1 0x00000000U +#define ADC_EXTERNALTRIGCONV_T1_CC2 ((uint32_t)ADC_CR2_EXTSEL_0) +#define ADC_EXTERNALTRIGCONV_T1_CC3 ((uint32_t)ADC_CR2_EXTSEL_1) +#define ADC_EXTERNALTRIGCONV_T2_CC2 ((uint32_t)(ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T2_CC3 ((uint32_t)ADC_CR2_EXTSEL_2) +#define ADC_EXTERNALTRIGCONV_T2_CC4 ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T2_TRGO ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1)) +#define ADC_EXTERNALTRIGCONV_T3_CC1 ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T3_TRGO ((uint32_t)ADC_CR2_EXTSEL_3) +#define ADC_EXTERNALTRIGCONV_T4_CC4 ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T5_CC1 ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_1)) +#define ADC_EXTERNALTRIGCONV_T5_CC2 ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T5_CC3 ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2)) +#define ADC_EXTERNALTRIGCONV_T8_CC1 ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T8_TRGO ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1)) +#define ADC_EXTERNALTRIGCONV_Ext_IT11 ((uint32_t)ADC_CR2_EXTSEL) +#define ADC_SOFTWARE_START ((uint32_t)ADC_CR2_EXTSEL + 1U) +/** + * @} + */ + +/** @defgroup ADC_Data_align ADC Data Align + * @{ + */ +#define ADC_DATAALIGN_RIGHT 0x00000000U +#define ADC_DATAALIGN_LEFT ((uint32_t)ADC_CR2_ALIGN) +/** + * @} + */ + +/** @defgroup ADC_channels ADC Common Channels + * @{ + */ +#define ADC_CHANNEL_0 0x00000000U +#define ADC_CHANNEL_1 ((uint32_t)ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_2 ((uint32_t)ADC_CR1_AWDCH_1) +#define ADC_CHANNEL_3 ((uint32_t)(ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_4 ((uint32_t)ADC_CR1_AWDCH_2) +#define ADC_CHANNEL_5 ((uint32_t)(ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_6 ((uint32_t)(ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1)) +#define ADC_CHANNEL_7 ((uint32_t)(ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_8 ((uint32_t)ADC_CR1_AWDCH_3) +#define ADC_CHANNEL_9 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_10 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_1)) +#define ADC_CHANNEL_11 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_12 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2)) +#define ADC_CHANNEL_13 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_14 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1)) +#define ADC_CHANNEL_15 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_16 ((uint32_t)ADC_CR1_AWDCH_4) +#define ADC_CHANNEL_17 ((uint32_t)(ADC_CR1_AWDCH_4 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_18 ((uint32_t)(ADC_CR1_AWDCH_4 | ADC_CR1_AWDCH_1)) + +#define ADC_CHANNEL_VREFINT ((uint32_t)ADC_CHANNEL_17) +#define ADC_CHANNEL_VBAT ((uint32_t)ADC_CHANNEL_18) +/** + * @} + */ + +/** @defgroup ADC_sampling_times ADC Sampling Times + * @{ + */ +#define ADC_SAMPLETIME_3CYCLES 0x00000000U +#define ADC_SAMPLETIME_15CYCLES ((uint32_t)ADC_SMPR1_SMP10_0) +#define ADC_SAMPLETIME_28CYCLES ((uint32_t)ADC_SMPR1_SMP10_1) +#define ADC_SAMPLETIME_56CYCLES ((uint32_t)(ADC_SMPR1_SMP10_1 | ADC_SMPR1_SMP10_0)) +#define ADC_SAMPLETIME_84CYCLES ((uint32_t)ADC_SMPR1_SMP10_2) +#define ADC_SAMPLETIME_112CYCLES ((uint32_t)(ADC_SMPR1_SMP10_2 | ADC_SMPR1_SMP10_0)) +#define ADC_SAMPLETIME_144CYCLES ((uint32_t)(ADC_SMPR1_SMP10_2 | ADC_SMPR1_SMP10_1)) +#define ADC_SAMPLETIME_480CYCLES ((uint32_t)ADC_SMPR1_SMP10) +/** + * @} + */ + +/** @defgroup ADC_EOCSelection ADC EOC Selection + * @{ + */ +#define ADC_EOC_SEQ_CONV 0x00000000U +#define ADC_EOC_SINGLE_CONV 0x00000001U +#define ADC_EOC_SINGLE_SEQ_CONV 0x00000002U /*!< reserved for future use */ +/** + * @} + */ + +/** @defgroup ADC_Event_type ADC Event Type + * @{ + */ +#define ADC_AWD_EVENT ((uint32_t)ADC_FLAG_AWD) +#define ADC_OVR_EVENT ((uint32_t)ADC_FLAG_OVR) +/** + * @} + */ + +/** @defgroup ADC_analog_watchdog_selection ADC Analog Watchdog Selection + * @{ + */ +#define ADC_ANALOGWATCHDOG_SINGLE_REG ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_AWDEN)) +#define ADC_ANALOGWATCHDOG_SINGLE_INJEC ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_JAWDEN)) +#define ADC_ANALOGWATCHDOG_SINGLE_REGINJEC ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_AWDEN | ADC_CR1_JAWDEN)) +#define ADC_ANALOGWATCHDOG_ALL_REG ((uint32_t)ADC_CR1_AWDEN) +#define ADC_ANALOGWATCHDOG_ALL_INJEC ((uint32_t)ADC_CR1_JAWDEN) +#define ADC_ANALOGWATCHDOG_ALL_REGINJEC ((uint32_t)(ADC_CR1_AWDEN | ADC_CR1_JAWDEN)) +#define ADC_ANALOGWATCHDOG_NONE 0x00000000U +/** + * @} + */ + +/** @defgroup ADC_interrupts_definition ADC Interrupts Definition + * @{ + */ +#define ADC_IT_EOC ((uint32_t)ADC_CR1_EOCIE) +#define ADC_IT_AWD ((uint32_t)ADC_CR1_AWDIE) +#define ADC_IT_JEOC ((uint32_t)ADC_CR1_JEOCIE) +#define ADC_IT_OVR ((uint32_t)ADC_CR1_OVRIE) +/** + * @} + */ + +/** @defgroup ADC_flags_definition ADC Flags Definition + * @{ + */ +#define ADC_FLAG_AWD ((uint32_t)ADC_SR_AWD) +#define ADC_FLAG_EOC ((uint32_t)ADC_SR_EOC) +#define ADC_FLAG_JEOC ((uint32_t)ADC_SR_JEOC) +#define ADC_FLAG_JSTRT ((uint32_t)ADC_SR_JSTRT) +#define ADC_FLAG_STRT ((uint32_t)ADC_SR_STRT) +#define ADC_FLAG_OVR ((uint32_t)ADC_SR_OVR) +/** + * @} + */ + +/** @defgroup ADC_channels_type ADC Channels Type + * @{ + */ +#define ADC_ALL_CHANNELS 0x00000001U +#define ADC_REGULAR_CHANNELS 0x00000002U /*!< reserved for future use */ +#define ADC_INJECTED_CHANNELS 0x00000003U /*!< reserved for future use */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ADC_Exported_Macros ADC Exported Macros + * @{ + */ + +/** @brief Reset ADC handle state + * @param __HANDLE__ ADC handle + * @retval None + */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +#define __HAL_ADC_RESET_HANDLE_STATE(__HANDLE__) \ + do{ \ + (__HANDLE__)->State = HAL_ADC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_ADC_RESET_HANDLE_STATE(__HANDLE__) \ + ((__HANDLE__)->State = HAL_ADC_STATE_RESET) +#endif + +/** + * @brief Enable the ADC peripheral. + * @param __HANDLE__ ADC handle + * @retval None + */ +#define __HAL_ADC_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR2 |= ADC_CR2_ADON) + +/** + * @brief Disable the ADC peripheral. + * @param __HANDLE__ ADC handle + * @retval None + */ +#define __HAL_ADC_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= ~ADC_CR2_ADON) + +/** + * @brief Enable the ADC end of conversion interrupt. + * @param __HANDLE__ specifies the ADC Handle. + * @param __INTERRUPT__ ADC Interrupt. + * @retval None + */ +#define __HAL_ADC_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR1) |= (__INTERRUPT__)) + +/** + * @brief Disable the ADC end of conversion interrupt. + * @param __HANDLE__ specifies the ADC Handle. + * @param __INTERRUPT__ ADC interrupt. + * @retval None + */ +#define __HAL_ADC_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR1) &= ~(__INTERRUPT__)) + +/** @brief Check if the specified ADC interrupt source is enabled or disabled. + * @param __HANDLE__ specifies the ADC Handle. + * @param __INTERRUPT__ specifies the ADC interrupt source to check. + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_ADC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Clear the ADC's pending flags. + * @param __HANDLE__ specifies the ADC Handle. + * @param __FLAG__ ADC flag. + * @retval None + */ +#define __HAL_ADC_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR) = ~(__FLAG__)) + +/** + * @brief Get the selected ADC's flag status. + * @param __HANDLE__ specifies the ADC Handle. + * @param __FLAG__ ADC flag. + * @retval None + */ +#define __HAL_ADC_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** + * @} + */ + +/* Include ADC HAL Extension module */ +#include "stm32f4xx_hal_adc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADC_Exported_Functions + * @{ + */ + +/** @addtogroup ADC_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions ***********************************/ +HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc); +void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc); +void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc); + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +/* Callbacks Register/UnRegister functions ***********************************/ +HAL_StatusTypeDef HAL_ADC_RegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID, pADC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_ADC_UnRegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup ADC_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ******************************************************/ +HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout); + +HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef *hadc, uint32_t EventType, uint32_t Timeout); + +HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef *hadc); + +void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc); + +HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length); +HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef *hadc); + +uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc); + +void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc); +void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc); +void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef *hadc); +void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc); +/** + * @} + */ + +/** @addtogroup ADC_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions *************************************************/ +HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConfTypeDef *sConfig); +HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, ADC_AnalogWDGConfTypeDef *AnalogWDGConfig); +/** + * @} + */ + +/** @addtogroup ADC_Exported_Functions_Group4 + * @{ + */ +/* Peripheral State functions ***************************************************/ +uint32_t HAL_ADC_GetState(ADC_HandleTypeDef *hadc); +uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup ADC_Private_Constants ADC Private Constants + * @{ + */ +/* Delay for ADC stabilization time. */ +/* Maximum delay is 1us (refer to device datasheet, parameter tSTAB). */ +/* Unit: us */ +#define ADC_STAB_DELAY_US 3U +/* Delay for temperature sensor stabilization time. */ +/* Maximum delay is 10us (refer to device datasheet, parameter tSTART). */ +/* Unit: us */ +#define ADC_TEMPSENSOR_DELAY_US 10U +/** + * @} + */ + +/* Private macro ------------------------------------------------------------*/ + +/** @defgroup ADC_Private_Macros ADC Private Macros + * @{ + */ +/* Macro reserved for internal HAL driver usage, not intended to be used in + code of final user */ + +/** + * @brief Verification of ADC state: enabled or disabled + * @param __HANDLE__ ADC handle + * @retval SET (ADC enabled) or RESET (ADC disabled) + */ +#define ADC_IS_ENABLE(__HANDLE__) \ + ((( ((__HANDLE__)->Instance->SR & ADC_SR_ADONS) == ADC_SR_ADONS ) \ + ) ? SET : RESET) + +/** + * @brief Test if conversion trigger of regular group is software start + * or external trigger. + * @param __HANDLE__ ADC handle + * @retval SET (software start) or RESET (external trigger) + */ +#define ADC_IS_SOFTWARE_START_REGULAR(__HANDLE__) \ + (((__HANDLE__)->Instance->CR2 & ADC_CR2_EXTEN) == RESET) + +/** + * @brief Test if conversion trigger of injected group is software start + * or external trigger. + * @param __HANDLE__ ADC handle + * @retval SET (software start) or RESET (external trigger) + */ +#define ADC_IS_SOFTWARE_START_INJECTED(__HANDLE__) \ + (((__HANDLE__)->Instance->CR2 & ADC_CR2_JEXTEN) == RESET) + +/** + * @brief Simultaneously clears and sets specific bits of the handle State + * @note: ADC_STATE_CLR_SET() macro is merely aliased to generic macro MODIFY_REG(), + * the first parameter is the ADC handle State, the second parameter is the + * bit field to clear, the third and last parameter is the bit field to set. + * @retval None + */ +#define ADC_STATE_CLR_SET MODIFY_REG + +/** + * @brief Clear ADC error code (set it to error code: "no error") + * @param __HANDLE__ ADC handle + * @retval None + */ +#define ADC_CLEAR_ERRORCODE(__HANDLE__) \ + ((__HANDLE__)->ErrorCode = HAL_ADC_ERROR_NONE) + + +#define IS_ADC_CLOCKPRESCALER(ADC_CLOCK) (((ADC_CLOCK) == ADC_CLOCK_SYNC_PCLK_DIV2) || \ + ((ADC_CLOCK) == ADC_CLOCK_SYNC_PCLK_DIV4) || \ + ((ADC_CLOCK) == ADC_CLOCK_SYNC_PCLK_DIV6) || \ + ((ADC_CLOCK) == ADC_CLOCK_SYNC_PCLK_DIV8)) +#define IS_ADC_SAMPLING_DELAY(DELAY) (((DELAY) == ADC_TWOSAMPLINGDELAY_5CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_6CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_7CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_8CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_9CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_10CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_11CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_12CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_13CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_14CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_15CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_16CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_17CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_18CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_19CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_20CYCLES)) +#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_RESOLUTION_12B) || \ + ((RESOLUTION) == ADC_RESOLUTION_10B) || \ + ((RESOLUTION) == ADC_RESOLUTION_8B) || \ + ((RESOLUTION) == ADC_RESOLUTION_6B)) +#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_EXTERNALTRIGCONVEDGE_NONE) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISING) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_FALLING) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING)) +#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC3) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC3) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC3) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_Ext_IT11)|| \ + ((REGTRIG) == ADC_SOFTWARE_START)) +#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DATAALIGN_RIGHT) || \ + ((ALIGN) == ADC_DATAALIGN_LEFT)) +#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SAMPLETIME_3CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_15CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_28CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_56CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_84CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_112CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_144CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_480CYCLES)) +#define IS_ADC_EOCSelection(EOCSelection) (((EOCSelection) == ADC_EOC_SINGLE_CONV) || \ + ((EOCSelection) == ADC_EOC_SEQ_CONV) || \ + ((EOCSelection) == ADC_EOC_SINGLE_SEQ_CONV)) +#define IS_ADC_EVENT_TYPE(EVENT) (((EVENT) == ADC_AWD_EVENT) || \ + ((EVENT) == ADC_OVR_EVENT)) +#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REG) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_INJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REG) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_INJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REGINJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_NONE)) +#define IS_ADC_CHANNELS_TYPE(CHANNEL_TYPE) (((CHANNEL_TYPE) == ADC_ALL_CHANNELS) || \ + ((CHANNEL_TYPE) == ADC_REGULAR_CHANNELS) || \ + ((CHANNEL_TYPE) == ADC_INJECTED_CHANNELS)) +#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFFU) + +#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 1U) && ((LENGTH) <= 16U)) +#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 1U) && ((RANK) <= (16U))) +#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 1U) && ((NUMBER) <= 8U)) +#define IS_ADC_RANGE(RESOLUTION, ADC_VALUE) \ + ((((RESOLUTION) == ADC_RESOLUTION_12B) && ((ADC_VALUE) <= 0x0FFFU)) || \ + (((RESOLUTION) == ADC_RESOLUTION_10B) && ((ADC_VALUE) <= 0x03FFU)) || \ + (((RESOLUTION) == ADC_RESOLUTION_8B) && ((ADC_VALUE) <= 0x00FFU)) || \ + (((RESOLUTION) == ADC_RESOLUTION_6B) && ((ADC_VALUE) <= 0x003FU))) + +/** + * @brief Set ADC Regular channel sequence length. + * @param _NbrOfConversion_ Regular channel sequence length. + * @retval None + */ +#define ADC_SQR1(_NbrOfConversion_) (((_NbrOfConversion_) - (uint8_t)1U) << 20U) + +/** + * @brief Set the ADC's sample time for channel numbers between 10 and 18. + * @param _SAMPLETIME_ Sample time parameter. + * @param _CHANNELNB_ Channel number. + * @retval None + */ +#define ADC_SMPR1(_SAMPLETIME_, _CHANNELNB_) ((_SAMPLETIME_) << (3U * (((uint32_t)((uint16_t)(_CHANNELNB_))) - 10U))) + +/** + * @brief Set the ADC's sample time for channel numbers between 0 and 9. + * @param _SAMPLETIME_ Sample time parameter. + * @param _CHANNELNB_ Channel number. + * @retval None + */ +#define ADC_SMPR2(_SAMPLETIME_, _CHANNELNB_) ((_SAMPLETIME_) << (3U * ((uint32_t)((uint16_t)(_CHANNELNB_))))) + +/** + * @brief Set the selected regular channel rank for rank between 1 and 6. + * @param _CHANNELNB_ Channel number. + * @param _RANKNB_ Rank number. + * @retval None + */ +#define ADC_SQR3_RK(_CHANNELNB_, _RANKNB_) (((uint32_t)((uint16_t)(_CHANNELNB_))) << (5U * ((_RANKNB_) - 1U))) + +/** + * @brief Set the selected regular channel rank for rank between 7 and 12. + * @param _CHANNELNB_ Channel number. + * @param _RANKNB_ Rank number. + * @retval None + */ +#define ADC_SQR2_RK(_CHANNELNB_, _RANKNB_) (((uint32_t)((uint16_t)(_CHANNELNB_))) << (5U * ((_RANKNB_) - 7U))) + +/** + * @brief Set the selected regular channel rank for rank between 13 and 16. + * @param _CHANNELNB_ Channel number. + * @param _RANKNB_ Rank number. + * @retval None + */ +#define ADC_SQR1_RK(_CHANNELNB_, _RANKNB_) (((uint32_t)((uint16_t)(_CHANNELNB_))) << (5U * ((_RANKNB_) - 13U))) + +/** + * @brief Enable ADC continuous conversion mode. + * @param _CONTINUOUS_MODE_ Continuous mode. + * @retval None + */ +#define ADC_CR2_CONTINUOUS(_CONTINUOUS_MODE_) ((_CONTINUOUS_MODE_) << 1U) + +/** + * @brief Configures the number of discontinuous conversions for the regular group channels. + * @param _NBR_DISCONTINUOUSCONV_ Number of discontinuous conversions. + * @retval None + */ +#define ADC_CR1_DISCONTINUOUS(_NBR_DISCONTINUOUSCONV_) (((_NBR_DISCONTINUOUSCONV_) - 1U) << ADC_CR1_DISCNUM_Pos) + +/** + * @brief Enable ADC scan mode. + * @param _SCANCONV_MODE_ Scan conversion mode. + * @retval None + */ +#define ADC_CR1_SCANCONV(_SCANCONV_MODE_) ((_SCANCONV_MODE_) << 8U) + +/** + * @brief Enable the ADC end of conversion selection. + * @param _EOCSelection_MODE_ End of conversion selection mode. + * @retval None + */ +#define ADC_CR2_EOCSelection(_EOCSelection_MODE_) ((_EOCSelection_MODE_) << 10U) + +/** + * @brief Enable the ADC DMA continuous request. + * @param _DMAContReq_MODE_ DMA continuous request mode. + * @retval None + */ +#define ADC_CR2_DMAContReq(_DMAContReq_MODE_) ((_DMAContReq_MODE_) << 9U) + +/** + * @brief Return resolution bits in CR1 register. + * @param __HANDLE__ ADC handle + * @retval None + */ +#define ADC_GET_RESOLUTION(__HANDLE__) (((__HANDLE__)->Instance->CR1) & ADC_CR1_RES) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup ADC_Private_Functions ADC Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_ADC_H */ + + diff --git a/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h b/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h new file mode 100644 index 00000000..8ce8484d --- /dev/null +++ b/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h @@ -0,0 +1,407 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_adc_ex.h + * @author MCD Application Team + * @brief Header file of ADC 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 __STM32F4xx_ADC_EX_H +#define __STM32F4xx_ADC_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup ADCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ADCEx_Exported_Types ADC Exported Types + * @{ + */ + +/** + * @brief ADC Configuration injected Channel structure definition + * @note Parameters of this structure are shared within 2 scopes: + * - Scope channel: InjectedChannel, InjectedRank, InjectedSamplingTime, InjectedOffset + * - Scope injected group (affects all channels of injected group): InjectedNbrOfConversion, InjectedDiscontinuousConvMode, + * AutoInjectedConv, ExternalTrigInjecConvEdge, ExternalTrigInjecConv. + * @note The setting of these parameters with function HAL_ADCEx_InjectedConfigChannel() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters: ADC disabled + * - For all except parameters 'InjectedDiscontinuousConvMode' and 'AutoInjectedConv': ADC enabled without conversion on going on injected group. + * - For parameters 'ExternalTrigInjecConv' and 'ExternalTrigInjecConvEdge': ADC enabled, even with conversion on going on injected group. + */ +typedef struct +{ + uint32_t InjectedChannel; /*!< Selection of ADC channel to configure + This parameter can be a value of @ref ADC_channels + Note: Depending on devices, some channels may not be available on package pins. Refer to device datasheet for channels availability. */ + uint32_t InjectedRank; /*!< Rank in the injected group sequencer + This parameter must be a value of @ref ADCEx_injected_rank + Note: In case of need to disable a channel or change order of conversion sequencer, rank containing a previous channel setting can be overwritten by the new channel setting (or parameter number of conversions can be adjusted) */ + uint32_t InjectedSamplingTime; /*!< Sampling time value to be set for the selected channel. + Unit: ADC clock cycles + Conversion time is the addition of sampling time and processing time (12 ADC clock cycles at ADC resolution 12 bits, 11 cycles at 10 bits, 9 cycles at 8 bits, 7 cycles at 6 bits). + This parameter can be a value of @ref ADC_sampling_times + Caution: This parameter updates the parameter property of the channel, that can be used into regular and/or injected groups. + If this same channel has been previously configured in the other group (regular/injected), it will be updated to last setting. + Note: In case of usage of internal measurement channels (VrefInt/Vbat/TempSensor), + sampling time constraints must be respected (sampling time can be adjusted in function of ADC clock frequency and sampling time setting) + Refer to device datasheet for timings values, parameters TS_vrefint, TS_temp (values rough order: 4us min). */ + uint32_t InjectedOffset; /*!< Defines the offset to be subtracted from the raw converted data (for channels set on injected group only). + Offset value must be a positive number. + Depending of ADC resolution selected (12, 10, 8 or 6 bits), + this parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F respectively. */ + uint32_t InjectedNbrOfConversion; /*!< Specifies the number of ranks that will be converted within the injected group sequencer. + To use the injected group sequencer and convert several ranks, parameter 'ScanConvMode' must be enabled. + This parameter must be a number between Min_Data = 1 and Max_Data = 4. + Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to + configure a channel on injected group can impact the configuration of other channels previously set. */ + FunctionalState InjectedDiscontinuousConvMode; /*!< Specifies whether the conversions sequence of injected group is performed in Complete-sequence/Discontinuous-sequence (main sequence subdivided in successive parts). + Discontinuous mode is used only if sequencer is enabled (parameter 'ScanConvMode'). If sequencer is disabled, this parameter is discarded. + Discontinuous mode can be enabled only if continuous mode is disabled. If continuous mode is enabled, this parameter setting is discarded. + This parameter can be set to ENABLE or DISABLE. + Note: For injected group, number of discontinuous ranks increment is fixed to one-by-one. + Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to + configure a channel on injected group can impact the configuration of other channels previously set. */ + FunctionalState AutoInjectedConv; /*!< Enables or disables the selected ADC automatic injected group conversion after regular one + This parameter can be set to ENABLE or DISABLE. + Note: To use Automatic injected conversion, discontinuous mode must be disabled ('DiscontinuousConvMode' and 'InjectedDiscontinuousConvMode' set to DISABLE) + Note: To use Automatic injected conversion, injected group external triggers must be disabled ('ExternalTrigInjecConv' set to ADC_SOFTWARE_START) + Note: In case of DMA used with regular group: if DMA configured in normal mode (single shot) JAUTO will be stopped upon DMA transfer complete. + To maintain JAUTO always enabled, DMA must be configured in circular mode. + Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to + configure a channel on injected group can impact the configuration of other channels previously set. */ + uint32_t ExternalTrigInjecConv; /*!< Selects the external event used to trigger the conversion start of injected group. + If set to ADC_INJECTED_SOFTWARE_START, external triggers are disabled. + If set to external trigger source, triggering is on event rising edge. + This parameter can be a value of @ref ADCEx_External_trigger_Source_Injected + Note: This parameter must be modified when ADC is disabled (before ADC start conversion or after ADC stop conversion). + If ADC is enabled, this parameter setting is bypassed without error reporting (as it can be the expected behaviour in case of another parameter update on the fly) + Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to + configure a channel on injected group can impact the configuration of other channels previously set. */ + uint32_t ExternalTrigInjecConvEdge; /*!< Selects the external trigger edge of injected group. + This parameter can be a value of @ref ADCEx_External_trigger_edge_Injected. + If trigger is set to ADC_INJECTED_SOFTWARE_START, this parameter is discarded. + Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to + configure a channel on injected group can impact the configuration of other channels previously set. */ +} ADC_InjectionConfTypeDef; + +/** + * @brief ADC Configuration multi-mode structure definition + */ +typedef struct +{ + uint32_t Mode; /*!< Configures the ADC to operate in independent or multi mode. + This parameter can be a value of @ref ADCEx_Common_mode */ + uint32_t DMAAccessMode; /*!< Configures the Direct memory access mode for multi ADC mode. + This parameter can be a value of @ref ADCEx_Direct_memory_access_mode_for_multi_mode */ + uint32_t TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases. + This parameter can be a value of @ref ADC_delay_between_2_sampling_phases */ +} ADC_MultiModeTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ADCEx_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup ADCEx_Common_mode ADC Common Mode + * @{ + */ +#define ADC_MODE_INDEPENDENT 0x00000000U +#define ADC_DUALMODE_REGSIMULT_INJECSIMULT ((uint32_t)ADC_CCR_MULTI_0) +#define ADC_DUALMODE_REGSIMULT_ALTERTRIG ((uint32_t)ADC_CCR_MULTI_1) +#define ADC_DUALMODE_INJECSIMULT ((uint32_t)(ADC_CCR_MULTI_2 | ADC_CCR_MULTI_0)) +#define ADC_DUALMODE_REGSIMULT ((uint32_t)(ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1)) +#define ADC_DUALMODE_INTERL ((uint32_t)(ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1 | ADC_CCR_MULTI_0)) +#define ADC_DUALMODE_ALTERTRIG ((uint32_t)(ADC_CCR_MULTI_3 | ADC_CCR_MULTI_0)) +#define ADC_TRIPLEMODE_REGSIMULT_INJECSIMULT ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_0)) +#define ADC_TRIPLEMODE_REGSIMULT_AlterTrig ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_1)) +#define ADC_TRIPLEMODE_INJECSIMULT ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_2 | ADC_CCR_MULTI_0)) +#define ADC_TRIPLEMODE_REGSIMULT ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1)) +#define ADC_TRIPLEMODE_INTERL ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1 | ADC_CCR_MULTI_0)) +#define ADC_TRIPLEMODE_ALTERTRIG ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_3 | ADC_CCR_MULTI_0)) +/** + * @} + */ + +/** @defgroup ADCEx_Direct_memory_access_mode_for_multi_mode ADC Direct Memory Access Mode For Multi Mode + * @{ + */ +#define ADC_DMAACCESSMODE_DISABLED 0x00000000U /*!< DMA mode disabled */ +#define ADC_DMAACCESSMODE_1 ((uint32_t)ADC_CCR_DMA_0) /*!< DMA mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)*/ +#define ADC_DMAACCESSMODE_2 ((uint32_t)ADC_CCR_DMA_1) /*!< DMA mode 2 enabled (2 / 3 half-words by pairs - 2&1 then 1&3 then 3&2)*/ +#define ADC_DMAACCESSMODE_3 ((uint32_t)ADC_CCR_DMA) /*!< DMA mode 3 enabled (2 / 3 bytes by pairs - 2&1 then 1&3 then 3&2) */ +/** + * @} + */ + +/** @defgroup ADCEx_External_trigger_edge_Injected ADC External Trigger Edge Injected + * @{ + */ +#define ADC_EXTERNALTRIGINJECCONVEDGE_NONE 0x00000000U +#define ADC_EXTERNALTRIGINJECCONVEDGE_RISING ((uint32_t)ADC_CR2_JEXTEN_0) +#define ADC_EXTERNALTRIGINJECCONVEDGE_FALLING ((uint32_t)ADC_CR2_JEXTEN_1) +#define ADC_EXTERNALTRIGINJECCONVEDGE_RISINGFALLING ((uint32_t)ADC_CR2_JEXTEN) +/** + * @} + */ + +/** @defgroup ADCEx_External_trigger_Source_Injected ADC External Trigger Source Injected + * @{ + */ +#define ADC_EXTERNALTRIGINJECCONV_T1_CC4 0x00000000U +#define ADC_EXTERNALTRIGINJECCONV_T1_TRGO ((uint32_t)ADC_CR2_JEXTSEL_0) +#define ADC_EXTERNALTRIGINJECCONV_T2_CC1 ((uint32_t)ADC_CR2_JEXTSEL_1) +#define ADC_EXTERNALTRIGINJECCONV_T2_TRGO ((uint32_t)(ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T3_CC2 ((uint32_t)ADC_CR2_JEXTSEL_2) +#define ADC_EXTERNALTRIGINJECCONV_T3_CC4 ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T4_CC1 ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1)) +#define ADC_EXTERNALTRIGINJECCONV_T4_CC2 ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T4_CC3 ((uint32_t)ADC_CR2_JEXTSEL_3) +#define ADC_EXTERNALTRIGINJECCONV_T4_TRGO ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T5_CC4 ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_1)) +#define ADC_EXTERNALTRIGINJECCONV_T5_TRGO ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T8_CC2 ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_2)) +#define ADC_EXTERNALTRIGINJECCONV_T8_CC3 ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T8_CC4 ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1)) +#define ADC_EXTERNALTRIGINJECCONV_EXT_IT15 ((uint32_t)ADC_CR2_JEXTSEL) +#define ADC_INJECTED_SOFTWARE_START ((uint32_t)ADC_CR2_JEXTSEL + 1U) +/** + * @} + */ + +/** @defgroup ADCEx_injected_rank ADC Injected Rank + * @{ + */ +#define ADC_INJECTED_RANK_1 0x00000001U +#define ADC_INJECTED_RANK_2 0x00000002U +#define ADC_INJECTED_RANK_3 0x00000003U +#define ADC_INJECTED_RANK_4 0x00000004U +/** + * @} + */ + +/** @defgroup ADCEx_channels ADC Specific Channels + * @{ + */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F410Tx) || defined(STM32F410Cx) || \ + defined(STM32F410Rx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || \ + defined(STM32F412Cx) +#define ADC_CHANNEL_TEMPSENSOR ((uint32_t)ADC_CHANNEL_16) +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F410xx || STM32F412Zx || + STM32F412Vx || STM32F412Rx || STM32F412Cx */ + +#if defined(STM32F411xE) || defined(STM32F413xx) || defined(STM32F423xx) || defined(STM32F427xx) || defined(STM32F437xx) ||\ + defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +#define ADC_CHANNEL_DIFFERENCIATION_TEMPSENSOR_VBAT 0x10000000U /* Dummy bit for driver internal usage, not used in ADC channel setting registers CR1 or SQRx */ +#define ADC_CHANNEL_TEMPSENSOR ((uint32_t)ADC_CHANNEL_18 | ADC_CHANNEL_DIFFERENCIATION_TEMPSENSOR_VBAT) +#endif /* STM32F411xE || STM32F413xx || STM32F423xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */ +/** + * @} + */ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ADC_Exported_Macros ADC Exported Macros + * @{ + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +/** + * @brief Disable internal path of ADC channel Vbat + * @note Use case of this macro: + * On devices STM32F42x and STM32F43x, ADC internal channels + * Vbat and VrefInt share the same internal path, only + * one of them can be enabled.This macro is to be used when ADC + * channels Vbat and VrefInt are selected, and must be called + * before starting conversion of ADC channel VrefInt in order + * to disable ADC channel Vbat. + * @retval None + */ +#define __HAL_ADC_PATH_INTERNAL_VBAT_DISABLE() (ADC->CCR &= ~(ADC_CCR_VBATE)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADCEx_Exported_Functions + * @{ + */ + +/** @addtogroup ADCEx_Exported_Functions_Group1 + * @{ + */ + +/* I/O operation functions ******************************************************/ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout); +HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef *hadc); +uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef *hadc, uint32_t InjectedRank); +HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length); +HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef *hadc); +uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef *hadc); +void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc); + +/* Peripheral Control functions *************************************************/ +HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, ADC_InjectionConfTypeDef *sConfigInjected); +HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef *hadc, ADC_MultiModeTypeDef *multimode); + +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup ADCEx_Private_Constants ADC Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup ADCEx_Private_Macros ADC Private Macros + * @{ + */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F410Tx) || defined(STM32F410Cx) || \ + defined(STM32F410Rx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || \ + defined(STM32F412Cx) +#define IS_ADC_CHANNEL(CHANNEL) ((CHANNEL) <= ADC_CHANNEL_18) +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || + STM32F410xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx */ + +#if defined(STM32F411xE) || defined(STM32F413xx) || defined(STM32F423xx) || defined(STM32F427xx) || \ + defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) || \ + defined(STM32F469xx) || defined(STM32F479xx) +#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) <= ADC_CHANNEL_18) || \ + ((CHANNEL) == ADC_CHANNEL_TEMPSENSOR)) +#endif /* STM32F411xE || STM32F413xx || STM32F423xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */ + +#define IS_ADC_MODE(MODE) (((MODE) == ADC_MODE_INDEPENDENT) || \ + ((MODE) == ADC_DUALMODE_REGSIMULT_INJECSIMULT) || \ + ((MODE) == ADC_DUALMODE_REGSIMULT_ALTERTRIG) || \ + ((MODE) == ADC_DUALMODE_INJECSIMULT) || \ + ((MODE) == ADC_DUALMODE_REGSIMULT) || \ + ((MODE) == ADC_DUALMODE_INTERL) || \ + ((MODE) == ADC_DUALMODE_ALTERTRIG) || \ + ((MODE) == ADC_TRIPLEMODE_REGSIMULT_INJECSIMULT) || \ + ((MODE) == ADC_TRIPLEMODE_REGSIMULT_AlterTrig) || \ + ((MODE) == ADC_TRIPLEMODE_INJECSIMULT) || \ + ((MODE) == ADC_TRIPLEMODE_REGSIMULT) || \ + ((MODE) == ADC_TRIPLEMODE_INTERL) || \ + ((MODE) == ADC_TRIPLEMODE_ALTERTRIG)) +#define IS_ADC_DMA_ACCESS_MODE(MODE) (((MODE) == ADC_DMAACCESSMODE_DISABLED) || \ + ((MODE) == ADC_DMAACCESSMODE_1) || \ + ((MODE) == ADC_DMAACCESSMODE_2) || \ + ((MODE) == ADC_DMAACCESSMODE_3)) +#define IS_ADC_EXT_INJEC_TRIG_EDGE(EDGE) (((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_NONE) || \ + ((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_RISING) || \ + ((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_FALLING) || \ + ((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_RISINGFALLING)) +#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC2) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_CC1) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_CC2) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_CC3) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_CC4) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_TRGO) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC2) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC3) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC4) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15)|| \ + ((INJTRIG) == ADC_INJECTED_SOFTWARE_START)) +#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 1U) && ((LENGTH) <= 4U)) +#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 1U) && ((RANK) <= 4U)) + +/** + * @brief Set the selected injected Channel rank. + * @param _CHANNELNB_ Channel number. + * @param _RANKNB_ Rank number. + * @param _JSQR_JL_ Sequence length. + * @retval None + */ +#define ADC_JSQR(_CHANNELNB_, _RANKNB_, _JSQR_JL_) (((uint32_t)((uint16_t)(_CHANNELNB_))) << (5U * (uint8_t)(((_RANKNB_) + 3U) - (_JSQR_JL_)))) + +/** + * @brief Defines if the selected ADC is within ADC common register ADC123 or ADC1 + * if available (ADC2, ADC3 availability depends on STM32 product) + * @param __HANDLE__ ADC handle + * @retval Common control register ADC123 or ADC1 + */ +#if defined(STM32F405xx) || defined(STM32F407xx) || defined(STM32F415xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F429xx) || defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +#define ADC_COMMON_REGISTER(__HANDLE__) ADC123_COMMON +#else +#define ADC_COMMON_REGISTER(__HANDLE__) ADC1_COMMON +#endif /* STM32F405xx || STM32F407xx || STM32F415xx || STM32F417xx || STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */ +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup ADCEx_Private_Functions ADC Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_ADC_EX_H */ + + diff --git a/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h b/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h new file mode 100644 index 00000000..13f6751b --- /dev/null +++ b/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h @@ -0,0 +1,4782 @@ +/** + ****************************************************************************** + * @file stm32f4xx_ll_adc.h + * @author MCD Application Team + * @brief Header file of ADC 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 __STM32F4xx_LL_ADC_H +#define __STM32F4xx_LL_ADC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_LL_Driver + * @{ + */ + +#if defined (ADC1) || defined (ADC2) || defined (ADC3) + +/** @defgroup ADC_LL ADC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup ADC_LL_Private_Constants ADC Private Constants + * @{ + */ + +/* Internal mask for ADC group regular sequencer: */ +/* To select into literal LL_ADC_REG_RANK_x the relevant bits for: */ +/* - sequencer register offset */ +/* - sequencer rank bits position into the selected register */ + +/* Internal register offset for ADC group regular sequencer configuration */ +/* (offset placed into a spare area of literal definition) */ +#define ADC_SQR1_REGOFFSET 0x00000000UL +#define ADC_SQR2_REGOFFSET 0x00000100UL +#define ADC_SQR3_REGOFFSET 0x00000200UL +#define ADC_SQR4_REGOFFSET 0x00000300UL + +#define ADC_REG_SQRX_REGOFFSET_MASK (ADC_SQR1_REGOFFSET | ADC_SQR2_REGOFFSET | ADC_SQR3_REGOFFSET | ADC_SQR4_REGOFFSET) +#define ADC_REG_RANK_ID_SQRX_MASK (ADC_CHANNEL_ID_NUMBER_MASK_POSBIT0) + +/* Definition of ADC group regular sequencer bits information to be inserted */ +/* into ADC group regular sequencer ranks literals definition. */ +#define ADC_REG_RANK_1_SQRX_BITOFFSET_POS ( 0UL) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ1) */ +#define ADC_REG_RANK_2_SQRX_BITOFFSET_POS ( 5UL) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ2) */ +#define ADC_REG_RANK_3_SQRX_BITOFFSET_POS (10UL) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ3) */ +#define ADC_REG_RANK_4_SQRX_BITOFFSET_POS (15UL) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ4) */ +#define ADC_REG_RANK_5_SQRX_BITOFFSET_POS (20UL) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ5) */ +#define ADC_REG_RANK_6_SQRX_BITOFFSET_POS (25UL) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ6) */ +#define ADC_REG_RANK_7_SQRX_BITOFFSET_POS ( 0UL) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ7) */ +#define ADC_REG_RANK_8_SQRX_BITOFFSET_POS ( 5UL) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ8) */ +#define ADC_REG_RANK_9_SQRX_BITOFFSET_POS (10UL) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ9) */ +#define ADC_REG_RANK_10_SQRX_BITOFFSET_POS (15UL) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ10) */ +#define ADC_REG_RANK_11_SQRX_BITOFFSET_POS (20UL) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ11) */ +#define ADC_REG_RANK_12_SQRX_BITOFFSET_POS (25UL) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ12) */ +#define ADC_REG_RANK_13_SQRX_BITOFFSET_POS ( 0UL) /* Value equivalent to POSITION_VAL(ADC_SQR1_SQ13) */ +#define ADC_REG_RANK_14_SQRX_BITOFFSET_POS ( 5UL) /* Value equivalent to POSITION_VAL(ADC_SQR1_SQ14) */ +#define ADC_REG_RANK_15_SQRX_BITOFFSET_POS (10UL) /* Value equivalent to POSITION_VAL(ADC_SQR1_SQ15) */ +#define ADC_REG_RANK_16_SQRX_BITOFFSET_POS (15UL) /* Value equivalent to POSITION_VAL(ADC_SQR1_SQ16) */ + +/* Internal mask for ADC group injected sequencer: */ +/* To select into literal LL_ADC_INJ_RANK_x the relevant bits for: */ +/* - data register offset */ +/* - offset register offset */ +/* - sequencer rank bits position into the selected register */ + +/* Internal register offset for ADC group injected data register */ +/* (offset placed into a spare area of literal definition) */ +#define ADC_JDR1_REGOFFSET 0x00000000UL +#define ADC_JDR2_REGOFFSET 0x00000100UL +#define ADC_JDR3_REGOFFSET 0x00000200UL +#define ADC_JDR4_REGOFFSET 0x00000300UL + +/* Internal register offset for ADC group injected offset configuration */ +/* (offset placed into a spare area of literal definition) */ +#define ADC_JOFR1_REGOFFSET 0x00000000UL +#define ADC_JOFR2_REGOFFSET 0x00001000UL +#define ADC_JOFR3_REGOFFSET 0x00002000UL +#define ADC_JOFR4_REGOFFSET 0x00003000UL + +#define ADC_INJ_JDRX_REGOFFSET_MASK (ADC_JDR1_REGOFFSET | ADC_JDR2_REGOFFSET | ADC_JDR3_REGOFFSET | ADC_JDR4_REGOFFSET) +#define ADC_INJ_JOFRX_REGOFFSET_MASK (ADC_JOFR1_REGOFFSET | ADC_JOFR2_REGOFFSET | ADC_JOFR3_REGOFFSET | ADC_JOFR4_REGOFFSET) +#define ADC_INJ_RANK_ID_JSQR_MASK (ADC_CHANNEL_ID_NUMBER_MASK_POSBIT0) + +/* Internal mask for ADC group regular trigger: */ +/* To select into literal LL_ADC_REG_TRIG_x the relevant bits for: */ +/* - regular trigger source */ +/* - regular trigger edge */ +#define ADC_REG_TRIG_EXT_EDGE_DEFAULT (ADC_CR2_EXTEN_0) /* Trigger edge set to rising edge (default setting for compatibility with some ADC on other STM32 families having this setting set by HW default value) */ + +/* Mask containing trigger source masks for each of possible */ +/* trigger edge selection duplicated with shifts [0; 4; 8; 12] */ +/* corresponding to {SW start; ext trigger; ext trigger; ext trigger}. */ +#define ADC_REG_TRIG_SOURCE_MASK (((LL_ADC_REG_TRIG_SOFTWARE & ADC_CR2_EXTSEL) >> (4UL * 0UL)) | \ + ((ADC_CR2_EXTSEL) >> (4UL * 1UL)) | \ + ((ADC_CR2_EXTSEL) >> (4UL * 2UL)) | \ + ((ADC_CR2_EXTSEL) >> (4UL * 3UL))) + +/* Mask containing trigger edge masks for each of possible */ +/* trigger edge selection duplicated with shifts [0; 4; 8; 12] */ +/* corresponding to {SW start; ext trigger; ext trigger; ext trigger}. */ +#define ADC_REG_TRIG_EDGE_MASK (((LL_ADC_REG_TRIG_SOFTWARE & ADC_CR2_EXTEN) >> (4UL * 0UL)) | \ + ((ADC_REG_TRIG_EXT_EDGE_DEFAULT) >> (4UL * 1UL)) | \ + ((ADC_REG_TRIG_EXT_EDGE_DEFAULT) >> (4UL * 2UL)) | \ + ((ADC_REG_TRIG_EXT_EDGE_DEFAULT) >> (4UL * 3UL))) + +/* Definition of ADC group regular trigger bits information. */ +#define ADC_REG_TRIG_EXTSEL_BITOFFSET_POS (24UL) /* Value equivalent to POSITION_VAL(ADC_CR2_EXTSEL) */ +#define ADC_REG_TRIG_EXTEN_BITOFFSET_POS (28UL) /* Value equivalent to POSITION_VAL(ADC_CR2_EXTEN) */ + + + +/* Internal mask for ADC group injected trigger: */ +/* To select into literal LL_ADC_INJ_TRIG_x the relevant bits for: */ +/* - injected trigger source */ +/* - injected trigger edge */ +#define ADC_INJ_TRIG_EXT_EDGE_DEFAULT (ADC_CR2_JEXTEN_0) /* Trigger edge set to rising edge (default setting for compatibility with some ADC on other STM32 families having this setting set by HW default value) */ + +/* Mask containing trigger source masks for each of possible */ +/* trigger edge selection duplicated with shifts [0; 4; 8; 12] */ +/* corresponding to {SW start; ext trigger; ext trigger; ext trigger}. */ +#define ADC_INJ_TRIG_SOURCE_MASK (((LL_ADC_REG_TRIG_SOFTWARE & ADC_CR2_JEXTSEL) >> (4UL * 0UL)) | \ + ((ADC_CR2_JEXTSEL) >> (4UL * 1UL)) | \ + ((ADC_CR2_JEXTSEL) >> (4UL * 2UL)) | \ + ((ADC_CR2_JEXTSEL) >> (4UL * 3UL))) + +/* Mask containing trigger edge masks for each of possible */ +/* trigger edge selection duplicated with shifts [0; 4; 8; 12] */ +/* corresponding to {SW start; ext trigger; ext trigger; ext trigger}. */ +#define ADC_INJ_TRIG_EDGE_MASK (((LL_ADC_INJ_TRIG_SOFTWARE & ADC_CR2_JEXTEN) >> (4UL * 0UL)) | \ + ((ADC_INJ_TRIG_EXT_EDGE_DEFAULT) >> (4UL * 1UL)) | \ + ((ADC_INJ_TRIG_EXT_EDGE_DEFAULT) >> (4UL * 2UL)) | \ + ((ADC_INJ_TRIG_EXT_EDGE_DEFAULT) >> (4UL * 3UL))) + +/* Definition of ADC group injected trigger bits information. */ +#define ADC_INJ_TRIG_EXTSEL_BITOFFSET_POS (16UL) /* Value equivalent to POSITION_VAL(ADC_CR2_JEXTSEL) */ +#define ADC_INJ_TRIG_EXTEN_BITOFFSET_POS (20UL) /* Value equivalent to POSITION_VAL(ADC_CR2_JEXTEN) */ + +/* Internal mask for ADC channel: */ +/* To select into literal LL_ADC_CHANNEL_x the relevant bits for: */ +/* - channel identifier defined by number */ +/* - channel differentiation between external channels (connected to */ +/* GPIO pins) and internal channels (connected to internal paths) */ +/* - channel sampling time defined by SMPRx register offset */ +/* and SMPx bits positions into SMPRx register */ +#define ADC_CHANNEL_ID_NUMBER_MASK (ADC_CR1_AWDCH) +#define ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS ( 0UL)/* Value equivalent to POSITION_VAL(ADC_CHANNEL_ID_NUMBER_MASK) */ +#define ADC_CHANNEL_ID_MASK (ADC_CHANNEL_ID_NUMBER_MASK | ADC_CHANNEL_ID_INTERNAL_CH_MASK) +/* Equivalent mask of ADC_CHANNEL_NUMBER_MASK aligned on register LSB (bit 0) */ +#define ADC_CHANNEL_ID_NUMBER_MASK_POSBIT0 0x0000001FU /* Equivalent to shift: (ADC_CHANNEL_NUMBER_MASK >> POSITION_VAL(ADC_CHANNEL_NUMBER_MASK)) */ + +/* Channel differentiation between external and internal channels */ +#define ADC_CHANNEL_ID_INTERNAL_CH 0x80000000UL /* Marker of internal channel */ +#define ADC_CHANNEL_ID_INTERNAL_CH_2 0x40000000UL /* Marker of internal channel for other ADC instances, in case of different ADC internal channels mapped on same channel number on different ADC instances */ +#define ADC_CHANNEL_DIFFERENCIATION_TEMPSENSOR_VBAT 0x10000000U /* Dummy bit for driver internal usage, not used in ADC channel setting registers CR1 or SQRx */ +#define ADC_CHANNEL_ID_INTERNAL_CH_MASK (ADC_CHANNEL_ID_INTERNAL_CH | ADC_CHANNEL_ID_INTERNAL_CH_2 | ADC_CHANNEL_DIFFERENCIATION_TEMPSENSOR_VBAT) + +/* Internal register offset for ADC channel sampling time configuration */ +/* (offset placed into a spare area of literal definition) */ +#define ADC_SMPR1_REGOFFSET 0x00000000UL +#define ADC_SMPR2_REGOFFSET 0x02000000UL +#define ADC_CHANNEL_SMPRX_REGOFFSET_MASK (ADC_SMPR1_REGOFFSET | ADC_SMPR2_REGOFFSET) + +#define ADC_CHANNEL_SMPx_BITOFFSET_MASK 0x01F00000UL +#define ADC_CHANNEL_SMPx_BITOFFSET_POS (20UL) /* Value equivalent to POSITION_VAL(ADC_CHANNEL_SMPx_BITOFFSET_MASK) */ + +/* Definition of channels ID number information to be inserted into */ +/* channels literals definition. */ +#define ADC_CHANNEL_0_NUMBER 0x00000000UL +#define ADC_CHANNEL_1_NUMBER ( ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_2_NUMBER ( ADC_CR1_AWDCH_1 ) +#define ADC_CHANNEL_3_NUMBER ( ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_4_NUMBER ( ADC_CR1_AWDCH_2 ) +#define ADC_CHANNEL_5_NUMBER ( ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_6_NUMBER ( ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 ) +#define ADC_CHANNEL_7_NUMBER ( ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_8_NUMBER ( ADC_CR1_AWDCH_3 ) +#define ADC_CHANNEL_9_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_10_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_1 ) +#define ADC_CHANNEL_11_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_12_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 ) +#define ADC_CHANNEL_13_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_14_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 ) +#define ADC_CHANNEL_15_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_16_NUMBER (ADC_CR1_AWDCH_4 ) +#define ADC_CHANNEL_17_NUMBER (ADC_CR1_AWDCH_4 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_18_NUMBER (ADC_CR1_AWDCH_4 | ADC_CR1_AWDCH_1 ) + +/* Definition of channels sampling time information to be inserted into */ +/* channels literals definition. */ +#define ADC_CHANNEL_0_SMP (ADC_SMPR2_REGOFFSET | (( 0UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP0) */ +#define ADC_CHANNEL_1_SMP (ADC_SMPR2_REGOFFSET | (( 3UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP1) */ +#define ADC_CHANNEL_2_SMP (ADC_SMPR2_REGOFFSET | (( 6UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP2) */ +#define ADC_CHANNEL_3_SMP (ADC_SMPR2_REGOFFSET | (( 9UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP3) */ +#define ADC_CHANNEL_4_SMP (ADC_SMPR2_REGOFFSET | ((12UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP4) */ +#define ADC_CHANNEL_5_SMP (ADC_SMPR2_REGOFFSET | ((15UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP5) */ +#define ADC_CHANNEL_6_SMP (ADC_SMPR2_REGOFFSET | ((18UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP6) */ +#define ADC_CHANNEL_7_SMP (ADC_SMPR2_REGOFFSET | ((21UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP7) */ +#define ADC_CHANNEL_8_SMP (ADC_SMPR2_REGOFFSET | ((24UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP8) */ +#define ADC_CHANNEL_9_SMP (ADC_SMPR2_REGOFFSET | ((27UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP9) */ +#define ADC_CHANNEL_10_SMP (ADC_SMPR1_REGOFFSET | (( 0UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP10) */ +#define ADC_CHANNEL_11_SMP (ADC_SMPR1_REGOFFSET | (( 3UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP11) */ +#define ADC_CHANNEL_12_SMP (ADC_SMPR1_REGOFFSET | (( 6UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP12) */ +#define ADC_CHANNEL_13_SMP (ADC_SMPR1_REGOFFSET | (( 9UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP13) */ +#define ADC_CHANNEL_14_SMP (ADC_SMPR1_REGOFFSET | ((12UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP14) */ +#define ADC_CHANNEL_15_SMP (ADC_SMPR1_REGOFFSET | ((15UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP15) */ +#define ADC_CHANNEL_16_SMP (ADC_SMPR1_REGOFFSET | ((18UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP16) */ +#define ADC_CHANNEL_17_SMP (ADC_SMPR1_REGOFFSET | ((21UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP17) */ +#define ADC_CHANNEL_18_SMP (ADC_SMPR1_REGOFFSET | ((24UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP18) */ + +/* Internal mask for ADC analog watchdog: */ +/* To select into literals LL_ADC_AWD_CHANNELx_xxx the relevant bits for: */ +/* (concatenation of multiple bits used in different analog watchdogs, */ +/* (feature of several watchdogs not available on all STM32 families)). */ +/* - analog watchdog 1: monitored channel defined by number, */ +/* selection of ADC group (ADC groups regular and-or injected). */ + +/* Internal register offset for ADC analog watchdog channel configuration */ +#define ADC_AWD_CR1_REGOFFSET 0x00000000UL + +#define ADC_AWD_CRX_REGOFFSET_MASK (ADC_AWD_CR1_REGOFFSET) + +#define ADC_AWD_CR1_CHANNEL_MASK (ADC_CR1_AWDCH | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) +#define ADC_AWD_CR_ALL_CHANNEL_MASK (ADC_AWD_CR1_CHANNEL_MASK) + +/* Internal register offset for ADC analog watchdog threshold configuration */ +#define ADC_AWD_TR1_HIGH_REGOFFSET 0x00000000UL +#define ADC_AWD_TR1_LOW_REGOFFSET 0x00000001UL +#define ADC_AWD_TRX_REGOFFSET_MASK (ADC_AWD_TR1_HIGH_REGOFFSET | ADC_AWD_TR1_LOW_REGOFFSET) + +/* ADC registers bits positions */ +#define ADC_CR1_RES_BITOFFSET_POS (24UL) /* Value equivalent to POSITION_VAL(ADC_CR1_RES) */ +#define ADC_TR_HT_BITOFFSET_POS (16UL) /* Value equivalent to POSITION_VAL(ADC_TR_HT) */ + +/* ADC internal channels related definitions */ +/* Internal voltage reference VrefInt */ +#define VREFINT_CAL_ADDR ((uint16_t*) (0x1FFF7A2AU)) /* Internal voltage reference, address of parameter VREFINT_CAL: VrefInt ADC raw data acquired at temperature 30 DegC (tolerance: +-5 DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */ +#define VREFINT_CAL_VREF ( 3300UL) /* Analog voltage reference (Vref+) value with which temperature sensor has been calibrated in production (tolerance: +-10 mV) (unit: mV). */ +/* Temperature sensor */ +#define TEMPSENSOR_CAL1_ADDR ((uint16_t*) (0x1FFF7A2CU)) /* Internal temperature sensor, address of parameter TS_CAL1: On STM32F4, temperature sensor ADC raw data acquired at temperature 30 DegC (tolerance: +-5 DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */ +#define TEMPSENSOR_CAL2_ADDR ((uint16_t*) (0x1FFF7A2EU)) /* Internal temperature sensor, address of parameter TS_CAL2: On STM32F4, temperature sensor ADC raw data acquired at temperature 110 DegC (tolerance: +-5 DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */ +#define TEMPSENSOR_CAL1_TEMP (( int32_t) 30) /* Internal temperature sensor, temperature at which temperature sensor has been calibrated in production for data into TEMPSENSOR_CAL1_ADDR (tolerance: +-5 DegC) (unit: DegC). */ +#define TEMPSENSOR_CAL2_TEMP (( int32_t) 110) /* Internal temperature sensor, temperature at which temperature sensor has been calibrated in production for data into TEMPSENSOR_CAL2_ADDR (tolerance: +-5 DegC) (unit: DegC). */ +#define TEMPSENSOR_CAL_VREFANALOG ( 3300UL) /* Analog voltage reference (Vref+) voltage with which temperature sensor has been calibrated in production (+-10 mV) (unit: mV). */ + +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup ADC_LL_Private_Macros ADC Private Macros + * @{ + */ + +/** + * @brief Driver macro reserved for internal use: isolate bits with the + * selected mask and shift them to the register LSB + * (shift mask on register position bit 0). + * @param __BITS__ Bits in register 32 bits + * @param __MASK__ Mask in register 32 bits + * @retval Bits in register 32 bits + */ +#define __ADC_MASK_SHIFT(__BITS__, __MASK__) \ + (((__BITS__) & (__MASK__)) >> POSITION_VAL((__MASK__))) + +/** + * @brief Driver macro reserved for internal use: set a pointer to + * a register from a register basis from which an offset + * is applied. + * @param __REG__ Register basis from which the offset is applied. + * @param __REG_OFFFSET__ Offset to be applied (unit number of registers). + * @retval Pointer to register address + */ +#define __ADC_PTR_REG_OFFSET(__REG__, __REG_OFFFSET__) \ + ((__IO uint32_t *)((uint32_t) ((uint32_t)(&(__REG__)) + ((__REG_OFFFSET__) << 2UL)))) + +/** + * @} + */ + + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup ADC_LL_ES_INIT ADC Exported Init structure + * @{ + */ + +/** + * @brief Structure definition of some features of ADC common parameters + * and multimode + * (all ADC instances belonging to the same ADC common instance). + * @note The setting of these parameters by function @ref LL_ADC_CommonInit() + * is conditioned to ADC instances state (all ADC instances + * sharing the same ADC common instance): + * All ADC instances sharing the same ADC common instance must be + * disabled. + */ +typedef struct +{ + uint32_t CommonClock; /*!< Set parameter common to several ADC: Clock source and prescaler. + This parameter can be a value of @ref ADC_LL_EC_COMMON_CLOCK_SOURCE + + This feature can be modified afterwards using unitary function @ref LL_ADC_SetCommonClock(). */ + +#if defined(ADC_MULTIMODE_SUPPORT) + uint32_t Multimode; /*!< Set ADC multimode configuration to operate in independent mode or multimode (for devices with several ADC instances). + This parameter can be a value of @ref ADC_LL_EC_MULTI_MODE + + This feature can be modified afterwards using unitary function @ref LL_ADC_SetMultimode(). */ + + uint32_t MultiDMATransfer; /*!< Set ADC multimode conversion data transfer: no transfer or transfer by DMA. + This parameter can be a value of @ref ADC_LL_EC_MULTI_DMA_TRANSFER + + This feature can be modified afterwards using unitary function @ref LL_ADC_SetMultiDMATransfer(). */ + + uint32_t MultiTwoSamplingDelay; /*!< Set ADC multimode delay between 2 sampling phases. + This parameter can be a value of @ref ADC_LL_EC_MULTI_TWOSMP_DELAY + + This feature can be modified afterwards using unitary function @ref LL_ADC_SetMultiTwoSamplingDelay(). */ +#endif /* ADC_MULTIMODE_SUPPORT */ + +} LL_ADC_CommonInitTypeDef; + +/** + * @brief Structure definition of some features of ADC instance. + * @note These parameters have an impact on ADC scope: ADC instance. + * Affects both group regular and group injected (availability + * of ADC group injected depends on STM32 families). + * Refer to corresponding unitary functions into + * @ref ADC_LL_EF_Configuration_ADC_Instance . + * @note The setting of these parameters by function @ref LL_ADC_Init() + * is conditioned to ADC state: + * ADC instance must be disabled. + * This condition is applied to all ADC features, for efficiency + * and compatibility over all STM32 families. However, the different + * features can be set under different ADC state conditions + * (setting possible with ADC enabled without conversion on going, + * ADC enabled with conversion on going, ...) + * Each feature can be updated afterwards with a unitary function + * and potentially with ADC in a different state than disabled, + * refer to description of each function for setting + * conditioned to ADC state. + */ +typedef struct +{ + uint32_t Resolution; /*!< Set ADC resolution. + This parameter can be a value of @ref ADC_LL_EC_RESOLUTION + + This feature can be modified afterwards using unitary function @ref LL_ADC_SetResolution(). */ + + uint32_t DataAlignment; /*!< Set ADC conversion data alignment. + This parameter can be a value of @ref ADC_LL_EC_DATA_ALIGN + + This feature can be modified afterwards using unitary function @ref LL_ADC_SetDataAlignment(). */ + + uint32_t SequencersScanMode; /*!< Set ADC scan selection. + This parameter can be a value of @ref ADC_LL_EC_SCAN_SELECTION + + This feature can be modified afterwards using unitary function @ref LL_ADC_SetSequencersScanMode(). */ + +} LL_ADC_InitTypeDef; + +/** + * @brief Structure definition of some features of ADC group regular. + * @note These parameters have an impact on ADC scope: ADC group regular. + * Refer to corresponding unitary functions into + * @ref ADC_LL_EF_Configuration_ADC_Group_Regular + * (functions with prefix "REG"). + * @note The setting of these parameters by function @ref LL_ADC_REG_Init() + * is conditioned to ADC state: + * ADC instance must be disabled. + * This condition is applied to all ADC features, for efficiency + * and compatibility over all STM32 families. However, the different + * features can be set under different ADC state conditions + * (setting possible with ADC enabled without conversion on going, + * ADC enabled with conversion on going, ...) + * Each feature can be updated afterwards with a unitary function + * and potentially with ADC in a different state than disabled, + * refer to description of each function for setting + * conditioned to ADC state. + */ +typedef struct +{ + uint32_t TriggerSource; /*!< Set ADC group regular conversion trigger source: internal (SW start) or from external IP (timer event, external interrupt line). + This parameter can be a value of @ref ADC_LL_EC_REG_TRIGGER_SOURCE + @note On this STM32 series, setting of external trigger edge is performed + using function @ref LL_ADC_REG_StartConversionExtTrig(). + + This feature can be modified afterwards using unitary function @ref LL_ADC_REG_SetTriggerSource(). */ + + uint32_t SequencerLength; /*!< Set ADC group regular sequencer length. + This parameter can be a value of @ref ADC_LL_EC_REG_SEQ_SCAN_LENGTH + @note This parameter is discarded if scan mode is disabled (refer to parameter 'ADC_SequencersScanMode'). + + This feature can be modified afterwards using unitary function @ref LL_ADC_REG_SetSequencerLength(). */ + + uint32_t SequencerDiscont; /*!< Set ADC group regular sequencer discontinuous mode: sequence subdivided and scan conversions interrupted every selected number of ranks. + This parameter can be a value of @ref ADC_LL_EC_REG_SEQ_DISCONT_MODE + @note This parameter has an effect only if group regular sequencer is enabled + (scan length of 2 ranks or more). + + This feature can be modified afterwards using unitary function @ref LL_ADC_REG_SetSequencerDiscont(). */ + + uint32_t ContinuousMode; /*!< Set ADC continuous conversion mode on ADC group regular, whether ADC conversions are performed in single mode (one conversion per trigger) or in continuous mode (after the first trigger, following conversions launched successively automatically). + This parameter can be a value of @ref ADC_LL_EC_REG_CONTINUOUS_MODE + Note: It is not possible to enable both ADC group regular continuous mode and discontinuous mode. + + This feature can be modified afterwards using unitary function @ref LL_ADC_REG_SetContinuousMode(). */ + + uint32_t DMATransfer; /*!< Set ADC group regular conversion data transfer: no transfer or transfer by DMA, and DMA requests mode. + This parameter can be a value of @ref ADC_LL_EC_REG_DMA_TRANSFER + + This feature can be modified afterwards using unitary function @ref LL_ADC_REG_SetDMATransfer(). */ + +} LL_ADC_REG_InitTypeDef; + +/** + * @brief Structure definition of some features of ADC group injected. + * @note These parameters have an impact on ADC scope: ADC group injected. + * Refer to corresponding unitary functions into + * @ref ADC_LL_EF_Configuration_ADC_Group_Regular + * (functions with prefix "INJ"). + * @note The setting of these parameters by function @ref LL_ADC_INJ_Init() + * is conditioned to ADC state: + * ADC instance must be disabled. + * This condition is applied to all ADC features, for efficiency + * and compatibility over all STM32 families. However, the different + * features can be set under different ADC state conditions + * (setting possible with ADC enabled without conversion on going, + * ADC enabled with conversion on going, ...) + * Each feature can be updated afterwards with a unitary function + * and potentially with ADC in a different state than disabled, + * refer to description of each function for setting + * conditioned to ADC state. + */ +typedef struct +{ + uint32_t TriggerSource; /*!< Set ADC group injected conversion trigger source: internal (SW start) or from external IP (timer event, external interrupt line). + This parameter can be a value of @ref ADC_LL_EC_INJ_TRIGGER_SOURCE + @note On this STM32 series, setting of external trigger edge is performed + using function @ref LL_ADC_INJ_StartConversionExtTrig(). + + This feature can be modified afterwards using unitary function @ref LL_ADC_INJ_SetTriggerSource(). */ + + uint32_t SequencerLength; /*!< Set ADC group injected sequencer length. + This parameter can be a value of @ref ADC_LL_EC_INJ_SEQ_SCAN_LENGTH + @note This parameter is discarded if scan mode is disabled (refer to parameter 'ADC_SequencersScanMode'). + + This feature can be modified afterwards using unitary function @ref LL_ADC_INJ_SetSequencerLength(). */ + + uint32_t SequencerDiscont; /*!< Set ADC group injected sequencer discontinuous mode: sequence subdivided and scan conversions interrupted every selected number of ranks. + This parameter can be a value of @ref ADC_LL_EC_INJ_SEQ_DISCONT_MODE + @note This parameter has an effect only if group injected sequencer is enabled + (scan length of 2 ranks or more). + + This feature can be modified afterwards using unitary function @ref LL_ADC_INJ_SetSequencerDiscont(). */ + + uint32_t TrigAuto; /*!< Set ADC group injected conversion trigger: independent or from ADC group regular. + This parameter can be a value of @ref ADC_LL_EC_INJ_TRIG_AUTO + Note: This parameter must be set to set to independent trigger if injected trigger source is set to an external trigger. + + This feature can be modified afterwards using unitary function @ref LL_ADC_INJ_SetTrigAuto(). */ + +} LL_ADC_INJ_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ADC_LL_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup ADC_LL_EC_FLAG ADC flags + * @brief Flags defines which can be used with LL_ADC_ReadReg function + * @{ + */ +#define LL_ADC_FLAG_STRT ADC_SR_STRT /*!< ADC flag ADC group regular conversion start */ +#define LL_ADC_FLAG_EOCS ADC_SR_EOC /*!< ADC flag ADC group regular end of unitary conversion or sequence conversions (to configure flag of end of conversion, use function @ref LL_ADC_REG_SetFlagEndOfConversion() ) */ +#define LL_ADC_FLAG_OVR ADC_SR_OVR /*!< ADC flag ADC group regular overrun */ +#define LL_ADC_FLAG_JSTRT ADC_SR_JSTRT /*!< ADC flag ADC group injected conversion start */ +#define LL_ADC_FLAG_JEOS ADC_SR_JEOC /*!< ADC flag ADC group injected end of sequence conversions (Note: on this STM32 series, there is no flag ADC group injected end of unitary conversion. Flag noted as "JEOC" is corresponding to flag "JEOS" in other STM32 families) */ +#define LL_ADC_FLAG_AWD1 ADC_SR_AWD /*!< ADC flag ADC analog watchdog 1 */ +#if defined(ADC_MULTIMODE_SUPPORT) +#define LL_ADC_FLAG_EOCS_MST ADC_CSR_EOC1 /*!< ADC flag ADC multimode master group regular end of unitary conversion or sequence conversions (to configure flag of end of conversion, use function @ref LL_ADC_REG_SetFlagEndOfConversion() ) */ +#define LL_ADC_FLAG_EOCS_SLV1 ADC_CSR_EOC2 /*!< ADC flag ADC multimode slave 1 group regular end of unitary conversion or sequence conversions (to configure flag of end of conversion, use function @ref LL_ADC_REG_SetFlagEndOfConversion() ) */ +#define LL_ADC_FLAG_EOCS_SLV2 ADC_CSR_EOC3 /*!< ADC flag ADC multimode slave 2 group regular end of unitary conversion or sequence conversions (to configure flag of end of conversion, use function @ref LL_ADC_REG_SetFlagEndOfConversion() ) */ +#define LL_ADC_FLAG_OVR_MST ADC_CSR_OVR1 /*!< ADC flag ADC multimode master group regular overrun */ +#define LL_ADC_FLAG_OVR_SLV1 ADC_CSR_OVR2 /*!< ADC flag ADC multimode slave 1 group regular overrun */ +#define LL_ADC_FLAG_OVR_SLV2 ADC_CSR_OVR3 /*!< ADC flag ADC multimode slave 2 group regular overrun */ +#define LL_ADC_FLAG_JEOS_MST ADC_CSR_JEOC1 /*!< ADC flag ADC multimode master group injected end of sequence conversions (Note: on this STM32 series, there is no flag ADC group injected end of unitary conversion. Flag noted as "JEOC" is corresponding to flag "JEOS" in other STM32 families) */ +#define LL_ADC_FLAG_JEOS_SLV1 ADC_CSR_JEOC2 /*!< ADC flag ADC multimode slave 1 group injected end of sequence conversions (Note: on this STM32 series, there is no flag ADC group injected end of unitary conversion. Flag noted as "JEOC" is corresponding to flag "JEOS" in other STM32 families) */ +#define LL_ADC_FLAG_JEOS_SLV2 ADC_CSR_JEOC3 /*!< ADC flag ADC multimode slave 2 group injected end of sequence conversions (Note: on this STM32 series, there is no flag ADC group injected end of unitary conversion. Flag noted as "JEOC" is corresponding to flag "JEOS" in other STM32 families) */ +#define LL_ADC_FLAG_AWD1_MST ADC_CSR_AWD1 /*!< ADC flag ADC multimode master analog watchdog 1 of the ADC master */ +#define LL_ADC_FLAG_AWD1_SLV1 ADC_CSR_AWD2 /*!< ADC flag ADC multimode slave 1 analog watchdog 1 */ +#define LL_ADC_FLAG_AWD1_SLV2 ADC_CSR_AWD3 /*!< ADC flag ADC multimode slave 2 analog watchdog 1 */ +#endif +/** + * @} + */ + +/** @defgroup ADC_LL_EC_IT ADC interruptions for configuration (interruption enable or disable) + * @brief IT defines which can be used with LL_ADC_ReadReg and LL_ADC_WriteReg functions + * @{ + */ +#define LL_ADC_IT_EOCS ADC_CR1_EOCIE /*!< ADC interruption ADC group regular end of unitary conversion or sequence conversions (to configure flag of end of conversion, use function @ref LL_ADC_REG_SetFlagEndOfConversion() ) */ +#define LL_ADC_IT_OVR ADC_CR1_OVRIE /*!< ADC interruption ADC group regular overrun */ +#define LL_ADC_IT_JEOS ADC_CR1_JEOCIE /*!< ADC interruption ADC group injected end of sequence conversions (Note: on this STM32 series, there is no flag ADC group injected end of unitary conversion. Flag noted as "JEOC" is corresponding to flag "JEOS" in other STM32 families) */ +#define LL_ADC_IT_AWD1 ADC_CR1_AWDIE /*!< ADC interruption ADC analog watchdog 1 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REGISTERS ADC registers compliant with specific purpose + * @{ + */ +/* List of ADC registers intended to be used (most commonly) with */ +/* DMA transfer. */ +/* Refer to function @ref LL_ADC_DMA_GetRegAddr(). */ +#define LL_ADC_DMA_REG_REGULAR_DATA 0x00000000UL /* ADC group regular conversion data register (corresponding to register DR) to be used with ADC configured in independent mode. Without DMA transfer, register accessed by LL function @ref LL_ADC_REG_ReadConversionData32() and other functions @ref LL_ADC_REG_ReadConversionDatax() */ +#if defined(ADC_MULTIMODE_SUPPORT) +#define LL_ADC_DMA_REG_REGULAR_DATA_MULTI 0x00000001UL /* ADC group regular conversion data register (corresponding to register CDR) to be used with ADC configured in multimode (available on STM32 devices with several ADC instances). Without DMA transfer, register accessed by LL function @ref LL_ADC_REG_ReadMultiConversionData32() */ +#endif +/** + * @} + */ + +/** @defgroup ADC_LL_EC_COMMON_CLOCK_SOURCE ADC common - Clock source + * @{ + */ +#define LL_ADC_CLOCK_SYNC_PCLK_DIV2 0x00000000UL /*!< ADC synchronous clock derived from AHB clock with prescaler division by 2 */ +#define LL_ADC_CLOCK_SYNC_PCLK_DIV4 ( ADC_CCR_ADCPRE_0) /*!< ADC synchronous clock derived from AHB clock with prescaler division by 4 */ +#define LL_ADC_CLOCK_SYNC_PCLK_DIV6 (ADC_CCR_ADCPRE_1 ) /*!< ADC synchronous clock derived from AHB clock with prescaler division by 6 */ +#define LL_ADC_CLOCK_SYNC_PCLK_DIV8 (ADC_CCR_ADCPRE_1 | ADC_CCR_ADCPRE_0) /*!< ADC synchronous clock derived from AHB clock with prescaler division by 8 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_COMMON_PATH_INTERNAL ADC common - Measurement path to internal channels + * @{ + */ +/* Note: Other measurement paths to internal channels may be available */ +/* (connections to other peripherals). */ +/* If they are not listed below, they do not require any specific */ +/* path enable. In this case, Access to measurement path is done */ +/* only by selecting the corresponding ADC internal channel. */ +#define LL_ADC_PATH_INTERNAL_NONE 0x00000000UL /*!< ADC measurement paths all disabled */ +#define LL_ADC_PATH_INTERNAL_VREFINT (ADC_CCR_TSVREFE) /*!< ADC measurement path to internal channel VrefInt */ +#define LL_ADC_PATH_INTERNAL_TEMPSENSOR (ADC_CCR_TSVREFE) /*!< ADC measurement path to internal channel temperature sensor */ +#define LL_ADC_PATH_INTERNAL_VBAT (ADC_CCR_VBATE) /*!< ADC measurement path to internal channel Vbat */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_RESOLUTION ADC instance - Resolution + * @{ + */ +#define LL_ADC_RESOLUTION_12B 0x00000000UL /*!< ADC resolution 12 bits */ +#define LL_ADC_RESOLUTION_10B ( ADC_CR1_RES_0) /*!< ADC resolution 10 bits */ +#define LL_ADC_RESOLUTION_8B (ADC_CR1_RES_1 ) /*!< ADC resolution 8 bits */ +#define LL_ADC_RESOLUTION_6B (ADC_CR1_RES_1 | ADC_CR1_RES_0) /*!< ADC resolution 6 bits */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_DATA_ALIGN ADC instance - Data alignment + * @{ + */ +#define LL_ADC_DATA_ALIGN_RIGHT 0x00000000UL /*!< ADC conversion data alignment: right aligned (alignment on data register LSB bit 0)*/ +#define LL_ADC_DATA_ALIGN_LEFT (ADC_CR2_ALIGN) /*!< ADC conversion data alignment: left aligned (alignment on data register MSB bit 15)*/ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_SCAN_SELECTION ADC instance - Scan selection + * @{ + */ +#define LL_ADC_SEQ_SCAN_DISABLE 0x00000000UL /*!< ADC conversion is performed in unitary conversion mode (one channel converted, that defined in rank 1). Configuration of both groups regular and injected sequencers (sequence length, ...) is discarded: equivalent to length of 1 rank.*/ +#define LL_ADC_SEQ_SCAN_ENABLE (ADC_CR1_SCAN) /*!< ADC conversions are performed in sequence conversions mode, according to configuration of both groups regular and injected sequencers (sequence length, ...). */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_GROUPS ADC instance - Groups + * @{ + */ +#define LL_ADC_GROUP_REGULAR 0x00000001UL /*!< ADC group regular (available on all STM32 devices) */ +#define LL_ADC_GROUP_INJECTED 0x00000002UL /*!< ADC group injected (not available on all STM32 devices)*/ +#define LL_ADC_GROUP_REGULAR_INJECTED 0x00000003UL /*!< ADC both groups regular and injected */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_CHANNEL ADC instance - Channel number + * @{ + */ +#define LL_ADC_CHANNEL_0 (ADC_CHANNEL_0_NUMBER | ADC_CHANNEL_0_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN0 */ +#define LL_ADC_CHANNEL_1 (ADC_CHANNEL_1_NUMBER | ADC_CHANNEL_1_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN1 */ +#define LL_ADC_CHANNEL_2 (ADC_CHANNEL_2_NUMBER | ADC_CHANNEL_2_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN2 */ +#define LL_ADC_CHANNEL_3 (ADC_CHANNEL_3_NUMBER | ADC_CHANNEL_3_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN3 */ +#define LL_ADC_CHANNEL_4 (ADC_CHANNEL_4_NUMBER | ADC_CHANNEL_4_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN4 */ +#define LL_ADC_CHANNEL_5 (ADC_CHANNEL_5_NUMBER | ADC_CHANNEL_5_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN5 */ +#define LL_ADC_CHANNEL_6 (ADC_CHANNEL_6_NUMBER | ADC_CHANNEL_6_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN6 */ +#define LL_ADC_CHANNEL_7 (ADC_CHANNEL_7_NUMBER | ADC_CHANNEL_7_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN7 */ +#define LL_ADC_CHANNEL_8 (ADC_CHANNEL_8_NUMBER | ADC_CHANNEL_8_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN8 */ +#define LL_ADC_CHANNEL_9 (ADC_CHANNEL_9_NUMBER | ADC_CHANNEL_9_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN9 */ +#define LL_ADC_CHANNEL_10 (ADC_CHANNEL_10_NUMBER | ADC_CHANNEL_10_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN10 */ +#define LL_ADC_CHANNEL_11 (ADC_CHANNEL_11_NUMBER | ADC_CHANNEL_11_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN11 */ +#define LL_ADC_CHANNEL_12 (ADC_CHANNEL_12_NUMBER | ADC_CHANNEL_12_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN12 */ +#define LL_ADC_CHANNEL_13 (ADC_CHANNEL_13_NUMBER | ADC_CHANNEL_13_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN13 */ +#define LL_ADC_CHANNEL_14 (ADC_CHANNEL_14_NUMBER | ADC_CHANNEL_14_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN14 */ +#define LL_ADC_CHANNEL_15 (ADC_CHANNEL_15_NUMBER | ADC_CHANNEL_15_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN15 */ +#define LL_ADC_CHANNEL_16 (ADC_CHANNEL_16_NUMBER | ADC_CHANNEL_16_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN16 */ +#define LL_ADC_CHANNEL_17 (ADC_CHANNEL_17_NUMBER | ADC_CHANNEL_17_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN17 */ +#define LL_ADC_CHANNEL_18 (ADC_CHANNEL_18_NUMBER | ADC_CHANNEL_18_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN18 */ +#define LL_ADC_CHANNEL_VREFINT (LL_ADC_CHANNEL_17 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel connected to VrefInt: Internal voltage reference. On STM32F4, ADC channel available only on ADC instance: ADC1. */ +#define LL_ADC_CHANNEL_VBAT (LL_ADC_CHANNEL_18 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel connected to Vbat/3: Vbat voltage through a divider ladder of factor 1/3 to have Vbat always below Vdda. On STM32F4, ADC channel available only on ADC instance: ADC1. */ +#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xx) || defined(STM32F407xx) || defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F415xx) || defined(STM32F417xx) +#define LL_ADC_CHANNEL_TEMPSENSOR (LL_ADC_CHANNEL_16 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel connected to Temperature sensor. On STM32F4, ADC channel available only on ADC instance: ADC1. */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F410xx */ +#if defined(STM32F411xE) || defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || defined(STM32F423xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +#define LL_ADC_CHANNEL_TEMPSENSOR (LL_ADC_CHANNEL_18 | ADC_CHANNEL_ID_INTERNAL_CH | ADC_CHANNEL_DIFFERENCIATION_TEMPSENSOR_VBAT) /*!< ADC internal channel connected to Temperature sensor. On STM32F4, ADC channel available only on ADC instance: ADC1. This internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. */ +#endif /* STM32F411xE || STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_TRIGGER_SOURCE ADC group regular - Trigger source + * @{ + */ +#define LL_ADC_REG_TRIG_SOFTWARE 0x00000000UL /*!< ADC group regular conversion trigger internal: SW start. */ +#define LL_ADC_REG_TRIG_EXT_TIM1_CH1 (ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM1 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM1_CH2 (ADC_CR2_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM1 channel 2 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM1_CH3 (ADC_CR2_EXTSEL_1 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM1 channel 3 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM2_CH2 (ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM2 channel 2 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM2_CH3 (ADC_CR2_EXTSEL_2 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM2 channel 3 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM2_CH4 (ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM2 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM2_TRGO (ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM2 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM3_CH1 (ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM3 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM3_TRGO (ADC_CR2_EXTSEL_3 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM3 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM4_CH4 (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM4 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM5_CH1 (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_1 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM5 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM5_CH2 (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM5 channel 2 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM5_CH3 (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM5 channel 3 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM8_CH1 (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM8 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM8_TRGO (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM8 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_EXTI_LINE11 (ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: external interrupt line 11. Trigger edge set to rising edge (default setting). */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_TRIGGER_EDGE ADC group regular - Trigger edge + * @{ + */ +#define LL_ADC_REG_TRIG_EXT_RISING ( ADC_CR2_EXTEN_0) /*!< ADC group regular conversion trigger polarity set to rising edge */ +#define LL_ADC_REG_TRIG_EXT_FALLING (ADC_CR2_EXTEN_1 ) /*!< ADC group regular conversion trigger polarity set to falling edge */ +#define LL_ADC_REG_TRIG_EXT_RISINGFALLING (ADC_CR2_EXTEN_1 | ADC_CR2_EXTEN_0) /*!< ADC group regular conversion trigger polarity set to both rising and falling edges */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_CONTINUOUS_MODE ADC group regular - Continuous mode + * @{ + */ +#define LL_ADC_REG_CONV_SINGLE 0x00000000UL /*!< ADC conversions are performed in single mode: one conversion per trigger */ +#define LL_ADC_REG_CONV_CONTINUOUS (ADC_CR2_CONT) /*!< ADC conversions are performed in continuous mode: after the first trigger, following conversions launched successively automatically */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_DMA_TRANSFER ADC group regular - DMA transfer of ADC conversion data + * @{ + */ +#define LL_ADC_REG_DMA_TRANSFER_NONE 0x00000000UL /*!< ADC conversions are not transferred by DMA */ +#define LL_ADC_REG_DMA_TRANSFER_LIMITED ( ADC_CR2_DMA) /*!< ADC conversion data are transferred by DMA, in limited mode (one shot mode): DMA transfer requests are stopped when number of DMA data transfers (number of ADC conversions) is reached. This ADC mode is intended to be used with DMA mode non-circular. */ +#define LL_ADC_REG_DMA_TRANSFER_UNLIMITED (ADC_CR2_DDS | ADC_CR2_DMA) /*!< ADC conversion data are transferred by DMA, in unlimited mode: DMA transfer requests are unlimited, whatever number of DMA data transferred (number of ADC conversions). This ADC mode is intended to be used with DMA mode circular. */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_FLAG_EOC_SELECTION ADC group regular - Flag EOC selection (unitary or sequence conversions) + * @{ + */ +#define LL_ADC_REG_FLAG_EOC_SEQUENCE_CONV 0x00000000UL /*!< ADC flag EOC (end of unitary conversion) selected */ +#define LL_ADC_REG_FLAG_EOC_UNITARY_CONV (ADC_CR2_EOCS) /*!< ADC flag EOS (end of sequence conversions) selected */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_SEQ_SCAN_LENGTH ADC group regular - Sequencer scan length + * @{ + */ +#define LL_ADC_REG_SEQ_SCAN_DISABLE 0x00000000UL /*!< ADC group regular sequencer disable (equivalent to sequencer of 1 rank: ADC conversion on only 1 channel) */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS ( ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 2 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS ( ADC_SQR1_L_1 ) /*!< ADC group regular sequencer enable with 3 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS ( ADC_SQR1_L_1 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 4 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS ( ADC_SQR1_L_2 ) /*!< ADC group regular sequencer enable with 5 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS ( ADC_SQR1_L_2 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 6 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS ( ADC_SQR1_L_2 | ADC_SQR1_L_1 ) /*!< ADC group regular sequencer enable with 7 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS ( ADC_SQR1_L_2 | ADC_SQR1_L_1 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 8 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS (ADC_SQR1_L_3 ) /*!< ADC group regular sequencer enable with 9 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 10 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_1 ) /*!< ADC group regular sequencer enable with 11 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_1 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 12 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_2 ) /*!< ADC group regular sequencer enable with 13 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_2 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 14 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_2 | ADC_SQR1_L_1 ) /*!< ADC group regular sequencer enable with 15 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_2 | ADC_SQR1_L_1 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 16 ranks in the sequence */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_SEQ_DISCONT_MODE ADC group regular - Sequencer discontinuous mode + * @{ + */ +#define LL_ADC_REG_SEQ_DISCONT_DISABLE 0x00000000UL /*!< ADC group regular sequencer discontinuous mode disable */ +#define LL_ADC_REG_SEQ_DISCONT_1RANK ( ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every rank */ +#define LL_ADC_REG_SEQ_DISCONT_2RANKS ( ADC_CR1_DISCNUM_0 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enabled with sequence interruption every 2 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_3RANKS ( ADC_CR1_DISCNUM_1 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 3 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_4RANKS ( ADC_CR1_DISCNUM_1 | ADC_CR1_DISCNUM_0 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 4 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_5RANKS (ADC_CR1_DISCNUM_2 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 5 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_6RANKS (ADC_CR1_DISCNUM_2 | ADC_CR1_DISCNUM_0 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 6 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_7RANKS (ADC_CR1_DISCNUM_2 | ADC_CR1_DISCNUM_1 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 7 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_8RANKS (ADC_CR1_DISCNUM_2 | ADC_CR1_DISCNUM_1 | ADC_CR1_DISCNUM_0 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 8 ranks */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_SEQ_RANKS ADC group regular - Sequencer ranks + * @{ + */ +#define LL_ADC_REG_RANK_1 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_1_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 1 */ +#define LL_ADC_REG_RANK_2 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_2_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 2 */ +#define LL_ADC_REG_RANK_3 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_3_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 3 */ +#define LL_ADC_REG_RANK_4 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_4_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 4 */ +#define LL_ADC_REG_RANK_5 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_5_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 5 */ +#define LL_ADC_REG_RANK_6 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_6_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 6 */ +#define LL_ADC_REG_RANK_7 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_7_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 7 */ +#define LL_ADC_REG_RANK_8 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_8_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 8 */ +#define LL_ADC_REG_RANK_9 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_9_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 9 */ +#define LL_ADC_REG_RANK_10 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_10_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 10 */ +#define LL_ADC_REG_RANK_11 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_11_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 11 */ +#define LL_ADC_REG_RANK_12 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_12_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 12 */ +#define LL_ADC_REG_RANK_13 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_13_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 13 */ +#define LL_ADC_REG_RANK_14 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_14_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 14 */ +#define LL_ADC_REG_RANK_15 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_15_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 15 */ +#define LL_ADC_REG_RANK_16 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_16_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 16 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_TRIGGER_SOURCE ADC group injected - Trigger source + * @{ + */ +#define LL_ADC_INJ_TRIG_SOFTWARE 0x00000000UL /*!< ADC group injected conversion trigger internal: SW start. */ +#define LL_ADC_INJ_TRIG_EXT_TIM1_CH4 (ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM1 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM1_TRGO (ADC_CR2_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM1 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM2_CH1 (ADC_CR2_JEXTSEL_1 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM2 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM2_TRGO (ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM2 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM3_CH2 (ADC_CR2_JEXTSEL_2 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM3 channel 2 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM3_CH4 (ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM3 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM4_CH1 (ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM4 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM4_CH2 (ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM4 channel 2 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM4_CH3 (ADC_CR2_JEXTSEL_3 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM4 channel 3 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM4_TRGO (ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM4 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM5_CH4 (ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_1 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM5 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM5_TRGO (ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM5 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM8_CH2 (ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_2 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM8 channel 2 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM8_CH3 (ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM8 channel 3 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM8_CH4 (ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: TIM8 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_EXTI_LINE15 (ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected conversion trigger from external IP: external interrupt line 15. Trigger edge set to rising edge (default setting). */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_TRIGGER_EDGE ADC group injected - Trigger edge + * @{ + */ +#define LL_ADC_INJ_TRIG_EXT_RISING ( ADC_CR2_JEXTEN_0) /*!< ADC group injected conversion trigger polarity set to rising edge */ +#define LL_ADC_INJ_TRIG_EXT_FALLING (ADC_CR2_JEXTEN_1 ) /*!< ADC group injected conversion trigger polarity set to falling edge */ +#define LL_ADC_INJ_TRIG_EXT_RISINGFALLING (ADC_CR2_JEXTEN_1 | ADC_CR2_JEXTEN_0) /*!< ADC group injected conversion trigger polarity set to both rising and falling edges */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_TRIG_AUTO ADC group injected - Automatic trigger mode + * @{ + */ +#define LL_ADC_INJ_TRIG_INDEPENDENT 0x00000000UL /*!< ADC group injected conversion trigger independent. Setting mandatory if ADC group injected injected trigger source is set to an external trigger. */ +#define LL_ADC_INJ_TRIG_FROM_GRP_REGULAR (ADC_CR1_JAUTO) /*!< ADC group injected conversion trigger from ADC group regular. Setting compliant only with group injected trigger source set to SW start, without any further action on ADC group injected conversion start or stop: in this case, ADC group injected is controlled only from ADC group regular. */ +/** + * @} + */ + + +/** @defgroup ADC_LL_EC_INJ_SEQ_SCAN_LENGTH ADC group injected - Sequencer scan length + * @{ + */ +#define LL_ADC_INJ_SEQ_SCAN_DISABLE 0x00000000UL /*!< ADC group injected sequencer disable (equivalent to sequencer of 1 rank: ADC conversion on only 1 channel) */ +#define LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS ( ADC_JSQR_JL_0) /*!< ADC group injected sequencer enable with 2 ranks in the sequence */ +#define LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS (ADC_JSQR_JL_1 ) /*!< ADC group injected sequencer enable with 3 ranks in the sequence */ +#define LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS (ADC_JSQR_JL_1 | ADC_JSQR_JL_0) /*!< ADC group injected sequencer enable with 4 ranks in the sequence */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_SEQ_DISCONT_MODE ADC group injected - Sequencer discontinuous mode + * @{ + */ +#define LL_ADC_INJ_SEQ_DISCONT_DISABLE 0x00000000UL /*!< ADC group injected sequencer discontinuous mode disable */ +#define LL_ADC_INJ_SEQ_DISCONT_1RANK (ADC_CR1_JDISCEN) /*!< ADC group injected sequencer discontinuous mode enable with sequence interruption every rank */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_SEQ_RANKS ADC group injected - Sequencer ranks + * @{ + */ +#define LL_ADC_INJ_RANK_1 (ADC_JDR1_REGOFFSET | ADC_JOFR1_REGOFFSET | 0x00000001UL) /*!< ADC group injected sequencer rank 1 */ +#define LL_ADC_INJ_RANK_2 (ADC_JDR2_REGOFFSET | ADC_JOFR2_REGOFFSET | 0x00000002UL) /*!< ADC group injected sequencer rank 2 */ +#define LL_ADC_INJ_RANK_3 (ADC_JDR3_REGOFFSET | ADC_JOFR3_REGOFFSET | 0x00000003UL) /*!< ADC group injected sequencer rank 3 */ +#define LL_ADC_INJ_RANK_4 (ADC_JDR4_REGOFFSET | ADC_JOFR4_REGOFFSET | 0x00000004UL) /*!< ADC group injected sequencer rank 4 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_CHANNEL_SAMPLINGTIME Channel - Sampling time + * @{ + */ +#define LL_ADC_SAMPLINGTIME_3CYCLES 0x00000000UL /*!< Sampling time 3 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_15CYCLES (ADC_SMPR1_SMP10_0) /*!< Sampling time 15 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_28CYCLES (ADC_SMPR1_SMP10_1) /*!< Sampling time 28 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_56CYCLES (ADC_SMPR1_SMP10_1 | ADC_SMPR1_SMP10_0) /*!< Sampling time 56 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_84CYCLES (ADC_SMPR1_SMP10_2) /*!< Sampling time 84 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_112CYCLES (ADC_SMPR1_SMP10_2 | ADC_SMPR1_SMP10_0) /*!< Sampling time 112 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_144CYCLES (ADC_SMPR1_SMP10_2 | ADC_SMPR1_SMP10_1) /*!< Sampling time 144 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_480CYCLES (ADC_SMPR1_SMP10) /*!< Sampling time 480 ADC clock cycles */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_NUMBER Analog watchdog - Analog watchdog number + * @{ + */ +#define LL_ADC_AWD1 (ADC_AWD_CR1_CHANNEL_MASK | ADC_AWD_CR1_REGOFFSET) /*!< ADC analog watchdog number 1 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_CHANNELS Analog watchdog - Monitored channels + * @{ + */ +#define LL_ADC_AWD_DISABLE 0x00000000UL /*!< ADC analog watchdog monitoring disabled */ +#define LL_ADC_AWD_ALL_CHANNELS_REG ( ADC_CR1_AWDEN ) /*!< ADC analog watchdog monitoring of all channels, converted by group regular only */ +#define LL_ADC_AWD_ALL_CHANNELS_INJ ( ADC_CR1_JAWDEN ) /*!< ADC analog watchdog monitoring of all channels, converted by group injected only */ +#define LL_ADC_AWD_ALL_CHANNELS_REG_INJ ( ADC_CR1_JAWDEN | ADC_CR1_AWDEN ) /*!< ADC analog watchdog monitoring of all channels, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_0_REG ((LL_ADC_CHANNEL_0 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN0, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_0_INJ ((LL_ADC_CHANNEL_0 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN0, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_0_REG_INJ ((LL_ADC_CHANNEL_0 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN0, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_1_REG ((LL_ADC_CHANNEL_1 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN1, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_1_INJ ((LL_ADC_CHANNEL_1 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN1, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_1_REG_INJ ((LL_ADC_CHANNEL_1 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN1, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_2_REG ((LL_ADC_CHANNEL_2 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN2, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_2_INJ ((LL_ADC_CHANNEL_2 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN2, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_2_REG_INJ ((LL_ADC_CHANNEL_2 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN2, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_3_REG ((LL_ADC_CHANNEL_3 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN3, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_3_INJ ((LL_ADC_CHANNEL_3 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN3, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_3_REG_INJ ((LL_ADC_CHANNEL_3 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN3, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_4_REG ((LL_ADC_CHANNEL_4 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN4, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_4_INJ ((LL_ADC_CHANNEL_4 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN4, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_4_REG_INJ ((LL_ADC_CHANNEL_4 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN4, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_5_REG ((LL_ADC_CHANNEL_5 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN5, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_5_INJ ((LL_ADC_CHANNEL_5 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN5, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_5_REG_INJ ((LL_ADC_CHANNEL_5 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN5, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_6_REG ((LL_ADC_CHANNEL_6 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN6, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_6_INJ ((LL_ADC_CHANNEL_6 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN6, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_6_REG_INJ ((LL_ADC_CHANNEL_6 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN6, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_7_REG ((LL_ADC_CHANNEL_7 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN7, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_7_INJ ((LL_ADC_CHANNEL_7 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN7, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_7_REG_INJ ((LL_ADC_CHANNEL_7 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN7, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_8_REG ((LL_ADC_CHANNEL_8 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN8, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_8_INJ ((LL_ADC_CHANNEL_8 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN8, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_8_REG_INJ ((LL_ADC_CHANNEL_8 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN8, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_9_REG ((LL_ADC_CHANNEL_9 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN9, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_9_INJ ((LL_ADC_CHANNEL_9 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN9, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_9_REG_INJ ((LL_ADC_CHANNEL_9 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN9, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_10_REG ((LL_ADC_CHANNEL_10 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN10, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_10_INJ ((LL_ADC_CHANNEL_10 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN10, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_10_REG_INJ ((LL_ADC_CHANNEL_10 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN10, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_11_REG ((LL_ADC_CHANNEL_11 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN11, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_11_INJ ((LL_ADC_CHANNEL_11 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN11, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_11_REG_INJ ((LL_ADC_CHANNEL_11 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN11, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_12_REG ((LL_ADC_CHANNEL_12 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN12, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_12_INJ ((LL_ADC_CHANNEL_12 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN12, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_12_REG_INJ ((LL_ADC_CHANNEL_12 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN12, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_13_REG ((LL_ADC_CHANNEL_13 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN13, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_13_INJ ((LL_ADC_CHANNEL_13 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN13, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_13_REG_INJ ((LL_ADC_CHANNEL_13 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN13, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_14_REG ((LL_ADC_CHANNEL_14 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN14, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_14_INJ ((LL_ADC_CHANNEL_14 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN14, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_14_REG_INJ ((LL_ADC_CHANNEL_14 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN14, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_15_REG ((LL_ADC_CHANNEL_15 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN15, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_15_INJ ((LL_ADC_CHANNEL_15 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN15, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_15_REG_INJ ((LL_ADC_CHANNEL_15 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN15, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_16_REG ((LL_ADC_CHANNEL_16 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN16, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_16_INJ ((LL_ADC_CHANNEL_16 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN16, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_16_REG_INJ ((LL_ADC_CHANNEL_16 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN16, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_17_REG ((LL_ADC_CHANNEL_17 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN17, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_17_INJ ((LL_ADC_CHANNEL_17 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN17, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_17_REG_INJ ((LL_ADC_CHANNEL_17 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN17, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_18_REG ((LL_ADC_CHANNEL_18 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN18, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_18_INJ ((LL_ADC_CHANNEL_18 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN18, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_18_REG_INJ ((LL_ADC_CHANNEL_18 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN18, converted by either group regular or injected */ +#define LL_ADC_AWD_CH_VREFINT_REG ((LL_ADC_CHANNEL_VREFINT & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to VrefInt: Internal voltage reference, converted by group regular only */ +#define LL_ADC_AWD_CH_VREFINT_INJ ((LL_ADC_CHANNEL_VREFINT & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to VrefInt: Internal voltage reference, converted by group injected only */ +#define LL_ADC_AWD_CH_VREFINT_REG_INJ ((LL_ADC_CHANNEL_VREFINT & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to VrefInt: Internal voltage reference, converted by either group regular or injected */ +#define LL_ADC_AWD_CH_VBAT_REG ((LL_ADC_CHANNEL_VBAT & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Vbat/3: Vbat voltage through a divider ladder of factor 1/3 to have Vbat always below Vdda, converted by group regular only */ +#define LL_ADC_AWD_CH_VBAT_INJ ((LL_ADC_CHANNEL_VBAT & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Vbat/3: Vbat voltage through a divider ladder of factor 1/3 to have Vbat always below Vdda, converted by group injected only */ +#define LL_ADC_AWD_CH_VBAT_REG_INJ ((LL_ADC_CHANNEL_VBAT & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Vbat/3: Vbat voltage through a divider ladder of factor 1/3 to have Vbat always below Vdda */ +#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xx) || defined(STM32F407xx) || defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F415xx) || defined(STM32F417xx) +#define LL_ADC_AWD_CH_TEMPSENSOR_REG ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Temperature sensor, converted by group regular only */ +#define LL_ADC_AWD_CH_TEMPSENSOR_INJ ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Temperature sensor, converted by group injected only */ +#define LL_ADC_AWD_CH_TEMPSENSOR_REG_INJ ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Temperature sensor, converted by either group regular or injected */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F410xx */ +#if defined(STM32F411xE) || defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || defined(STM32F423xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +#define LL_ADC_AWD_CH_TEMPSENSOR_REG ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Temperature sensor, converted by group regular only. This internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. */ +#define LL_ADC_AWD_CH_TEMPSENSOR_INJ ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Temperature sensor, converted by group injected only. This internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. */ +#define LL_ADC_AWD_CH_TEMPSENSOR_REG_INJ ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Temperature sensor, converted by either group regular or injected. This internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. */ +#endif /* STM32F411xE || STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_THRESHOLDS Analog watchdog - Thresholds + * @{ + */ +#define LL_ADC_AWD_THRESHOLD_HIGH (ADC_AWD_TR1_HIGH_REGOFFSET) /*!< ADC analog watchdog threshold high */ +#define LL_ADC_AWD_THRESHOLD_LOW (ADC_AWD_TR1_LOW_REGOFFSET) /*!< ADC analog watchdog threshold low */ +/** + * @} + */ + +#if defined(ADC_MULTIMODE_SUPPORT) +/** @defgroup ADC_LL_EC_MULTI_MODE Multimode - Mode + * @{ + */ +#define LL_ADC_MULTI_INDEPENDENT 0x00000000UL /*!< ADC dual mode disabled (ADC independent mode) */ +#define LL_ADC_MULTI_DUAL_REG_SIMULT ( ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1 ) /*!< ADC dual mode enabled: group regular simultaneous */ +#define LL_ADC_MULTI_DUAL_REG_INTERL ( ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1 | ADC_CCR_MULTI_0) /*!< ADC dual mode enabled: Combined group regular interleaved */ +#define LL_ADC_MULTI_DUAL_INJ_SIMULT ( ADC_CCR_MULTI_2 | ADC_CCR_MULTI_0) /*!< ADC dual mode enabled: group injected simultaneous */ +#define LL_ADC_MULTI_DUAL_INJ_ALTERN (ADC_CCR_MULTI_3 | ADC_CCR_MULTI_0) /*!< ADC dual mode enabled: group injected alternate trigger. Works only with external triggers (not internal SW start) */ +#define LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM ( ADC_CCR_MULTI_0) /*!< ADC dual mode enabled: Combined group regular simultaneous + group injected simultaneous */ +#define LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT ( ADC_CCR_MULTI_1 ) /*!< ADC dual mode enabled: Combined group regular simultaneous + group injected alternate trigger */ +#define LL_ADC_MULTI_DUAL_REG_INT_INJ_SIM ( ADC_CCR_MULTI_1 | ADC_CCR_MULTI_0) /*!< ADC dual mode enabled: Combined group regular interleaved + group injected simultaneous */ +#if defined(ADC3) +#define LL_ADC_MULTI_TRIPLE_REG_SIM_INJ_SIM (ADC_CCR_MULTI_4 | ADC_CCR_MULTI_0) /*!< ADC triple mode enabled: Combined group regular simultaneous + group injected simultaneous */ +#define LL_ADC_MULTI_TRIPLE_REG_SIM_INJ_ALT (ADC_CCR_MULTI_4 | ADC_CCR_MULTI_1 ) /*!< ADC triple mode enabled: Combined group regular simultaneous + group injected alternate trigger */ +#define LL_ADC_MULTI_TRIPLE_INJ_SIMULT (ADC_CCR_MULTI_4 | ADC_CCR_MULTI_2 | ADC_CCR_MULTI_0) /*!< ADC triple mode enabled: group injected simultaneous */ +#define LL_ADC_MULTI_TRIPLE_REG_SIMULT (ADC_CCR_MULTI_4 | ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1 ) /*!< ADC triple mode enabled: group regular simultaneous */ +#define LL_ADC_MULTI_TRIPLE_REG_INTERL (ADC_CCR_MULTI_4 | ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1 | ADC_CCR_MULTI_0) /*!< ADC triple mode enabled: Combined group regular interleaved */ +#define LL_ADC_MULTI_TRIPLE_INJ_ALTERN (ADC_CCR_MULTI_4 | ADC_CCR_MULTI_0) /*!< ADC triple mode enabled: group injected alternate trigger. Works only with external triggers (not internal SW start) */ +#endif +/** + * @} + */ + +/** @defgroup ADC_LL_EC_MULTI_DMA_TRANSFER Multimode - DMA transfer + * @{ + */ +#define LL_ADC_MULTI_REG_DMA_EACH_ADC 0x00000000UL /*!< ADC multimode group regular conversions are transferred by DMA: each ADC uses its own DMA channel, with its individual DMA transfer settings */ +#define LL_ADC_MULTI_REG_DMA_LIMIT_1 ( ADC_CCR_DMA_0) /*!< ADC multimode group regular conversions are transferred by DMA, one DMA channel for all ADC instances (DMA of ADC master), in limited mode (one shot mode): DMA transfer requests are stopped when number of DMA data transfers (number of ADC conversions) is reached. This ADC mode is intended to be used with DMA mode non-circular. Setting of DMA mode 1: 2 or 3 (dual or triple mode) half-words one by one, ADC1 then ADC2 then ADC3. */ +#define LL_ADC_MULTI_REG_DMA_LIMIT_2 ( ADC_CCR_DMA_1 ) /*!< ADC multimode group regular conversions are transferred by DMA, one DMA channel for all ADC instances (DMA of ADC master), in limited mode (one shot mode): DMA transfer requests are stopped when number of DMA data transfers (number of ADC conversions) is reached. This ADC mode is intended to be used with DMA mode non-circular. Setting of DMA mode 2: 2 or 3 (dual or triple mode) half-words one by one, ADC2&1 then ADC1&3 then ADC3&2. */ +#define LL_ADC_MULTI_REG_DMA_LIMIT_3 ( ADC_CCR_DMA_1 | ADC_CCR_DMA_0) /*!< ADC multimode group regular conversions are transferred by DMA, one DMA channel for all ADC instances (DMA of ADC master), in limited mode (one shot mode): DMA transfer requests are stopped when number of DMA data transfers (number of ADC conversions) is reached. This ADC mode is intended to be used with DMA mode non-circular. Setting of DMA mode 3: 2 or 3 (dual or triple mode) bytes one by one, ADC2&1 then ADC1&3 then ADC3&2. */ +#define LL_ADC_MULTI_REG_DMA_UNLMT_1 (ADC_CCR_DDS | ADC_CCR_DMA_0) /*!< ADC multimode group regular conversions are transferred by DMA, one DMA channel for all ADC instances (DMA of ADC master), in unlimited mode: DMA transfer requests are unlimited, whatever number of DMA data transferred (number of ADC conversions) is reached. This ADC mode is intended to be used with DMA mode non-circular. Setting of DMA mode 1: 2 or 3 (dual or triple mode) half-words one by one, ADC1 then ADC2 then ADC3. */ +#define LL_ADC_MULTI_REG_DMA_UNLMT_2 (ADC_CCR_DDS | ADC_CCR_DMA_1 ) /*!< ADC multimode group regular conversions are transferred by DMA, one DMA channel for all ADC instances (DMA of ADC master), in unlimited mode: DMA transfer requests are unlimited, whatever number of DMA data transferred (number of ADC conversions) is reached. This ADC mode is intended to be used with DMA mode non-circular. Setting of DMA mode 2: 2 or 3 (dual or triple mode) half-words by pairs, ADC2&1 then ADC1&3 then ADC3&2. */ +#define LL_ADC_MULTI_REG_DMA_UNLMT_3 (ADC_CCR_DDS | ADC_CCR_DMA_1 | ADC_CCR_DMA_0) /*!< ADC multimode group regular conversions are transferred by DMA, one DMA channel for all ADC instances (DMA of ADC master), in unlimited mode: DMA transfer requests are unlimited, whatever number of DMA data transferred (number of ADC conversions) is reached. This ADC mode is intended to be used with DMA mode non-circular. Setting of DMA mode 3: 2 or 3 (dual or triple mode) bytes one by one, ADC2&1 then ADC1&3 then ADC3&2. */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_MULTI_TWOSMP_DELAY Multimode - Delay between two sampling phases + * @{ + */ +#define LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES 0x00000000UL /*!< ADC multimode delay between two sampling phases: 5 ADC clock cycles*/ +#define LL_ADC_MULTI_TWOSMP_DELAY_6CYCLES ( ADC_CCR_DELAY_0) /*!< ADC multimode delay between two sampling phases: 6 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_7CYCLES ( ADC_CCR_DELAY_1 ) /*!< ADC multimode delay between two sampling phases: 7 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_8CYCLES ( ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0) /*!< ADC multimode delay between two sampling phases: 8 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_9CYCLES ( ADC_CCR_DELAY_2 ) /*!< ADC multimode delay between two sampling phases: 9 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_10CYCLES ( ADC_CCR_DELAY_2 | ADC_CCR_DELAY_0) /*!< ADC multimode delay between two sampling phases: 10 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_11CYCLES ( ADC_CCR_DELAY_2 | ADC_CCR_DELAY_1 ) /*!< ADC multimode delay between two sampling phases: 11 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_12CYCLES ( ADC_CCR_DELAY_2 | ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0) /*!< ADC multimode delay between two sampling phases: 12 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_13CYCLES (ADC_CCR_DELAY_3 ) /*!< ADC multimode delay between two sampling phases: 13 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_14CYCLES (ADC_CCR_DELAY_3 | ADC_CCR_DELAY_0) /*!< ADC multimode delay between two sampling phases: 14 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_15CYCLES (ADC_CCR_DELAY_3 | ADC_CCR_DELAY_1 ) /*!< ADC multimode delay between two sampling phases: 15 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_16CYCLES (ADC_CCR_DELAY_3 | ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0) /*!< ADC multimode delay between two sampling phases: 16 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_17CYCLES (ADC_CCR_DELAY_3 | ADC_CCR_DELAY_2 ) /*!< ADC multimode delay between two sampling phases: 17 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_18CYCLES (ADC_CCR_DELAY_3 | ADC_CCR_DELAY_2 | ADC_CCR_DELAY_0) /*!< ADC multimode delay between two sampling phases: 18 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_19CYCLES (ADC_CCR_DELAY_3 | ADC_CCR_DELAY_2 | ADC_CCR_DELAY_1 ) /*!< ADC multimode delay between two sampling phases: 19 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_20CYCLES (ADC_CCR_DELAY_3 | ADC_CCR_DELAY_2 | ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0) /*!< ADC multimode delay between two sampling phases: 20 ADC clock cycles */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_MULTI_MASTER_SLAVE Multimode - ADC master or slave + * @{ + */ +#define LL_ADC_MULTI_MASTER ( ADC_CDR_RDATA_MST) /*!< In multimode, selection among several ADC instances: ADC master */ +#define LL_ADC_MULTI_SLAVE (ADC_CDR_RDATA_SLV ) /*!< In multimode, selection among several ADC instances: ADC slave */ +#define LL_ADC_MULTI_MASTER_SLAVE (ADC_CDR_RDATA_SLV | ADC_CDR_RDATA_MST) /*!< In multimode, selection among several ADC instances: both ADC master and ADC slave */ +/** + * @} + */ + +#endif /* ADC_MULTIMODE_SUPPORT */ + + +/** @defgroup ADC_LL_EC_HW_DELAYS Definitions of ADC hardware constraints delays + * @note Only ADC IP HW delays are defined in ADC LL driver driver, + * not timeout values. + * For details on delays values, refer to descriptions in source code + * above each literal definition. + * @{ + */ + +/* Note: Only ADC IP HW delays are defined in ADC LL driver driver, */ +/* not timeout values. */ +/* Timeout values for ADC operations are dependent to device clock */ +/* configuration (system clock versus ADC clock), */ +/* and therefore must be defined in user application. */ +/* Indications for estimation of ADC timeout delays, for this */ +/* STM32 series: */ +/* - ADC enable time: maximum delay is 2us */ +/* (refer to device datasheet, parameter "tSTAB") */ +/* - ADC conversion time: duration depending on ADC clock and ADC */ +/* configuration. */ +/* (refer to device reference manual, section "Timing") */ + +/* Delay for internal voltage reference stabilization time. */ +/* Delay set to maximum value (refer to device datasheet, */ +/* parameter "tSTART"). */ +/* Unit: us */ +#define LL_ADC_DELAY_VREFINT_STAB_US ( 10UL) /*!< Delay for internal voltage reference stabilization time */ + +/* Delay for temperature sensor stabilization time. */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tSTART"). */ +/* Unit: us */ +#define LL_ADC_DELAY_TEMPSENSOR_STAB_US ( 10UL) /*!< Delay for internal voltage reference stabilization time */ + +/** + * @} + */ + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ADC_LL_Exported_Macros ADC Exported Macros + * @{ + */ + +/** @defgroup ADC_LL_EM_WRITE_READ Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in ADC register + * @param __INSTANCE__ ADC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_ADC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in ADC register + * @param __INSTANCE__ ADC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_ADC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup ADC_LL_EM_HELPER_MACRO ADC helper macro + * @{ + */ + +/** + * @brief Helper macro to get ADC channel number in decimal format + * from literals LL_ADC_CHANNEL_x. + * @note Example: + * __LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_4) + * will return decimal number "4". + * @note The input can be a value from functions where a channel + * number is returned, either defined with number + * or with bitfield (only one bit must be set). + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. + * @retval Value between Min_Data=0 and Max_Data=18 + */ +#define __LL_ADC_CHANNEL_TO_DECIMAL_NB(__CHANNEL__) \ + (((__CHANNEL__) & ADC_CHANNEL_ID_NUMBER_MASK) >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) + +/** + * @brief Helper macro to get ADC channel in literal format LL_ADC_CHANNEL_x + * from number in decimal format. + * @note Example: + * __LL_ADC_DECIMAL_NB_TO_CHANNEL(4) + * will return a data equivalent to "LL_ADC_CHANNEL_4". + * @param __DECIMAL_NB__ Value between Min_Data=0 and Max_Data=18 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled.\n + * (1) For ADC channel read back from ADC register, + * comparison with internal channel parameter to be done + * using helper macro @ref __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(). + */ +#define __LL_ADC_DECIMAL_NB_TO_CHANNEL(__DECIMAL_NB__) \ + (((__DECIMAL_NB__) <= 9UL) \ + ? ( \ + ((__DECIMAL_NB__) << ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) | \ + (ADC_SMPR2_REGOFFSET | (((uint32_t) (3UL * (__DECIMAL_NB__))) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) \ + ) \ + : \ + ( \ + ((__DECIMAL_NB__) << ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) | \ + (ADC_SMPR1_REGOFFSET | (((uint32_t) (3UL * ((__DECIMAL_NB__) - 10UL))) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) \ + ) \ + ) + +/** + * @brief Helper macro to determine whether the selected channel + * corresponds to literal definitions of driver. + * @note The different literal definitions of ADC channels are: + * - ADC internal channel: + * LL_ADC_CHANNEL_VREFINT, LL_ADC_CHANNEL_TEMPSENSOR, ... + * - ADC external channel (channel connected to a GPIO pin): + * LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ... + * @note The channel parameter must be a value defined from literal + * definition of a ADC internal channel (LL_ADC_CHANNEL_VREFINT, + * LL_ADC_CHANNEL_TEMPSENSOR, ...), + * ADC external channel (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...), + * must not be a value from functions where a channel number is + * returned from ADC registers, + * because internal and external channels share the same channel + * number in ADC registers. The differentiation is made only with + * parameters definitions of driver. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. + * @retval Value "0" if the channel corresponds to a parameter definition of a ADC external channel (channel connected to a GPIO pin). + * Value "1" if the channel corresponds to a parameter definition of a ADC internal channel. + */ +#define __LL_ADC_IS_CHANNEL_INTERNAL(__CHANNEL__) \ + (((__CHANNEL__) & ADC_CHANNEL_ID_INTERNAL_CH_MASK) != 0UL) + +/** + * @brief Helper macro to convert a channel defined from parameter + * definition of a ADC internal channel (LL_ADC_CHANNEL_VREFINT, + * LL_ADC_CHANNEL_TEMPSENSOR, ...), + * to its equivalent parameter definition of a ADC external channel + * (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...). + * @note The channel parameter can be, additionally to a value + * defined from parameter definition of a ADC internal channel + * (LL_ADC_CHANNEL_VREFINT, LL_ADC_CHANNEL_TEMPSENSOR, ...), + * a value defined from parameter definition of + * ADC external channel (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...) + * or a value from functions where a channel number is returned + * from ADC registers. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + */ +#define __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(__CHANNEL__) \ + ((__CHANNEL__) & ~ADC_CHANNEL_ID_INTERNAL_CH_MASK) + +/** + * @brief Helper macro to determine whether the internal channel + * selected is available on the ADC instance selected. + * @note The channel parameter must be a value defined from parameter + * definition of a ADC internal channel (LL_ADC_CHANNEL_VREFINT, + * LL_ADC_CHANNEL_TEMPSENSOR, ...), + * must not be a value defined from parameter definition of + * ADC external channel (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...) + * or a value from functions where a channel number is + * returned from ADC registers, + * because internal and external channels share the same channel + * number in ADC registers. The differentiation is made only with + * parameters definitions of driver. + * @param __ADC_INSTANCE__ ADC instance + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1. + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. + * @retval Value "0" if the internal channel selected is not available on the ADC instance selected. + * Value "1" if the internal channel selected is available on the ADC instance selected. + */ +#define __LL_ADC_IS_CHANNEL_INTERNAL_AVAILABLE(__ADC_INSTANCE__, __CHANNEL__) \ + ( \ + ((__CHANNEL__) == LL_ADC_CHANNEL_VREFINT) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_TEMPSENSOR) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_VBAT) \ + ) +/** + * @brief Helper macro to define ADC analog watchdog parameter: + * define a single channel to monitor with analog watchdog + * from sequencer channel and groups definition. + * @note To be used with function @ref LL_ADC_SetAnalogWDMonitChannels(). + * Example: + * LL_ADC_SetAnalogWDMonitChannels( + * ADC1, LL_ADC_AWD1, + * __LL_ADC_ANALOGWD_CHANNEL_GROUP(LL_ADC_CHANNEL4, LL_ADC_GROUP_REGULAR)) + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled.\n + * (1) For ADC channel read back from ADC register, + * comparison with internal channel parameter to be done + * using helper macro @ref __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(). + * @param __GROUP__ This parameter can be one of the following values: + * @arg @ref LL_ADC_GROUP_REGULAR + * @arg @ref LL_ADC_GROUP_INJECTED + * @arg @ref LL_ADC_GROUP_REGULAR_INJECTED + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_AWD_DISABLE + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_INJ + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG + * @arg @ref LL_ADC_AWD_CHANNEL_0_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG + * @arg @ref LL_ADC_AWD_CHANNEL_1_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG + * @arg @ref LL_ADC_AWD_CHANNEL_2_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG + * @arg @ref LL_ADC_AWD_CHANNEL_3_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG + * @arg @ref LL_ADC_AWD_CHANNEL_4_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG + * @arg @ref LL_ADC_AWD_CHANNEL_5_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG + * @arg @ref LL_ADC_AWD_CHANNEL_6_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG + * @arg @ref LL_ADC_AWD_CHANNEL_7_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG + * @arg @ref LL_ADC_AWD_CHANNEL_8_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG + * @arg @ref LL_ADC_AWD_CHANNEL_9_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG + * @arg @ref LL_ADC_AWD_CHANNEL_10_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG + * @arg @ref LL_ADC_AWD_CHANNEL_11_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG + * @arg @ref LL_ADC_AWD_CHANNEL_12_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG + * @arg @ref LL_ADC_AWD_CHANNEL_13_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG + * @arg @ref LL_ADC_AWD_CHANNEL_14_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG + * @arg @ref LL_ADC_AWD_CHANNEL_15_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG + * @arg @ref LL_ADC_AWD_CHANNEL_16_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG + * @arg @ref LL_ADC_AWD_CHANNEL_17_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG + * @arg @ref LL_ADC_AWD_CHANNEL_18_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG_INJ + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG (1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_INJ (1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG_INJ (1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG (1)(2) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_INJ (1)(2) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG_INJ (1)(2) + * @arg @ref LL_ADC_AWD_CH_VBAT_REG (1) + * @arg @ref LL_ADC_AWD_CH_VBAT_INJ (1) + * @arg @ref LL_ADC_AWD_CH_VBAT_REG_INJ (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. + */ +#define __LL_ADC_ANALOGWD_CHANNEL_GROUP(__CHANNEL__, __GROUP__) \ + (((__GROUP__) == LL_ADC_GROUP_REGULAR) \ + ? (((__CHANNEL__) & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) \ + : \ + ((__GROUP__) == LL_ADC_GROUP_INJECTED) \ + ? (((__CHANNEL__) & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) \ + : \ + (((__CHANNEL__) & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) \ + ) + +/** + * @brief Helper macro to set the value of ADC analog watchdog threshold high + * or low in function of ADC resolution, when ADC resolution is + * different of 12 bits. + * @note To be used with function @ref LL_ADC_SetAnalogWDThresholds(). + * Example, with a ADC resolution of 8 bits, to set the value of + * analog watchdog threshold high (on 8 bits): + * LL_ADC_SetAnalogWDThresholds + * (< ADCx param >, + * __LL_ADC_ANALOGWD_SET_THRESHOLD_RESOLUTION(LL_ADC_RESOLUTION_8B, ) + * ); + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @param __AWD_THRESHOLD__ Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +#define __LL_ADC_ANALOGWD_SET_THRESHOLD_RESOLUTION(__ADC_RESOLUTION__, __AWD_THRESHOLD__) \ + ((__AWD_THRESHOLD__) << ((__ADC_RESOLUTION__) >> (ADC_CR1_RES_BITOFFSET_POS - 1UL ))) + +/** + * @brief Helper macro to get the value of ADC analog watchdog threshold high + * or low in function of ADC resolution, when ADC resolution is + * different of 12 bits. + * @note To be used with function @ref LL_ADC_GetAnalogWDThresholds(). + * Example, with a ADC resolution of 8 bits, to get the value of + * analog watchdog threshold high (on 8 bits): + * < threshold_value_6_bits > = __LL_ADC_ANALOGWD_GET_THRESHOLD_RESOLUTION + * (LL_ADC_RESOLUTION_8B, + * LL_ADC_GetAnalogWDThresholds(, LL_ADC_AWD_THRESHOLD_HIGH) + * ); + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @param __AWD_THRESHOLD_12_BITS__ Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +#define __LL_ADC_ANALOGWD_GET_THRESHOLD_RESOLUTION(__ADC_RESOLUTION__, __AWD_THRESHOLD_12_BITS__) \ + ((__AWD_THRESHOLD_12_BITS__) >> ((__ADC_RESOLUTION__) >> (ADC_CR1_RES_BITOFFSET_POS - 1UL ))) + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Helper macro to get the ADC multimode conversion data of ADC master + * or ADC slave from raw value with both ADC conversion data concatenated. + * @note This macro is intended to be used when multimode transfer by DMA + * is enabled: refer to function @ref LL_ADC_SetMultiDMATransfer(). + * In this case the transferred data need to processed with this macro + * to separate the conversion data of ADC master and ADC slave. + * @param __ADC_MULTI_MASTER_SLAVE__ This parameter can be one of the following values: + * @arg @ref LL_ADC_MULTI_MASTER + * @arg @ref LL_ADC_MULTI_SLAVE + * @param __ADC_MULTI_CONV_DATA__ Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +#define __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(__ADC_MULTI_MASTER_SLAVE__, __ADC_MULTI_CONV_DATA__) \ + (((__ADC_MULTI_CONV_DATA__) >> POSITION_VAL((__ADC_MULTI_MASTER_SLAVE__))) & ADC_CDR_RDATA_MST) +#endif + +/** + * @brief Helper macro to select the ADC common instance + * to which is belonging the selected ADC instance. + * @note ADC common register instance can be used for: + * - Set parameters common to several ADC instances + * - Multimode (for devices with several ADC instances) + * Refer to functions having argument "ADCxy_COMMON" as parameter. + * @param __ADCx__ ADC instance + * @retval ADC common register instance + */ +#if defined(ADC1) && defined(ADC2) && defined(ADC3) +#define __LL_ADC_COMMON_INSTANCE(__ADCx__) \ + (ADC123_COMMON) +#elif defined(ADC1) && defined(ADC2) +#define __LL_ADC_COMMON_INSTANCE(__ADCx__) \ + (ADC12_COMMON) +#else +#define __LL_ADC_COMMON_INSTANCE(__ADCx__) \ + (ADC1_COMMON) +#endif + +/** + * @brief Helper macro to check if all ADC instances sharing the same + * ADC common instance are disabled. + * @note This check is required by functions with setting conditioned to + * ADC state: + * All ADC instances of the ADC common group must be disabled. + * Refer to functions having argument "ADCxy_COMMON" as parameter. + * @note On devices with only 1 ADC common instance, parameter of this macro + * is useless and can be ignored (parameter kept for compatibility + * with devices featuring several ADC common instances). + * @param __ADCXY_COMMON__ ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval Value "0" if all ADC instances sharing the same ADC common instance + * are disabled. + * Value "1" if at least one ADC instance sharing the same ADC common instance + * is enabled. + */ +#if defined(ADC1) && defined(ADC2) && defined(ADC3) +#define __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__ADCXY_COMMON__) \ + (LL_ADC_IsEnabled(ADC1) | \ + LL_ADC_IsEnabled(ADC2) | \ + LL_ADC_IsEnabled(ADC3) ) +#elif defined(ADC1) && defined(ADC2) +#define __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__ADCXY_COMMON__) \ + (LL_ADC_IsEnabled(ADC1) | \ + LL_ADC_IsEnabled(ADC2) ) +#else +#define __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__ADCXY_COMMON__) \ + (LL_ADC_IsEnabled(ADC1)) +#endif + +/** + * @brief Helper macro to define the ADC conversion data full-scale digital + * value corresponding to the selected ADC resolution. + * @note ADC conversion data full-scale corresponds to voltage range + * determined by analog voltage references Vref+ and Vref- + * (refer to reference manual). + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval ADC conversion data equivalent voltage value (unit: mVolt) + */ +#define __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__) \ + (0xFFFU >> ((__ADC_RESOLUTION__) >> (ADC_CR1_RES_BITOFFSET_POS - 1UL))) + +/** + * @brief Helper macro to convert the ADC conversion data from + * a resolution to another resolution. + * @param __DATA__ ADC conversion data to be converted + * @param __ADC_RESOLUTION_CURRENT__ Resolution of to the data to be converted + * This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @param __ADC_RESOLUTION_TARGET__ Resolution of the data after conversion + * This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval ADC conversion data to the requested resolution + */ +#define __LL_ADC_CONVERT_DATA_RESOLUTION(__DATA__, __ADC_RESOLUTION_CURRENT__, __ADC_RESOLUTION_TARGET__) \ + (((__DATA__) \ + << ((__ADC_RESOLUTION_CURRENT__) >> (ADC_CR1_RES_BITOFFSET_POS - 1UL))) \ + >> ((__ADC_RESOLUTION_TARGET__) >> (ADC_CR1_RES_BITOFFSET_POS - 1UL)) \ + ) + +/** + * @brief Helper macro to calculate the voltage (unit: mVolt) + * corresponding to a ADC conversion data (unit: digital value). + * @note Analog reference voltage (Vref+) must be either known from + * user board environment or can be calculated using ADC measurement + * and ADC helper macro @ref __LL_ADC_CALC_VREFANALOG_VOLTAGE(). + * @param __VREFANALOG_VOLTAGE__ Analog reference voltage (unit mV) + * @param __ADC_DATA__ ADC conversion data (resolution 12 bits) + * (unit: digital value). + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval ADC conversion data equivalent voltage value (unit: mVolt) + */ +#define __LL_ADC_CALC_DATA_TO_VOLTAGE(__VREFANALOG_VOLTAGE__,\ + __ADC_DATA__,\ + __ADC_RESOLUTION__) \ + ((__ADC_DATA__) * (__VREFANALOG_VOLTAGE__) \ + / __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__) \ + ) + +/** + * @brief Helper macro to calculate analog reference voltage (Vref+) + * (unit: mVolt) from ADC conversion data of internal voltage + * reference VrefInt. + * @note Computation is using VrefInt calibration value + * stored in system memory for each device during production. + * @note This voltage depends on user board environment: voltage level + * connected to pin Vref+. + * On devices with small package, the pin Vref+ is not present + * and internally bonded to pin Vdda. + * @note On this STM32 series, calibration data of internal voltage reference + * VrefInt corresponds to a resolution of 12 bits, + * this is the recommended ADC resolution to convert voltage of + * internal voltage reference VrefInt. + * Otherwise, this macro performs the processing to scale + * ADC conversion data to 12 bits. + * @param __VREFINT_ADC_DATA__ ADC conversion data (resolution 12 bits) + * of internal voltage reference VrefInt (unit: digital value). + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval Analog reference voltage (unit: mV) + */ +#define __LL_ADC_CALC_VREFANALOG_VOLTAGE(__VREFINT_ADC_DATA__,\ + __ADC_RESOLUTION__) \ + (((uint32_t)(*VREFINT_CAL_ADDR) * VREFINT_CAL_VREF) \ + / __LL_ADC_CONVERT_DATA_RESOLUTION((__VREFINT_ADC_DATA__), \ + (__ADC_RESOLUTION__), \ + LL_ADC_RESOLUTION_12B)) + +/* Note: On device STM32F4x9, calibration parameter TS_CAL2 is not available. */ +/* Therefore, helper macro __LL_ADC_CALC_TEMPERATURE() is not available.*/ +/* Use helper macro @ref __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(). */ +#if !defined(STM32F469) && !defined(STM32F479xx) && !defined(STM32F429xx) && !defined(STM32F439xx) +/** + * @brief Helper macro to calculate the temperature (unit: degree Celsius) + * from ADC conversion data of internal temperature sensor. + * @note Computation is using temperature sensor calibration values + * stored in system memory for each device during production. + * @note Calculation formula: + * Temperature = ((TS_ADC_DATA - TS_CAL1) + * * (TS_CAL2_TEMP - TS_CAL1_TEMP)) + * / (TS_CAL2 - TS_CAL1) + TS_CAL1_TEMP + * with TS_ADC_DATA = temperature sensor raw data measured by ADC + * Avg_Slope = (TS_CAL2 - TS_CAL1) + * / (TS_CAL2_TEMP - TS_CAL1_TEMP) + * TS_CAL1 = equivalent TS_ADC_DATA at temperature + * TEMP_DEGC_CAL1 (calibrated in factory) + * TS_CAL2 = equivalent TS_ADC_DATA at temperature + * TEMP_DEGC_CAL2 (calibrated in factory) + * Caution: Calculation relevancy under reserve that calibration + * parameters are correct (address and data). + * To calculate temperature using temperature sensor + * datasheet typical values (generic values less, therefore + * less accurate than calibrated values), + * use helper macro @ref __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(). + * @note As calculation input, the analog reference voltage (Vref+) must be + * defined as it impacts the ADC LSB equivalent voltage. + * @note Analog reference voltage (Vref+) must be either known from + * user board environment or can be calculated using ADC measurement + * and ADC helper macro @ref __LL_ADC_CALC_VREFANALOG_VOLTAGE(). + * @note On this STM32 series, calibration data of temperature sensor + * corresponds to a resolution of 12 bits, + * this is the recommended ADC resolution to convert voltage of + * temperature sensor. + * Otherwise, this macro performs the processing to scale + * ADC conversion data to 12 bits. + * @param __VREFANALOG_VOLTAGE__ Analog reference voltage (unit mV) + * @param __TEMPSENSOR_ADC_DATA__ ADC conversion data of internal + * temperature sensor (unit: digital value). + * @param __ADC_RESOLUTION__ ADC resolution at which internal temperature + * sensor voltage has been measured. + * This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval Temperature (unit: degree Celsius) + */ +#define __LL_ADC_CALC_TEMPERATURE(__VREFANALOG_VOLTAGE__,\ + __TEMPSENSOR_ADC_DATA__,\ + __ADC_RESOLUTION__) \ + (((( ((int32_t)((__LL_ADC_CONVERT_DATA_RESOLUTION((__TEMPSENSOR_ADC_DATA__), \ + (__ADC_RESOLUTION__), \ + LL_ADC_RESOLUTION_12B) \ + * (__VREFANALOG_VOLTAGE__)) \ + / TEMPSENSOR_CAL_VREFANALOG) \ + - (int32_t) *TEMPSENSOR_CAL1_ADDR) \ + ) * (int32_t)(TEMPSENSOR_CAL2_TEMP - TEMPSENSOR_CAL1_TEMP) \ + ) / (int32_t)((int32_t)*TEMPSENSOR_CAL2_ADDR - (int32_t)*TEMPSENSOR_CAL1_ADDR) \ + ) + TEMPSENSOR_CAL1_TEMP \ + ) +#endif + +/** + * @brief Helper macro to calculate the temperature (unit: degree Celsius) + * from ADC conversion data of internal temperature sensor. + * @note Computation is using temperature sensor typical values + * (refer to device datasheet). + * @note Calculation formula: + * Temperature = (TS_TYP_CALx_VOLT(uV) - TS_ADC_DATA * Conversion_uV) + * / Avg_Slope + CALx_TEMP + * with TS_ADC_DATA = temperature sensor raw data measured by ADC + * (unit: digital value) + * Avg_Slope = temperature sensor slope + * (unit: uV/Degree Celsius) + * TS_TYP_CALx_VOLT = temperature sensor digital value at + * temperature CALx_TEMP (unit: mV) + * Caution: Calculation relevancy under reserve the temperature sensor + * of the current device has characteristics in line with + * datasheet typical values. + * If temperature sensor calibration values are available on + * on this device (presence of macro __LL_ADC_CALC_TEMPERATURE()), + * temperature calculation will be more accurate using + * helper macro @ref __LL_ADC_CALC_TEMPERATURE(). + * @note As calculation input, the analog reference voltage (Vref+) must be + * defined as it impacts the ADC LSB equivalent voltage. + * @note Analog reference voltage (Vref+) must be either known from + * user board environment or can be calculated using ADC measurement + * and ADC helper macro @ref __LL_ADC_CALC_VREFANALOG_VOLTAGE(). + * @note ADC measurement data must correspond to a resolution of 12bits + * (full scale digital value 4095). If not the case, the data must be + * preliminarily rescaled to an equivalent resolution of 12 bits. + * @param __TEMPSENSOR_TYP_AVGSLOPE__ Device datasheet data Temperature sensor slope typical value (unit uV/DegCelsius). + * On STM32F4, refer to device datasheet parameter "Avg_Slope". + * @param __TEMPSENSOR_TYP_CALX_V__ Device datasheet data Temperature sensor voltage typical value (at temperature and Vref+ defined in parameters below) (unit mV). + * On STM32F4, refer to device datasheet parameter "V25". + * @param __TEMPSENSOR_CALX_TEMP__ Device datasheet data Temperature at which temperature sensor voltage (see parameter above) is corresponding (unit mV) + * @param __VREFANALOG_VOLTAGE__ Analog voltage reference (Vref+) voltage (unit mV) + * @param __TEMPSENSOR_ADC_DATA__ ADC conversion data of internal temperature sensor (unit digital value). + * @param __ADC_RESOLUTION__ ADC resolution at which internal temperature sensor voltage has been measured. + * This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval Temperature (unit: degree Celsius) + */ +#define __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(__TEMPSENSOR_TYP_AVGSLOPE__,\ + __TEMPSENSOR_TYP_CALX_V__,\ + __TEMPSENSOR_CALX_TEMP__,\ + __VREFANALOG_VOLTAGE__,\ + __TEMPSENSOR_ADC_DATA__,\ + __ADC_RESOLUTION__) \ + ((( ( \ + (int32_t)(((__TEMPSENSOR_TYP_CALX_V__)) \ + * 1000) \ + - \ + (int32_t)((((__TEMPSENSOR_ADC_DATA__) * (__VREFANALOG_VOLTAGE__)) \ + / __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__)) \ + * 1000) \ + ) \ + ) / (__TEMPSENSOR_TYP_AVGSLOPE__) \ + ) + (__TEMPSENSOR_CALX_TEMP__) \ + ) + +/** + * @} + */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup ADC_LL_Exported_Functions ADC Exported Functions + * @{ + */ + +/** @defgroup ADC_LL_EF_DMA_Management ADC DMA management + * @{ + */ +/* Note: LL ADC functions to set DMA transfer are located into sections of */ +/* configuration of ADC instance, groups and multimode (if available): */ +/* @ref LL_ADC_REG_SetDMATransfer(), ... */ + +/** + * @brief Function to help to configure DMA transfer from ADC: retrieve the + * ADC register address from ADC instance and a list of ADC registers + * intended to be used (most commonly) with DMA transfer. + * @note These ADC registers are data registers: + * when ADC conversion data is available in ADC data registers, + * ADC generates a DMA transfer request. + * @note This macro is intended to be used with LL DMA driver, refer to + * function "LL_DMA_ConfigAddresses()". + * Example: + * LL_DMA_ConfigAddresses(DMA1, + * LL_DMA_CHANNEL_1, + * LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA), + * (uint32_t)&< array or variable >, + * LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + * @note For devices with several ADC: in multimode, some devices + * use a different data register outside of ADC instance scope + * (common data register). This macro manages this register difference, + * only ADC instance has to be set as parameter. + * @rmtoll DR RDATA LL_ADC_DMA_GetRegAddr\n + * CDR RDATA_MST LL_ADC_DMA_GetRegAddr\n + * CDR RDATA_SLV LL_ADC_DMA_GetRegAddr + * @param ADCx ADC instance + * @param Register This parameter can be one of the following values: + * @arg @ref LL_ADC_DMA_REG_REGULAR_DATA + * @arg @ref LL_ADC_DMA_REG_REGULAR_DATA_MULTI (1) + * + * (1) Available on devices with several ADC instances. + * @retval ADC register address + */ +#if defined(ADC_MULTIMODE_SUPPORT) +__STATIC_INLINE uint32_t LL_ADC_DMA_GetRegAddr(const ADC_TypeDef *ADCx, uint32_t Register) +{ + uint32_t data_reg_addr = 0UL; + + if (Register == LL_ADC_DMA_REG_REGULAR_DATA) + { + /* Retrieve address of register DR */ + data_reg_addr = (uint32_t) & (ADCx->DR); + } + else /* (Register == LL_ADC_DMA_REG_REGULAR_DATA_MULTI) */ + { + /* Retrieve address of register CDR */ + data_reg_addr = (uint32_t) & ((__LL_ADC_COMMON_INSTANCE(ADCx))->CDR); + } + + return data_reg_addr; +} +#else +__STATIC_INLINE uint32_t LL_ADC_DMA_GetRegAddr(ADC_TypeDef *ADCx, uint32_t Register) +{ + /* Prevent unused argument compilation warning */ + (void)Register; + + /* Retrieve address of register DR */ + return (uint32_t) & (ADCx->DR); +} +#endif + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Common Configuration of ADC hierarchical scope: common to several ADC instances + * @{ + */ + +/** + * @brief Set parameter common to several ADC: Clock source and prescaler. + * @rmtoll CCR ADCPRE LL_ADC_SetCommonClock + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @param CommonClock This parameter can be one of the following values: + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV2 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV4 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV6 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV8 + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetCommonClock(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t CommonClock) +{ + MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_ADCPRE, CommonClock); +} + +/** + * @brief Get parameter common to several ADC: Clock source and prescaler. + * @rmtoll CCR ADCPRE LL_ADC_GetCommonClock + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV2 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV4 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV6 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV8 + */ +__STATIC_INLINE uint32_t LL_ADC_GetCommonClock(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CCR, ADC_CCR_ADCPRE)); +} + +/** + * @brief Set parameter common to several ADC: measurement path to internal + * channels (VrefInt, temperature sensor, ...). + * @note One or several values can be selected. + * Example: (LL_ADC_PATH_INTERNAL_VREFINT | + * LL_ADC_PATH_INTERNAL_TEMPSENSOR) + * @note Stabilization time of measurement path to internal channel: + * After enabling internal paths, before starting ADC conversion, + * a delay is required for internal voltage reference and + * temperature sensor stabilization time. + * Refer to device datasheet. + * Refer to literal @ref LL_ADC_DELAY_VREFINT_STAB_US. + * Refer to literal @ref LL_ADC_DELAY_TEMPSENSOR_STAB_US. + * @note ADC internal channel sampling time constraint: + * For ADC conversion of internal channels, + * a sampling time minimum value is required. + * Refer to device datasheet. + * @rmtoll CCR TSVREFE LL_ADC_SetCommonPathInternalCh\n + * CCR VBATE LL_ADC_SetCommonPathInternalCh + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @param PathInternal This parameter can be a combination of the following values: + * @arg @ref LL_ADC_PATH_INTERNAL_NONE + * @arg @ref LL_ADC_PATH_INTERNAL_VREFINT + * @arg @ref LL_ADC_PATH_INTERNAL_TEMPSENSOR + * @arg @ref LL_ADC_PATH_INTERNAL_VBAT + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetCommonPathInternalCh(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t PathInternal) +{ + MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_TSVREFE | ADC_CCR_VBATE, PathInternal); +} + +/** + * @brief Get parameter common to several ADC: measurement path to internal + * channels (VrefInt, temperature sensor, ...). + * @note One or several values can be selected. + * Example: (LL_ADC_PATH_INTERNAL_VREFINT | + * LL_ADC_PATH_INTERNAL_TEMPSENSOR) + * @rmtoll CCR TSVREFE LL_ADC_GetCommonPathInternalCh\n + * CCR VBATE LL_ADC_GetCommonPathInternalCh + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_ADC_PATH_INTERNAL_NONE + * @arg @ref LL_ADC_PATH_INTERNAL_VREFINT + * @arg @ref LL_ADC_PATH_INTERNAL_TEMPSENSOR + * @arg @ref LL_ADC_PATH_INTERNAL_VBAT + */ +__STATIC_INLINE uint32_t LL_ADC_GetCommonPathInternalCh(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CCR, ADC_CCR_TSVREFE | ADC_CCR_VBATE)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Instance Configuration of ADC hierarchical scope: ADC instance + * @{ + */ + +/** + * @brief Set ADC resolution. + * Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @rmtoll CR1 RES LL_ADC_SetResolution + * @param ADCx ADC instance + * @param Resolution This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetResolution(ADC_TypeDef *ADCx, uint32_t Resolution) +{ + MODIFY_REG(ADCx->CR1, ADC_CR1_RES, Resolution); +} + +/** + * @brief Get ADC resolution. + * Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @rmtoll CR1 RES LL_ADC_GetResolution + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + */ +__STATIC_INLINE uint32_t LL_ADC_GetResolution(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, ADC_CR1_RES)); +} + +/** + * @brief Set ADC conversion data alignment. + * @note Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @rmtoll CR2 ALIGN LL_ADC_SetDataAlignment + * @param ADCx ADC instance + * @param DataAlignment This parameter can be one of the following values: + * @arg @ref LL_ADC_DATA_ALIGN_RIGHT + * @arg @ref LL_ADC_DATA_ALIGN_LEFT + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetDataAlignment(ADC_TypeDef *ADCx, uint32_t DataAlignment) +{ + MODIFY_REG(ADCx->CR2, ADC_CR2_ALIGN, DataAlignment); +} + +/** + * @brief Get ADC conversion data alignment. + * @note Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @rmtoll CR2 ALIGN LL_ADC_SetDataAlignment + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_DATA_ALIGN_RIGHT + * @arg @ref LL_ADC_DATA_ALIGN_LEFT + */ +__STATIC_INLINE uint32_t LL_ADC_GetDataAlignment(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_ALIGN)); +} + +/** + * @brief Set ADC sequencers scan mode, for all ADC groups + * (group regular, group injected). + * @note According to sequencers scan mode : + * - If disabled: ADC conversion is performed in unitary conversion + * mode (one channel converted, that defined in rank 1). + * Configuration of sequencers of all ADC groups + * (sequencer scan length, ...) is discarded: equivalent to + * scan length of 1 rank. + * - If enabled: ADC conversions are performed in sequence conversions + * mode, according to configuration of sequencers of + * each ADC group (sequencer scan length, ...). + * Refer to function @ref LL_ADC_REG_SetSequencerLength() + * and to function @ref LL_ADC_INJ_SetSequencerLength(). + * @rmtoll CR1 SCAN LL_ADC_SetSequencersScanMode + * @param ADCx ADC instance + * @param ScanMode This parameter can be one of the following values: + * @arg @ref LL_ADC_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_SEQ_SCAN_ENABLE + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetSequencersScanMode(ADC_TypeDef *ADCx, uint32_t ScanMode) +{ + MODIFY_REG(ADCx->CR1, ADC_CR1_SCAN, ScanMode); +} + +/** + * @brief Get ADC sequencers scan mode, for all ADC groups + * (group regular, group injected). + * @note According to sequencers scan mode : + * - If disabled: ADC conversion is performed in unitary conversion + * mode (one channel converted, that defined in rank 1). + * Configuration of sequencers of all ADC groups + * (sequencer scan length, ...) is discarded: equivalent to + * scan length of 1 rank. + * - If enabled: ADC conversions are performed in sequence conversions + * mode, according to configuration of sequencers of + * each ADC group (sequencer scan length, ...). + * Refer to function @ref LL_ADC_REG_SetSequencerLength() + * and to function @ref LL_ADC_INJ_SetSequencerLength(). + * @rmtoll CR1 SCAN LL_ADC_GetSequencersScanMode + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_SEQ_SCAN_ENABLE + */ +__STATIC_INLINE uint32_t LL_ADC_GetSequencersScanMode(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, ADC_CR1_SCAN)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Group_Regular Configuration of ADC hierarchical scope: group regular + * @{ + */ + +/** + * @brief Set ADC group regular conversion trigger source: + * internal (SW start) or from external IP (timer event, + * external interrupt line). + * @note On this STM32 series, setting of external trigger edge is performed + * using function @ref LL_ADC_REG_StartConversionExtTrig(). + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR2 EXTSEL LL_ADC_REG_SetTriggerSource\n + * CR2 EXTEN LL_ADC_REG_SetTriggerSource + * @param ADCx ADC instance + * @param TriggerSource This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_SOFTWARE + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH2 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH3 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH2 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH3 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH4 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM4_CH4 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM5_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM5_CH2 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM5_CH3 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_EXTI_LINE11 + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetTriggerSource(ADC_TypeDef *ADCx, uint32_t TriggerSource) +{ + /* Note: On this STM32 series, ADC group regular external trigger edge */ + /* is used to perform a ADC conversion start. */ + /* This function does not set external trigger edge. */ + /* This feature is set using function */ + /* @ref LL_ADC_REG_StartConversionExtTrig(). */ + MODIFY_REG(ADCx->CR2, ADC_CR2_EXTSEL, (TriggerSource & ADC_CR2_EXTSEL)); +} + +/** + * @brief Get ADC group regular conversion trigger source: + * internal (SW start) or from external IP (timer event, + * external interrupt line). + * @note To determine whether group regular trigger source is + * internal (SW start) or external, without detail + * of which peripheral is selected as external trigger, + * (equivalent to + * "if(LL_ADC_REG_GetTriggerSource(ADC1) == LL_ADC_REG_TRIG_SOFTWARE)") + * use function @ref LL_ADC_REG_IsTriggerSourceSWStart. + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR2 EXTSEL LL_ADC_REG_GetTriggerSource\n + * CR2 EXTEN LL_ADC_REG_GetTriggerSource + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_SOFTWARE + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH2 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH3 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH2 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH3 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH4 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM4_CH4 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM5_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM5_CH2 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM5_CH3 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_EXTI_LINE11 + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetTriggerSource(const ADC_TypeDef *ADCx) +{ + uint32_t TriggerSource = READ_BIT(ADCx->CR2, ADC_CR2_EXTSEL | ADC_CR2_EXTEN); + + /* Value for shift of {0; 4; 8; 12} depending on value of bitfield */ + /* corresponding to ADC_CR2_EXTEN {0; 1; 2; 3}. */ + uint32_t ShiftExten = ((TriggerSource & ADC_CR2_EXTEN) >> (ADC_REG_TRIG_EXTEN_BITOFFSET_POS - 2UL)); + + /* Set bitfield corresponding to ADC_CR2_EXTEN and ADC_CR2_EXTSEL */ + /* to match with triggers literals definition. */ + return ((TriggerSource + & (ADC_REG_TRIG_SOURCE_MASK << ShiftExten) & ADC_CR2_EXTSEL) + | ((ADC_REG_TRIG_EDGE_MASK << ShiftExten) & ADC_CR2_EXTEN) + ); +} + +/** + * @brief Get ADC group regular conversion trigger source internal (SW start) + or external. + * @note In case of group regular trigger source set to external trigger, + * to determine which peripheral is selected as external trigger, + * use function @ref LL_ADC_REG_GetTriggerSource(). + * @rmtoll CR2 EXTEN LL_ADC_REG_IsTriggerSourceSWStart + * @param ADCx ADC instance + * @retval Value "0" if trigger source external trigger + * Value "1" if trigger source SW start. + */ +__STATIC_INLINE uint32_t LL_ADC_REG_IsTriggerSourceSWStart(const ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR2, ADC_CR2_EXTEN) == (LL_ADC_REG_TRIG_SOFTWARE & ADC_CR2_EXTEN)); +} + +/** + * @brief Get ADC group regular conversion trigger polarity. + * @note Applicable only for trigger source set to external trigger. + * @note On this STM32 series, setting of external trigger edge is performed + * using function @ref LL_ADC_REG_StartConversionExtTrig(). + * @rmtoll CR2 EXTEN LL_ADC_REG_GetTriggerEdge + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_EXT_RISING + * @arg @ref LL_ADC_REG_TRIG_EXT_FALLING + * @arg @ref LL_ADC_REG_TRIG_EXT_RISINGFALLING + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetTriggerEdge(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_EXTEN)); +} + + +/** + * @brief Set ADC group regular sequencer length and scan direction. + * @note Description of ADC group regular sequencer features: + * - For devices with sequencer fully configurable + * (function "LL_ADC_REG_SetSequencerRanks()" available): + * sequencer length and each rank affectation to a channel + * are configurable. + * This function performs configuration of: + * - Sequence length: Number of ranks in the scan sequence. + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from rank 1 to rank n). + * Sequencer ranks are selected using + * function "LL_ADC_REG_SetSequencerRanks()". + * - For devices with sequencer not fully configurable + * (function "LL_ADC_REG_SetSequencerChannels()" available): + * sequencer length and each rank affectation to a channel + * are defined by channel number. + * This function performs configuration of: + * - Sequence length: Number of ranks in the scan sequence is + * defined by number of channels set in the sequence, + * rank of each channel is fixed by channel HW number. + * (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from lowest channel number to + * highest channel number). + * Sequencer ranks are selected using + * function "LL_ADC_REG_SetSequencerChannels()". + * @note On this STM32 series, group regular sequencer configuration + * is conditioned to ADC instance sequencer mode. + * If ADC instance sequencer mode is disabled, sequencers of + * all groups (group regular, group injected) can be configured + * but their execution is disabled (limited to rank 1). + * Refer to function @ref LL_ADC_SetSequencersScanMode(). + * @note Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @rmtoll SQR1 L LL_ADC_REG_SetSequencerLength + * @param ADCx ADC instance + * @param SequencerNbRanks This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetSequencerLength(ADC_TypeDef *ADCx, uint32_t SequencerNbRanks) +{ + MODIFY_REG(ADCx->SQR1, ADC_SQR1_L, SequencerNbRanks); +} + +/** + * @brief Get ADC group regular sequencer length and scan direction. + * @note Description of ADC group regular sequencer features: + * - For devices with sequencer fully configurable + * (function "LL_ADC_REG_SetSequencerRanks()" available): + * sequencer length and each rank affectation to a channel + * are configurable. + * This function retrieves: + * - Sequence length: Number of ranks in the scan sequence. + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from rank 1 to rank n). + * Sequencer ranks are selected using + * function "LL_ADC_REG_SetSequencerRanks()". + * - For devices with sequencer not fully configurable + * (function "LL_ADC_REG_SetSequencerChannels()" available): + * sequencer length and each rank affectation to a channel + * are defined by channel number. + * This function retrieves: + * - Sequence length: Number of ranks in the scan sequence is + * defined by number of channels set in the sequence, + * rank of each channel is fixed by channel HW number. + * (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from lowest channel number to + * highest channel number). + * Sequencer ranks are selected using + * function "LL_ADC_REG_SetSequencerChannels()". + * @note On this STM32 series, group regular sequencer configuration + * is conditioned to ADC instance sequencer mode. + * If ADC instance sequencer mode is disabled, sequencers of + * all groups (group regular, group injected) can be configured + * but their execution is disabled (limited to rank 1). + * Refer to function @ref LL_ADC_SetSequencersScanMode(). + * @note Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @rmtoll SQR1 L LL_ADC_REG_SetSequencerLength + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetSequencerLength(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->SQR1, ADC_SQR1_L)); +} + +/** + * @brief Set ADC group regular sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @note It is not possible to enable both ADC group regular + * continuous mode and sequencer discontinuous mode. + * @note It is not possible to enable both ADC auto-injected mode + * and ADC group regular sequencer discontinuous mode. + * @rmtoll CR1 DISCEN LL_ADC_REG_SetSequencerDiscont\n + * CR1 DISCNUM LL_ADC_REG_SetSequencerDiscont + * @param ADCx ADC instance + * @param SeqDiscont This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_DISCONT_DISABLE + * @arg @ref LL_ADC_REG_SEQ_DISCONT_1RANK + * @arg @ref LL_ADC_REG_SEQ_DISCONT_2RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_3RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_4RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_5RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_6RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_7RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_8RANKS + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetSequencerDiscont(ADC_TypeDef *ADCx, uint32_t SeqDiscont) +{ + MODIFY_REG(ADCx->CR1, ADC_CR1_DISCEN | ADC_CR1_DISCNUM, SeqDiscont); +} + +/** + * @brief Get ADC group regular sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @rmtoll CR1 DISCEN LL_ADC_REG_GetSequencerDiscont\n + * CR1 DISCNUM LL_ADC_REG_GetSequencerDiscont + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_DISCONT_DISABLE + * @arg @ref LL_ADC_REG_SEQ_DISCONT_1RANK + * @arg @ref LL_ADC_REG_SEQ_DISCONT_2RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_3RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_4RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_5RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_6RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_7RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_8RANKS + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetSequencerDiscont(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, ADC_CR1_DISCEN | ADC_CR1_DISCNUM)); +} + +/** + * @brief Set ADC group regular sequence: channel on the selected + * scan sequence rank. + * @note This function performs configuration of: + * - Channels ordering into each rank of scan sequence: + * whatever channel can be placed into whatever rank. + * @note On this STM32 series, ADC group regular sequencer is + * fully configurable: sequencer length and each rank + * affectation to a channel are configurable. + * Refer to description of function @ref LL_ADC_REG_SetSequencerLength(). + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note On this STM32 series, to measure internal channels (VrefInt, + * TempSensor, ...), measurement paths to internal channels must be + * enabled separately. + * This can be done using function @ref LL_ADC_SetCommonPathInternalCh(). + * @rmtoll SQR3 SQ1 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ2 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ3 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ4 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ5 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ6 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ7 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ8 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ9 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ10 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ11 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ12 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ13 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ14 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ15 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ16 LL_ADC_REG_SetSequencerRanks + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_RANK_1 + * @arg @ref LL_ADC_REG_RANK_2 + * @arg @ref LL_ADC_REG_RANK_3 + * @arg @ref LL_ADC_REG_RANK_4 + * @arg @ref LL_ADC_REG_RANK_5 + * @arg @ref LL_ADC_REG_RANK_6 + * @arg @ref LL_ADC_REG_RANK_7 + * @arg @ref LL_ADC_REG_RANK_8 + * @arg @ref LL_ADC_REG_RANK_9 + * @arg @ref LL_ADC_REG_RANK_10 + * @arg @ref LL_ADC_REG_RANK_11 + * @arg @ref LL_ADC_REG_RANK_12 + * @arg @ref LL_ADC_REG_RANK_13 + * @arg @ref LL_ADC_REG_RANK_14 + * @arg @ref LL_ADC_REG_RANK_15 + * @arg @ref LL_ADC_REG_RANK_16 + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetSequencerRanks(ADC_TypeDef *ADCx, uint32_t Rank, uint32_t Channel) +{ + /* Set bits with content of parameter "Channel" with bits position */ + /* in register and register position depending on parameter "Rank". */ + /* Parameters "Rank" and "Channel" are used with masks because containing */ + /* other bits reserved for other purpose. */ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->SQR1, __ADC_MASK_SHIFT(Rank, ADC_REG_SQRX_REGOFFSET_MASK)); + + MODIFY_REG(*preg, + ADC_CHANNEL_ID_NUMBER_MASK << (Rank & ADC_REG_RANK_ID_SQRX_MASK), + (Channel & ADC_CHANNEL_ID_NUMBER_MASK) << (Rank & ADC_REG_RANK_ID_SQRX_MASK)); +} + +/** + * @brief Get ADC group regular sequence: channel on the selected + * scan sequence rank. + * @note On this STM32 series, ADC group regular sequencer is + * fully configurable: sequencer length and each rank + * affectation to a channel are configurable. + * Refer to description of function @ref LL_ADC_REG_SetSequencerLength(). + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note Usage of the returned channel number: + * - To reinject this channel into another function LL_ADC_xxx: + * the returned channel number is only partly formatted on definition + * of literals LL_ADC_CHANNEL_x. Therefore, it has to be compared + * with parts of literals LL_ADC_CHANNEL_x or using + * helper macro @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * Then the selected literal LL_ADC_CHANNEL_x can be used + * as parameter for another function. + * - To get the channel number in decimal format: + * process the returned value with the helper macro + * @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * @rmtoll SQR3 SQ1 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ2 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ3 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ4 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ5 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ6 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ7 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ8 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ9 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ10 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ11 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ12 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ13 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ14 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ15 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ16 LL_ADC_REG_GetSequencerRanks + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_RANK_1 + * @arg @ref LL_ADC_REG_RANK_2 + * @arg @ref LL_ADC_REG_RANK_3 + * @arg @ref LL_ADC_REG_RANK_4 + * @arg @ref LL_ADC_REG_RANK_5 + * @arg @ref LL_ADC_REG_RANK_6 + * @arg @ref LL_ADC_REG_RANK_7 + * @arg @ref LL_ADC_REG_RANK_8 + * @arg @ref LL_ADC_REG_RANK_9 + * @arg @ref LL_ADC_REG_RANK_10 + * @arg @ref LL_ADC_REG_RANK_11 + * @arg @ref LL_ADC_REG_RANK_12 + * @arg @ref LL_ADC_REG_RANK_13 + * @arg @ref LL_ADC_REG_RANK_14 + * @arg @ref LL_ADC_REG_RANK_15 + * @arg @ref LL_ADC_REG_RANK_16 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled.\n + * (1) For ADC channel read back from ADC register, + * comparison with internal channel parameter to be done + * using helper macro @ref __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(). + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetSequencerRanks(const ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t const *preg = __ADC_PTR_REG_OFFSET(ADCx->SQR1, __ADC_MASK_SHIFT(Rank, ADC_REG_SQRX_REGOFFSET_MASK)); + + return (uint32_t)(READ_BIT(*preg, + ADC_CHANNEL_ID_NUMBER_MASK << (Rank & ADC_REG_RANK_ID_SQRX_MASK)) + >> (Rank & ADC_REG_RANK_ID_SQRX_MASK) + ); +} + +/** + * @brief Set ADC continuous conversion mode on ADC group regular. + * @note Description of ADC continuous conversion mode: + * - single mode: one conversion per trigger + * - continuous mode: after the first trigger, following + * conversions launched successively automatically. + * @note It is not possible to enable both ADC group regular + * continuous mode and sequencer discontinuous mode. + * @rmtoll CR2 CONT LL_ADC_REG_SetContinuousMode + * @param ADCx ADC instance + * @param Continuous This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_CONV_SINGLE + * @arg @ref LL_ADC_REG_CONV_CONTINUOUS + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetContinuousMode(ADC_TypeDef *ADCx, uint32_t Continuous) +{ + MODIFY_REG(ADCx->CR2, ADC_CR2_CONT, Continuous); +} + +/** + * @brief Get ADC continuous conversion mode on ADC group regular. + * @note Description of ADC continuous conversion mode: + * - single mode: one conversion per trigger + * - continuous mode: after the first trigger, following + * conversions launched successively automatically. + * @rmtoll CR2 CONT LL_ADC_REG_GetContinuousMode + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_CONV_SINGLE + * @arg @ref LL_ADC_REG_CONV_CONTINUOUS + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetContinuousMode(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_CONT)); +} + +/** + * @brief Set ADC group regular conversion data transfer: no transfer or + * transfer by DMA, and DMA requests mode. + * @note If transfer by DMA selected, specifies the DMA requests + * mode: + * - Limited mode (One shot mode): DMA transfer requests are stopped + * when number of DMA data transfers (number of + * ADC conversions) is reached. + * This ADC mode is intended to be used with DMA mode non-circular. + * - Unlimited mode: DMA transfer requests are unlimited, + * whatever number of DMA data transfers (number of + * ADC conversions). + * This ADC mode is intended to be used with DMA mode circular. + * @note If ADC DMA requests mode is set to unlimited and DMA is set to + * mode non-circular: + * when DMA transfers size will be reached, DMA will stop transfers of + * ADC conversions data ADC will raise an overrun error + * (overrun flag and interruption if enabled). + * @note For devices with several ADC instances: ADC multimode DMA + * settings are available using function @ref LL_ADC_SetMultiDMATransfer(). + * @note To configure DMA source address (peripheral address), + * use function @ref LL_ADC_DMA_GetRegAddr(). + * @rmtoll CR2 DMA LL_ADC_REG_SetDMATransfer\n + * CR2 DDS LL_ADC_REG_SetDMATransfer + * @param ADCx ADC instance + * @param DMATransfer This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_DMA_TRANSFER_NONE + * @arg @ref LL_ADC_REG_DMA_TRANSFER_LIMITED + * @arg @ref LL_ADC_REG_DMA_TRANSFER_UNLIMITED + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetDMATransfer(ADC_TypeDef *ADCx, uint32_t DMATransfer) +{ + MODIFY_REG(ADCx->CR2, ADC_CR2_DMA | ADC_CR2_DDS, DMATransfer); +} + +/** + * @brief Get ADC group regular conversion data transfer: no transfer or + * transfer by DMA, and DMA requests mode. + * @note If transfer by DMA selected, specifies the DMA requests + * mode: + * - Limited mode (One shot mode): DMA transfer requests are stopped + * when number of DMA data transfers (number of + * ADC conversions) is reached. + * This ADC mode is intended to be used with DMA mode non-circular. + * - Unlimited mode: DMA transfer requests are unlimited, + * whatever number of DMA data transfers (number of + * ADC conversions). + * This ADC mode is intended to be used with DMA mode circular. + * @note If ADC DMA requests mode is set to unlimited and DMA is set to + * mode non-circular: + * when DMA transfers size will be reached, DMA will stop transfers of + * ADC conversions data ADC will raise an overrun error + * (overrun flag and interruption if enabled). + * @note For devices with several ADC instances: ADC multimode DMA + * settings are available using function @ref LL_ADC_GetMultiDMATransfer(). + * @note To configure DMA source address (peripheral address), + * use function @ref LL_ADC_DMA_GetRegAddr(). + * @rmtoll CR2 DMA LL_ADC_REG_GetDMATransfer\n + * CR2 DDS LL_ADC_REG_GetDMATransfer + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_DMA_TRANSFER_NONE + * @arg @ref LL_ADC_REG_DMA_TRANSFER_LIMITED + * @arg @ref LL_ADC_REG_DMA_TRANSFER_UNLIMITED + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetDMATransfer(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_DMA | ADC_CR2_DDS)); +} + +/** + * @brief Specify which ADC flag between EOC (end of unitary conversion) + * or EOS (end of sequence conversions) is used to indicate + * the end of conversion. + * @note This feature is aimed to be set when using ADC with + * programming model by polling or interruption + * (programming model by DMA usually uses DMA interruptions + * to indicate end of conversion and data transfer). + * @note For ADC group injected, end of conversion (flag&IT) is raised + * only at the end of the sequence. + * @rmtoll CR2 EOCS LL_ADC_REG_SetFlagEndOfConversion + * @param ADCx ADC instance + * @param EocSelection This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_FLAG_EOC_SEQUENCE_CONV + * @arg @ref LL_ADC_REG_FLAG_EOC_UNITARY_CONV + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetFlagEndOfConversion(ADC_TypeDef *ADCx, uint32_t EocSelection) +{ + MODIFY_REG(ADCx->CR2, ADC_CR2_EOCS, EocSelection); +} + +/** + * @brief Get which ADC flag between EOC (end of unitary conversion) + * or EOS (end of sequence conversions) is used to indicate + * the end of conversion. + * @rmtoll CR2 EOCS LL_ADC_REG_GetFlagEndOfConversion + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_FLAG_EOC_SEQUENCE_CONV + * @arg @ref LL_ADC_REG_FLAG_EOC_UNITARY_CONV + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetFlagEndOfConversion(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_EOCS)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Group_Injected Configuration of ADC hierarchical scope: group injected + * @{ + */ + +/** + * @brief Set ADC group injected conversion trigger source: + * internal (SW start) or from external IP (timer event, + * external interrupt line). + * @note On this STM32 series, setting of external trigger edge is performed + * using function @ref LL_ADC_INJ_StartConversionExtTrig(). + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR2 JEXTSEL LL_ADC_INJ_SetTriggerSource\n + * CR2 JEXTEN LL_ADC_INJ_SetTriggerSource + * @param ADCx ADC instance + * @param TriggerSource This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_SOFTWARE + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH2 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_CH2 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_CH3 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM5_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM5_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH2 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH3 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_EXTI_LINE15 + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetTriggerSource(ADC_TypeDef *ADCx, uint32_t TriggerSource) +{ + /* Note: On this STM32 series, ADC group injected external trigger edge */ + /* is used to perform a ADC conversion start. */ + /* This function does not set external trigger edge. */ + /* This feature is set using function */ + /* @ref LL_ADC_INJ_StartConversionExtTrig(). */ + MODIFY_REG(ADCx->CR2, ADC_CR2_JEXTSEL, (TriggerSource & ADC_CR2_JEXTSEL)); +} + +/** + * @brief Get ADC group injected conversion trigger source: + * internal (SW start) or from external IP (timer event, + * external interrupt line). + * @note To determine whether group injected trigger source is + * internal (SW start) or external, without detail + * of which peripheral is selected as external trigger, + * (equivalent to + * "if(LL_ADC_INJ_GetTriggerSource(ADC1) == LL_ADC_INJ_TRIG_SOFTWARE)") + * use function @ref LL_ADC_INJ_IsTriggerSourceSWStart. + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR2 JEXTSEL LL_ADC_INJ_GetTriggerSource\n + * CR2 JEXTEN LL_ADC_INJ_GetTriggerSource + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_SOFTWARE + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH2 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_CH2 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_CH3 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM5_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM5_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH2 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH3 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_EXTI_LINE15 + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetTriggerSource(const ADC_TypeDef *ADCx) +{ + uint32_t TriggerSource = READ_BIT(ADCx->CR2, ADC_CR2_JEXTSEL | ADC_CR2_JEXTEN); + + /* Value for shift of {0; 4; 8; 12} depending on value of bitfield */ + /* corresponding to ADC_CR2_JEXTEN {0; 1; 2; 3}. */ + uint32_t ShiftExten = ((TriggerSource & ADC_CR2_JEXTEN) >> (ADC_INJ_TRIG_EXTEN_BITOFFSET_POS - 2UL)); + + /* Set bitfield corresponding to ADC_CR2_JEXTEN and ADC_CR2_JEXTSEL */ + /* to match with triggers literals definition. */ + return ((TriggerSource + & (ADC_INJ_TRIG_SOURCE_MASK << ShiftExten) & ADC_CR2_JEXTSEL) + | ((ADC_INJ_TRIG_EDGE_MASK << ShiftExten) & ADC_CR2_JEXTEN) + ); +} + +/** + * @brief Get ADC group injected conversion trigger source internal (SW start) + or external + * @note In case of group injected trigger source set to external trigger, + * to determine which peripheral is selected as external trigger, + * use function @ref LL_ADC_INJ_GetTriggerSource. + * @rmtoll CR2 JEXTEN LL_ADC_INJ_IsTriggerSourceSWStart + * @param ADCx ADC instance + * @retval Value "0" if trigger source external trigger + * Value "1" if trigger source SW start. + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_IsTriggerSourceSWStart(const ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR2, ADC_CR2_JEXTEN) == (LL_ADC_INJ_TRIG_SOFTWARE & ADC_CR2_JEXTEN)); +} + +/** + * @brief Get ADC group injected conversion trigger polarity. + * Applicable only for trigger source set to external trigger. + * @rmtoll CR2 JEXTEN LL_ADC_INJ_GetTriggerEdge + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_EXT_RISING + * @arg @ref LL_ADC_INJ_TRIG_EXT_FALLING + * @arg @ref LL_ADC_INJ_TRIG_EXT_RISINGFALLING + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetTriggerEdge(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_JEXTEN)); +} + +/** + * @brief Set ADC group injected sequencer length and scan direction. + * @note This function performs configuration of: + * - Sequence length: Number of ranks in the scan sequence. + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from rank 1 to rank n). + * @note On this STM32 series, group injected sequencer configuration + * is conditioned to ADC instance sequencer mode. + * If ADC instance sequencer mode is disabled, sequencers of + * all groups (group regular, group injected) can be configured + * but their execution is disabled (limited to rank 1). + * Refer to function @ref LL_ADC_SetSequencersScanMode(). + * @note Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @rmtoll JSQR JL LL_ADC_INJ_SetSequencerLength + * @param ADCx ADC instance + * @param SequencerNbRanks This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetSequencerLength(ADC_TypeDef *ADCx, uint32_t SequencerNbRanks) +{ + MODIFY_REG(ADCx->JSQR, ADC_JSQR_JL, SequencerNbRanks); +} + +/** + * @brief Get ADC group injected sequencer length and scan direction. + * @note This function retrieves: + * - Sequence length: Number of ranks in the scan sequence. + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from rank 1 to rank n). + * @note On this STM32 series, group injected sequencer configuration + * is conditioned to ADC instance sequencer mode. + * If ADC instance sequencer mode is disabled, sequencers of + * all groups (group regular, group injected) can be configured + * but their execution is disabled (limited to rank 1). + * Refer to function @ref LL_ADC_SetSequencersScanMode(). + * @note Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @rmtoll JSQR JL LL_ADC_INJ_GetSequencerLength + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INJ_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetSequencerLength(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->JSQR, ADC_JSQR_JL)); +} + +/** + * @brief Set ADC group injected sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @note It is not possible to enable both ADC group injected + * auto-injected mode and sequencer discontinuous mode. + * @rmtoll CR1 DISCEN LL_ADC_INJ_SetSequencerDiscont + * @param ADCx ADC instance + * @param SeqDiscont This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_SEQ_DISCONT_DISABLE + * @arg @ref LL_ADC_INJ_SEQ_DISCONT_1RANK + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetSequencerDiscont(ADC_TypeDef *ADCx, uint32_t SeqDiscont) +{ + MODIFY_REG(ADCx->CR1, ADC_CR1_JDISCEN, SeqDiscont); +} + +/** + * @brief Get ADC group injected sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @rmtoll CR1 DISCEN LL_ADC_REG_GetSequencerDiscont + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INJ_SEQ_DISCONT_DISABLE + * @arg @ref LL_ADC_INJ_SEQ_DISCONT_1RANK + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetSequencerDiscont(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, ADC_CR1_JDISCEN)); +} + +/** + * @brief Set ADC group injected sequence: channel on the selected + * sequence rank. + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note On this STM32 series, to measure internal channels (VrefInt, + * TempSensor, ...), measurement paths to internal channels must be + * enabled separately. + * This can be done using function @ref LL_ADC_SetCommonPathInternalCh(). + * @rmtoll JSQR JSQ1 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ2 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ3 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ4 LL_ADC_INJ_SetSequencerRanks + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetSequencerRanks(ADC_TypeDef *ADCx, uint32_t Rank, uint32_t Channel) +{ + /* Set bits with content of parameter "Channel" with bits position */ + /* in register depending on parameter "Rank". */ + /* Parameters "Rank" and "Channel" are used with masks because containing */ + /* other bits reserved for other purpose. */ + uint32_t tmpreg1 = (READ_BIT(ADCx->JSQR, ADC_JSQR_JL) >> ADC_JSQR_JL_Pos) + 1UL; + + MODIFY_REG(ADCx->JSQR, + ADC_CHANNEL_ID_NUMBER_MASK << (5UL * (uint8_t)(((Rank) + 3UL) - (tmpreg1))), + (Channel & ADC_CHANNEL_ID_NUMBER_MASK) << (5UL * (uint8_t)(((Rank) + 3UL) - (tmpreg1)))); +} + +/** + * @brief Get ADC group injected sequence: channel on the selected + * sequence rank. + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note Usage of the returned channel number: + * - To reinject this channel into another function LL_ADC_xxx: + * the returned channel number is only partly formatted on definition + * of literals LL_ADC_CHANNEL_x. Therefore, it has to be compared + * with parts of literals LL_ADC_CHANNEL_x or using + * helper macro @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * Then the selected literal LL_ADC_CHANNEL_x can be used + * as parameter for another function. + * - To get the channel number in decimal format: + * process the returned value with the helper macro + * @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * @rmtoll JSQR JSQ1 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ2 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ3 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ4 LL_ADC_INJ_SetSequencerRanks + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled.\n + * (1) For ADC channel read back from ADC register, + * comparison with internal channel parameter to be done + * using helper macro @ref __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(). + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetSequencerRanks(const ADC_TypeDef *ADCx, uint32_t Rank) +{ + uint32_t tmpreg1 = (READ_BIT(ADCx->JSQR, ADC_JSQR_JL) >> ADC_JSQR_JL_Pos) + 1UL; + + return (uint32_t)(READ_BIT(ADCx->JSQR, + ADC_CHANNEL_ID_NUMBER_MASK << (5UL * (uint8_t)(((Rank) + 3UL) - (tmpreg1)))) + >> (5UL * (uint8_t)(((Rank) + 3UL) - (tmpreg1))) + ); +} + +/** + * @brief Set ADC group injected conversion trigger: + * independent or from ADC group regular. + * @note This mode can be used to extend number of data registers + * updated after one ADC conversion trigger and with data + * permanently kept (not erased by successive conversions of scan of + * ADC sequencer ranks), up to 5 data registers: + * 1 data register on ADC group regular, 4 data registers + * on ADC group injected. + * @note If ADC group injected injected trigger source is set to an + * external trigger, this feature must be must be set to + * independent trigger. + * ADC group injected automatic trigger is compliant only with + * group injected trigger source set to SW start, without any + * further action on ADC group injected conversion start or stop: + * in this case, ADC group injected is controlled only + * from ADC group regular. + * @note It is not possible to enable both ADC group injected + * auto-injected mode and sequencer discontinuous mode. + * @rmtoll CR1 JAUTO LL_ADC_INJ_SetTrigAuto + * @param ADCx ADC instance + * @param TrigAuto This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_INDEPENDENT + * @arg @ref LL_ADC_INJ_TRIG_FROM_GRP_REGULAR + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetTrigAuto(ADC_TypeDef *ADCx, uint32_t TrigAuto) +{ + MODIFY_REG(ADCx->CR1, ADC_CR1_JAUTO, TrigAuto); +} + +/** + * @brief Get ADC group injected conversion trigger: + * independent or from ADC group regular. + * @rmtoll CR1 JAUTO LL_ADC_INJ_GetTrigAuto + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_INDEPENDENT + * @arg @ref LL_ADC_INJ_TRIG_FROM_GRP_REGULAR + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetTrigAuto(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, ADC_CR1_JAUTO)); +} + +/** + * @brief Set ADC group injected offset. + * @note It sets: + * - ADC group injected rank to which the offset programmed + * will be applied + * - Offset level (offset to be subtracted from the raw + * converted data). + * Caution: Offset format is dependent to ADC resolution: + * offset has to be left-aligned on bit 11, the LSB (right bits) + * are set to 0. + * @note Offset cannot be enabled or disabled. + * To emulate offset disabled, set an offset value equal to 0. + * @rmtoll JOFR1 JOFFSET1 LL_ADC_INJ_SetOffset\n + * JOFR2 JOFFSET2 LL_ADC_INJ_SetOffset\n + * JOFR3 JOFFSET3 LL_ADC_INJ_SetOffset\n + * JOFR4 JOFFSET4 LL_ADC_INJ_SetOffset + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @param OffsetLevel Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetOffset(ADC_TypeDef *ADCx, uint32_t Rank, uint32_t OffsetLevel) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->JOFR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JOFRX_REGOFFSET_MASK)); + + MODIFY_REG(*preg, + ADC_JOFR1_JOFFSET1, + OffsetLevel); +} + +/** + * @brief Get ADC group injected offset. + * @note It gives offset level (offset to be subtracted from the raw converted data). + * Caution: Offset format is dependent to ADC resolution: + * offset has to be left-aligned on bit 11, the LSB (right bits) + * are set to 0. + * @rmtoll JOFR1 JOFFSET1 LL_ADC_INJ_GetOffset\n + * JOFR2 JOFFSET2 LL_ADC_INJ_GetOffset\n + * JOFR3 JOFFSET3 LL_ADC_INJ_GetOffset\n + * JOFR4 JOFFSET4 LL_ADC_INJ_GetOffset + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetOffset(const ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t const *preg = __ADC_PTR_REG_OFFSET(ADCx->JOFR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JOFRX_REGOFFSET_MASK)); + + return (uint32_t)(READ_BIT(*preg, + ADC_JOFR1_JOFFSET1) + ); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_Channels Configuration of ADC hierarchical scope: channels + * @{ + */ + +/** + * @brief Set sampling time of the selected ADC channel + * Unit: ADC clock cycles. + * @note On this device, sampling time is on channel scope: independently + * of channel mapped on ADC group regular or injected. + * @note In case of internal channel (VrefInt, TempSensor, ...) to be + * converted: + * sampling time constraints must be respected (sampling time can be + * adjusted in function of ADC clock frequency and sampling time + * setting). + * Refer to device datasheet for timings values (parameters TS_vrefint, + * TS_temp, ...). + * @note Conversion time is the addition of sampling time and processing time. + * Refer to reference manual for ADC processing time of + * this STM32 series. + * @note In case of ADC conversion of internal channel (VrefInt, + * temperature sensor, ...), a sampling time minimum value + * is required. + * Refer to device datasheet. + * @rmtoll SMPR1 SMP18 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP17 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP16 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP15 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP14 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP13 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP12 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP11 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP10 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP9 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP8 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP7 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP6 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP5 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP4 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP3 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP2 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP1 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP0 LL_ADC_SetChannelSamplingTime + * @param ADCx ADC instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. + * @param SamplingTime This parameter can be one of the following values: + * @arg @ref LL_ADC_SAMPLINGTIME_3CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_15CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_28CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_56CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_84CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_112CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_144CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_480CYCLES + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetChannelSamplingTime(ADC_TypeDef *ADCx, uint32_t Channel, uint32_t SamplingTime) +{ + /* Set bits with content of parameter "SamplingTime" with bits position */ + /* in register and register position depending on parameter "Channel". */ + /* Parameter "Channel" is used with masks because containing */ + /* other bits reserved for other purpose. */ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->SMPR1, __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPRX_REGOFFSET_MASK)); + + MODIFY_REG(*preg, + ADC_SMPR2_SMP0 << __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPx_BITOFFSET_MASK), + SamplingTime << __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPx_BITOFFSET_MASK)); +} + +/** + * @brief Get sampling time of the selected ADC channel + * Unit: ADC clock cycles. + * @note On this device, sampling time is on channel scope: independently + * of channel mapped on ADC group regular or injected. + * @note Conversion time is the addition of sampling time and processing time. + * Refer to reference manual for ADC processing time of + * this STM32 series. + * @rmtoll SMPR1 SMP18 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP17 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP16 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP15 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP14 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP13 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP12 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP11 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP10 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP9 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP8 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP7 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP6 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP5 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP4 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP3 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP2 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP1 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP0 LL_ADC_GetChannelSamplingTime + * @param ADCx ADC instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_SAMPLINGTIME_3CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_15CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_28CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_56CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_84CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_112CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_144CYCLES + * @arg @ref LL_ADC_SAMPLINGTIME_480CYCLES + */ +__STATIC_INLINE uint32_t LL_ADC_GetChannelSamplingTime(const ADC_TypeDef *ADCx, uint32_t Channel) +{ + __IO uint32_t const *preg = __ADC_PTR_REG_OFFSET(ADCx->SMPR1, __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPRX_REGOFFSET_MASK)); + + return (uint32_t)(READ_BIT(*preg, + ADC_SMPR2_SMP0 << __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPx_BITOFFSET_MASK)) + >> __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPx_BITOFFSET_MASK) + ); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_AnalogWatchdog Configuration of ADC transversal scope: analog watchdog + * @{ + */ + +/** + * @brief Set ADC analog watchdog monitored channels: + * a single channel or all channels, + * on ADC groups regular and-or injected. + * @note Once monitored channels are selected, analog watchdog + * is enabled. + * @note In case of need to define a single channel to monitor + * with analog watchdog from sequencer channel definition, + * use helper macro @ref __LL_ADC_ANALOGWD_CHANNEL_GROUP(). + * @note On this STM32 series, there is only 1 kind of analog watchdog + * instance: + * - AWD standard (instance AWD1): + * - channels monitored: can monitor 1 channel or all channels. + * - groups monitored: ADC groups regular and-or injected. + * - resolution: resolution is not limited (corresponds to + * ADC resolution configured). + * @rmtoll CR1 AWD1CH LL_ADC_SetAnalogWDMonitChannels\n + * CR1 AWD1SGL LL_ADC_SetAnalogWDMonitChannels\n + * CR1 AWD1EN LL_ADC_SetAnalogWDMonitChannels + * @param ADCx ADC instance + * @param AWDChannelGroup This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_DISABLE + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_INJ + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG + * @arg @ref LL_ADC_AWD_CHANNEL_0_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG + * @arg @ref LL_ADC_AWD_CHANNEL_1_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG + * @arg @ref LL_ADC_AWD_CHANNEL_2_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG + * @arg @ref LL_ADC_AWD_CHANNEL_3_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG + * @arg @ref LL_ADC_AWD_CHANNEL_4_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG + * @arg @ref LL_ADC_AWD_CHANNEL_5_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG + * @arg @ref LL_ADC_AWD_CHANNEL_6_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG + * @arg @ref LL_ADC_AWD_CHANNEL_7_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG + * @arg @ref LL_ADC_AWD_CHANNEL_8_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG + * @arg @ref LL_ADC_AWD_CHANNEL_9_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG + * @arg @ref LL_ADC_AWD_CHANNEL_10_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG + * @arg @ref LL_ADC_AWD_CHANNEL_11_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG + * @arg @ref LL_ADC_AWD_CHANNEL_12_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG + * @arg @ref LL_ADC_AWD_CHANNEL_13_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG + * @arg @ref LL_ADC_AWD_CHANNEL_14_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG + * @arg @ref LL_ADC_AWD_CHANNEL_15_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG + * @arg @ref LL_ADC_AWD_CHANNEL_16_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG + * @arg @ref LL_ADC_AWD_CHANNEL_17_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG + * @arg @ref LL_ADC_AWD_CHANNEL_18_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG_INJ + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG (1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_INJ (1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG_INJ (1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG (1)(2) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_INJ (1)(2) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG_INJ (1)(2) + * @arg @ref LL_ADC_AWD_CH_VBAT_REG (1) + * @arg @ref LL_ADC_AWD_CH_VBAT_INJ (1) + * @arg @ref LL_ADC_AWD_CH_VBAT_REG_INJ (1) + * + * (1) On STM32F4, parameter available only on ADC instance: ADC1.\n + * (2) On devices STM32F42x and STM32F43x, limitation: this internal channel is shared between temperature sensor and Vbat, only 1 measurement path must be enabled. + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetAnalogWDMonitChannels(ADC_TypeDef *ADCx, uint32_t AWDChannelGroup) +{ + MODIFY_REG(ADCx->CR1, + (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL | ADC_CR1_AWDCH), + AWDChannelGroup); +} + +/** + * @brief Get ADC analog watchdog monitored channel. + * @note Usage of the returned channel number: + * - To reinject this channel into another function LL_ADC_xxx: + * the returned channel number is only partly formatted on definition + * of literals LL_ADC_CHANNEL_x. Therefore, it has to be compared + * with parts of literals LL_ADC_CHANNEL_x or using + * helper macro @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * Then the selected literal LL_ADC_CHANNEL_x can be used + * as parameter for another function. + * - To get the channel number in decimal format: + * process the returned value with the helper macro + * @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * Applicable only when the analog watchdog is set to monitor + * one channel. + * @note On this STM32 series, there is only 1 kind of analog watchdog + * instance: + * - AWD standard (instance AWD1): + * - channels monitored: can monitor 1 channel or all channels. + * - groups monitored: ADC groups regular and-or injected. + * - resolution: resolution is not limited (corresponds to + * ADC resolution configured). + * @rmtoll CR1 AWD1CH LL_ADC_GetAnalogWDMonitChannels\n + * CR1 AWD1SGL LL_ADC_GetAnalogWDMonitChannels\n + * CR1 AWD1EN LL_ADC_GetAnalogWDMonitChannels + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_AWD_DISABLE + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_INJ + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG + * @arg @ref LL_ADC_AWD_CHANNEL_0_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG + * @arg @ref LL_ADC_AWD_CHANNEL_1_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG + * @arg @ref LL_ADC_AWD_CHANNEL_2_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG + * @arg @ref LL_ADC_AWD_CHANNEL_3_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG + * @arg @ref LL_ADC_AWD_CHANNEL_4_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG + * @arg @ref LL_ADC_AWD_CHANNEL_5_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG + * @arg @ref LL_ADC_AWD_CHANNEL_6_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG + * @arg @ref LL_ADC_AWD_CHANNEL_7_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG + * @arg @ref LL_ADC_AWD_CHANNEL_8_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG + * @arg @ref LL_ADC_AWD_CHANNEL_9_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG + * @arg @ref LL_ADC_AWD_CHANNEL_10_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG + * @arg @ref LL_ADC_AWD_CHANNEL_11_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG + * @arg @ref LL_ADC_AWD_CHANNEL_12_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG + * @arg @ref LL_ADC_AWD_CHANNEL_13_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG + * @arg @ref LL_ADC_AWD_CHANNEL_14_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG + * @arg @ref LL_ADC_AWD_CHANNEL_15_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG + * @arg @ref LL_ADC_AWD_CHANNEL_16_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG + * @arg @ref LL_ADC_AWD_CHANNEL_17_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG + * @arg @ref LL_ADC_AWD_CHANNEL_18_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG_INJ + */ +__STATIC_INLINE uint32_t LL_ADC_GetAnalogWDMonitChannels(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL | ADC_CR1_AWDCH))); +} + +/** + * @brief Set ADC analog watchdog threshold value of threshold + * high or low. + * @note In case of ADC resolution different of 12 bits, + * analog watchdog thresholds data require a specific shift. + * Use helper macro @ref __LL_ADC_ANALOGWD_SET_THRESHOLD_RESOLUTION(). + * @note On this STM32 series, there is only 1 kind of analog watchdog + * instance: + * - AWD standard (instance AWD1): + * - channels monitored: can monitor 1 channel or all channels. + * - groups monitored: ADC groups regular and-or injected. + * - resolution: resolution is not limited (corresponds to + * ADC resolution configured). + * @rmtoll HTR HT LL_ADC_SetAnalogWDThresholds\n + * LTR LT LL_ADC_SetAnalogWDThresholds + * @param ADCx ADC instance + * @param AWDThresholdsHighLow This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_THRESHOLD_HIGH + * @arg @ref LL_ADC_AWD_THRESHOLD_LOW + * @param AWDThresholdValue Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetAnalogWDThresholds(ADC_TypeDef *ADCx, uint32_t AWDThresholdsHighLow, uint32_t AWDThresholdValue) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->HTR, AWDThresholdsHighLow); + + MODIFY_REG(*preg, + ADC_HTR_HT, + AWDThresholdValue); +} + +/** + * @brief Get ADC analog watchdog threshold value of threshold high or + * threshold low. + * @note In case of ADC resolution different of 12 bits, + * analog watchdog thresholds data require a specific shift. + * Use helper macro @ref __LL_ADC_ANALOGWD_GET_THRESHOLD_RESOLUTION(). + * @rmtoll HTR HT LL_ADC_GetAnalogWDThresholds\n + * LTR LT LL_ADC_GetAnalogWDThresholds + * @param ADCx ADC instance + * @param AWDThresholdsHighLow This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_THRESHOLD_HIGH + * @arg @ref LL_ADC_AWD_THRESHOLD_LOW + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF +*/ +__STATIC_INLINE uint32_t LL_ADC_GetAnalogWDThresholds(const ADC_TypeDef *ADCx, uint32_t AWDThresholdsHighLow) +{ + __IO uint32_t const *preg = __ADC_PTR_REG_OFFSET(ADCx->HTR, AWDThresholdsHighLow); + + return (uint32_t)(READ_BIT(*preg, ADC_HTR_HT)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Multimode Configuration of ADC hierarchical scope: multimode + * @{ + */ + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Set ADC multimode configuration to operate in independent mode + * or multimode (for devices with several ADC instances). + * @note If multimode configuration: the selected ADC instance is + * either master or slave depending on hardware. + * Refer to reference manual. + * @rmtoll CCR MULTI LL_ADC_SetMultimode + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @param Multimode This parameter can be one of the following values: + * @arg @ref LL_ADC_MULTI_INDEPENDENT + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIMULT + * @arg @ref LL_ADC_MULTI_DUAL_REG_INTERL + * @arg @ref LL_ADC_MULTI_DUAL_INJ_SIMULT + * @arg @ref LL_ADC_MULTI_DUAL_INJ_ALTERN + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT + * @arg @ref LL_ADC_MULTI_DUAL_REG_INT_INJ_SIM + * @arg @ref LL_ADC_MULTI_TRIPLE_REG_SIM_INJ_SIM + * @arg @ref LL_ADC_MULTI_TRIPLE_REG_SIM_INJ_ALT + * @arg @ref LL_ADC_MULTI_TRIPLE_INJ_SIMULT + * @arg @ref LL_ADC_MULTI_TRIPLE_REG_SIMULT + * @arg @ref LL_ADC_MULTI_TRIPLE_REG_INTERL + * @arg @ref LL_ADC_MULTI_TRIPLE_INJ_ALTERN + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetMultimode(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t Multimode) +{ + MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_MULTI, Multimode); +} + +/** + * @brief Get ADC multimode configuration to operate in independent mode + * or multimode (for devices with several ADC instances). + * @note If multimode configuration: the selected ADC instance is + * either master or slave depending on hardware. + * Refer to reference manual. + * @rmtoll CCR MULTI LL_ADC_GetMultimode + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_MULTI_INDEPENDENT + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIMULT + * @arg @ref LL_ADC_MULTI_DUAL_REG_INTERL + * @arg @ref LL_ADC_MULTI_DUAL_INJ_SIMULT + * @arg @ref LL_ADC_MULTI_DUAL_INJ_ALTERN + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT + * @arg @ref LL_ADC_MULTI_DUAL_REG_INT_INJ_SIM + * @arg @ref LL_ADC_MULTI_TRIPLE_REG_SIM_INJ_SIM + * @arg @ref LL_ADC_MULTI_TRIPLE_REG_SIM_INJ_ALT + * @arg @ref LL_ADC_MULTI_TRIPLE_INJ_SIMULT + * @arg @ref LL_ADC_MULTI_TRIPLE_REG_SIMULT + * @arg @ref LL_ADC_MULTI_TRIPLE_REG_INTERL + * @arg @ref LL_ADC_MULTI_TRIPLE_INJ_ALTERN + */ +__STATIC_INLINE uint32_t LL_ADC_GetMultimode(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CCR, ADC_CCR_MULTI)); +} + +/** + * @brief Set ADC multimode conversion data transfer: no transfer + * or transfer by DMA. + * @note If ADC multimode transfer by DMA is not selected: + * each ADC uses its own DMA channel, with its individual + * DMA transfer settings. + * If ADC multimode transfer by DMA is selected: + * One DMA channel is used for both ADC (DMA of ADC master) + * Specifies the DMA requests mode: + * - Limited mode (One shot mode): DMA transfer requests are stopped + * when number of DMA data transfers (number of + * ADC conversions) is reached. + * This ADC mode is intended to be used with DMA mode non-circular. + * - Unlimited mode: DMA transfer requests are unlimited, + * whatever number of DMA data transfers (number of + * ADC conversions). + * This ADC mode is intended to be used with DMA mode circular. + * @note If ADC DMA requests mode is set to unlimited and DMA is set to + * mode non-circular: + * when DMA transfers size will be reached, DMA will stop transfers of + * ADC conversions data ADC will raise an overrun error + * (overrun flag and interruption if enabled). + * @note How to retrieve multimode conversion data: + * Whatever multimode transfer by DMA setting: using function + * @ref LL_ADC_REG_ReadMultiConversionData32(). + * If ADC multimode transfer by DMA is selected: conversion data + * is a raw data with ADC master and slave concatenated. + * A macro is available to get the conversion data of + * ADC master or ADC slave: see helper macro + * @ref __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(). + * @rmtoll CCR MDMA LL_ADC_SetMultiDMATransfer\n + * CCR DDS LL_ADC_SetMultiDMATransfer + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @param MultiDMATransfer This parameter can be one of the following values: + * @arg @ref LL_ADC_MULTI_REG_DMA_EACH_ADC + * @arg @ref LL_ADC_MULTI_REG_DMA_LIMIT_1 + * @arg @ref LL_ADC_MULTI_REG_DMA_LIMIT_2 + * @arg @ref LL_ADC_MULTI_REG_DMA_LIMIT_3 + * @arg @ref LL_ADC_MULTI_REG_DMA_UNLMT_1 + * @arg @ref LL_ADC_MULTI_REG_DMA_UNLMT_2 + * @arg @ref LL_ADC_MULTI_REG_DMA_UNLMT_3 + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetMultiDMATransfer(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t MultiDMATransfer) +{ + MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_DMA | ADC_CCR_DDS, MultiDMATransfer); +} + +/** + * @brief Get ADC multimode conversion data transfer: no transfer + * or transfer by DMA. + * @note If ADC multimode transfer by DMA is not selected: + * each ADC uses its own DMA channel, with its individual + * DMA transfer settings. + * If ADC multimode transfer by DMA is selected: + * One DMA channel is used for both ADC (DMA of ADC master) + * Specifies the DMA requests mode: + * - Limited mode (One shot mode): DMA transfer requests are stopped + * when number of DMA data transfers (number of + * ADC conversions) is reached. + * This ADC mode is intended to be used with DMA mode non-circular. + * - Unlimited mode: DMA transfer requests are unlimited, + * whatever number of DMA data transfers (number of + * ADC conversions). + * This ADC mode is intended to be used with DMA mode circular. + * @note If ADC DMA requests mode is set to unlimited and DMA is set to + * mode non-circular: + * when DMA transfers size will be reached, DMA will stop transfers of + * ADC conversions data ADC will raise an overrun error + * (overrun flag and interruption if enabled). + * @note How to retrieve multimode conversion data: + * Whatever multimode transfer by DMA setting: using function + * @ref LL_ADC_REG_ReadMultiConversionData32(). + * If ADC multimode transfer by DMA is selected: conversion data + * is a raw data with ADC master and slave concatenated. + * A macro is available to get the conversion data of + * ADC master or ADC slave: see helper macro + * @ref __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(). + * @rmtoll CCR MDMA LL_ADC_GetMultiDMATransfer\n + * CCR DDS LL_ADC_GetMultiDMATransfer + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_MULTI_REG_DMA_EACH_ADC + * @arg @ref LL_ADC_MULTI_REG_DMA_LIMIT_1 + * @arg @ref LL_ADC_MULTI_REG_DMA_LIMIT_2 + * @arg @ref LL_ADC_MULTI_REG_DMA_LIMIT_3 + * @arg @ref LL_ADC_MULTI_REG_DMA_UNLMT_1 + * @arg @ref LL_ADC_MULTI_REG_DMA_UNLMT_2 + * @arg @ref LL_ADC_MULTI_REG_DMA_UNLMT_3 + */ +__STATIC_INLINE uint32_t LL_ADC_GetMultiDMATransfer(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CCR, ADC_CCR_DMA | ADC_CCR_DDS)); +} + +/** + * @brief Set ADC multimode delay between 2 sampling phases. + * @note The sampling delay range depends on ADC resolution: + * - ADC resolution 12 bits can have maximum delay of 12 cycles. + * - ADC resolution 10 bits can have maximum delay of 10 cycles. + * - ADC resolution 8 bits can have maximum delay of 8 cycles. + * - ADC resolution 6 bits can have maximum delay of 6 cycles. + * @rmtoll CCR DELAY LL_ADC_SetMultiTwoSamplingDelay + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @param MultiTwoSamplingDelay This parameter can be one of the following values: + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_6CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_7CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_8CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_9CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_10CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_11CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_12CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_13CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_14CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_15CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_16CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_17CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_18CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_19CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_20CYCLES + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetMultiTwoSamplingDelay(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t MultiTwoSamplingDelay) +{ + MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_DELAY, MultiTwoSamplingDelay); +} + +/** + * @brief Get ADC multimode delay between 2 sampling phases. + * @rmtoll CCR DELAY LL_ADC_GetMultiTwoSamplingDelay + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_6CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_7CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_8CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_9CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_10CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_11CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_12CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_13CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_14CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_15CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_16CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_17CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_18CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_19CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_20CYCLES + */ +__STATIC_INLINE uint32_t LL_ADC_GetMultiTwoSamplingDelay(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CCR, ADC_CCR_DELAY)); +} +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ +/** @defgroup ADC_LL_EF_Operation_ADC_Instance Operation on ADC hierarchical scope: ADC instance + * @{ + */ + +/** + * @brief Enable the selected ADC instance. + * @note On this STM32 series, after ADC enable, a delay for + * ADC internal analog stabilization is required before performing a + * ADC conversion start. + * Refer to device datasheet, parameter tSTAB. + * @rmtoll CR2 ADON LL_ADC_Enable + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_Enable(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR2, ADC_CR2_ADON); +} + +/** + * @brief Disable the selected ADC instance. + * @rmtoll CR2 ADON LL_ADC_Disable + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_Disable(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR2, ADC_CR2_ADON); +} + +/** + * @brief Get the selected ADC instance enable state. + * @rmtoll CR2 ADON LL_ADC_IsEnabled + * @param ADCx ADC instance + * @retval 0: ADC is disabled, 1: ADC is enabled. + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabled(const ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR2, ADC_CR2_ADON) == (ADC_CR2_ADON)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Operation_ADC_Group_Regular Operation on ADC hierarchical scope: group regular + * @{ + */ + +/** + * @brief Start ADC group regular conversion. + * @note On this STM32 series, this function is relevant only for + * internal trigger (SW start), not for external trigger: + * - If ADC trigger has been set to software start, ADC conversion + * starts immediately. + * - If ADC trigger has been set to external trigger, ADC conversion + * start must be performed using function + * @ref LL_ADC_REG_StartConversionExtTrig(). + * (if external trigger edge would have been set during ADC other + * settings, ADC conversion would start at trigger event + * as soon as ADC is enabled). + * @rmtoll CR2 SWSTART LL_ADC_REG_StartConversionSWStart + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_StartConversionSWStart(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR2, ADC_CR2_SWSTART); +} + +/** + * @brief Start ADC group regular conversion from external trigger. + * @note ADC conversion will start at next trigger event (on the selected + * trigger edge) following the ADC start conversion command. + * @note On this STM32 series, this function is relevant for + * ADC conversion start from external trigger. + * If internal trigger (SW start) is needed, perform ADC conversion + * start using function @ref LL_ADC_REG_StartConversionSWStart(). + * @rmtoll CR2 EXTEN LL_ADC_REG_StartConversionExtTrig + * @param ExternalTriggerEdge This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_EXT_RISING + * @arg @ref LL_ADC_REG_TRIG_EXT_FALLING + * @arg @ref LL_ADC_REG_TRIG_EXT_RISINGFALLING + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_StartConversionExtTrig(ADC_TypeDef *ADCx, uint32_t ExternalTriggerEdge) +{ + SET_BIT(ADCx->CR2, ExternalTriggerEdge); +} + +/** + * @brief Stop ADC group regular conversion from external trigger. + * @note No more ADC conversion will start at next trigger event + * following the ADC stop conversion command. + * If a conversion is on-going, it will be completed. + * @note On this STM32 series, there is no specific command + * to stop a conversion on-going or to stop ADC converting + * in continuous mode. These actions can be performed + * using function @ref LL_ADC_Disable(). + * @rmtoll CR2 EXTEN LL_ADC_REG_StopConversionExtTrig + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_StopConversionExtTrig(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR2, ADC_CR2_EXTEN); +} + +/** + * @brief Get ADC group regular conversion data, range fit for + * all ADC configurations: all ADC resolutions and + * all oversampling increased data width (for devices + * with feature oversampling). + * @rmtoll DR RDATA LL_ADC_REG_ReadConversionData32 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_ADC_REG_ReadConversionData32(const ADC_TypeDef *ADCx) +{ + return (uint16_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); +} + +/** + * @brief Get ADC group regular conversion data, range fit for + * ADC resolution 12 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_REG_ReadConversionData32. + * @rmtoll DR RDATA LL_ADC_REG_ReadConversionData12 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +__STATIC_INLINE uint16_t LL_ADC_REG_ReadConversionData12(const ADC_TypeDef *ADCx) +{ + return (uint16_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); +} + +/** + * @brief Get ADC group regular conversion data, range fit for + * ADC resolution 10 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_REG_ReadConversionData32. + * @rmtoll DR RDATA LL_ADC_REG_ReadConversionData10 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x000 and Max_Data=0x3FF + */ +__STATIC_INLINE uint16_t LL_ADC_REG_ReadConversionData10(const ADC_TypeDef *ADCx) +{ + return (uint16_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); +} + +/** + * @brief Get ADC group regular conversion data, range fit for + * ADC resolution 8 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_REG_ReadConversionData32. + * @rmtoll DR RDATA LL_ADC_REG_ReadConversionData8 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint8_t LL_ADC_REG_ReadConversionData8(const ADC_TypeDef *ADCx) +{ + return (uint8_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); +} + +/** + * @brief Get ADC group regular conversion data, range fit for + * ADC resolution 6 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_REG_ReadConversionData32. + * @rmtoll DR RDATA LL_ADC_REG_ReadConversionData6 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x00 and Max_Data=0x3F + */ +__STATIC_INLINE uint8_t LL_ADC_REG_ReadConversionData6(const ADC_TypeDef *ADCx) +{ + return (uint8_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); +} + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Get ADC multimode conversion data of ADC master, ADC slave + * or raw data with ADC master and slave concatenated. + * @note If raw data with ADC master and slave concatenated is retrieved, + * a macro is available to get the conversion data of + * ADC master or ADC slave: see helper macro + * @ref __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(). + * (however this macro is mainly intended for multimode + * transfer by DMA, because this function can do the same + * by getting multimode conversion data of ADC master or ADC slave + * separately). + * @rmtoll CDR DATA1 LL_ADC_REG_ReadMultiConversionData32\n + * CDR DATA2 LL_ADC_REG_ReadMultiConversionData32 + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @param ConversionData This parameter can be one of the following values: + * @arg @ref LL_ADC_MULTI_MASTER + * @arg @ref LL_ADC_MULTI_SLAVE + * @arg @ref LL_ADC_MULTI_MASTER_SLAVE + * @retval Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_ADC_REG_ReadMultiConversionData32(const ADC_Common_TypeDef *ADCxy_COMMON, uint32_t ConversionData) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CDR, + ADC_DR_ADC2DATA) + >> POSITION_VAL(ConversionData) + ); +} +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Operation_ADC_Group_Injected Operation on ADC hierarchical scope: group injected + * @{ + */ + +/** + * @brief Start ADC group injected conversion. + * @note On this STM32 series, this function is relevant only for + * internal trigger (SW start), not for external trigger: + * - If ADC trigger has been set to software start, ADC conversion + * starts immediately. + * - If ADC trigger has been set to external trigger, ADC conversion + * start must be performed using function + * @ref LL_ADC_INJ_StartConversionExtTrig(). + * (if external trigger edge would have been set during ADC other + * settings, ADC conversion would start at trigger event + * as soon as ADC is enabled). + * @rmtoll CR2 JSWSTART LL_ADC_INJ_StartConversionSWStart + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_StartConversionSWStart(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR2, ADC_CR2_JSWSTART); +} + +/** + * @brief Start ADC group injected conversion from external trigger. + * @note ADC conversion will start at next trigger event (on the selected + * trigger edge) following the ADC start conversion command. + * @note On this STM32 series, this function is relevant for + * ADC conversion start from external trigger. + * If internal trigger (SW start) is needed, perform ADC conversion + * start using function @ref LL_ADC_INJ_StartConversionSWStart(). + * @rmtoll CR2 JEXTEN LL_ADC_INJ_StartConversionExtTrig + * @param ExternalTriggerEdge This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_EXT_RISING + * @arg @ref LL_ADC_INJ_TRIG_EXT_FALLING + * @arg @ref LL_ADC_INJ_TRIG_EXT_RISINGFALLING + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_StartConversionExtTrig(ADC_TypeDef *ADCx, uint32_t ExternalTriggerEdge) +{ + SET_BIT(ADCx->CR2, ExternalTriggerEdge); +} + +/** + * @brief Stop ADC group injected conversion from external trigger. + * @note No more ADC conversion will start at next trigger event + * following the ADC stop conversion command. + * If a conversion is on-going, it will be completed. + * @note On this STM32 series, there is no specific command + * to stop a conversion on-going or to stop ADC converting + * in continuous mode. These actions can be performed + * using function @ref LL_ADC_Disable(). + * @rmtoll CR2 JEXTEN LL_ADC_INJ_StopConversionExtTrig + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_StopConversionExtTrig(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR2, ADC_CR2_JEXTEN); +} + +/** + * @brief Get ADC group regular conversion data, range fit for + * all ADC configurations: all ADC resolutions and + * all oversampling increased data width (for devices + * with feature oversampling). + * @rmtoll JDR1 JDATA LL_ADC_INJ_ReadConversionData32\n + * JDR2 JDATA LL_ADC_INJ_ReadConversionData32\n + * JDR3 JDATA LL_ADC_INJ_ReadConversionData32\n + * JDR4 JDATA LL_ADC_INJ_ReadConversionData32 + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_ReadConversionData32(const ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t const *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JDRX_REGOFFSET_MASK)); + + return (uint32_t)(READ_BIT(*preg, + ADC_JDR1_JDATA) + ); +} + +/** + * @brief Get ADC group injected conversion data, range fit for + * ADC resolution 12 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_INJ_ReadConversionData32. + * @rmtoll JDR1 JDATA LL_ADC_INJ_ReadConversionData12\n + * JDR2 JDATA LL_ADC_INJ_ReadConversionData12\n + * JDR3 JDATA LL_ADC_INJ_ReadConversionData12\n + * JDR4 JDATA LL_ADC_INJ_ReadConversionData12 + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +__STATIC_INLINE uint16_t LL_ADC_INJ_ReadConversionData12(const ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t const *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JDRX_REGOFFSET_MASK)); + + return (uint16_t)(READ_BIT(*preg, + ADC_JDR1_JDATA) + ); +} + +/** + * @brief Get ADC group injected conversion data, range fit for + * ADC resolution 10 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_INJ_ReadConversionData32. + * @rmtoll JDR1 JDATA LL_ADC_INJ_ReadConversionData10\n + * JDR2 JDATA LL_ADC_INJ_ReadConversionData10\n + * JDR3 JDATA LL_ADC_INJ_ReadConversionData10\n + * JDR4 JDATA LL_ADC_INJ_ReadConversionData10 + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Value between Min_Data=0x000 and Max_Data=0x3FF + */ +__STATIC_INLINE uint16_t LL_ADC_INJ_ReadConversionData10(const ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t const *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JDRX_REGOFFSET_MASK)); + + return (uint16_t)(READ_BIT(*preg, + ADC_JDR1_JDATA) + ); +} + +/** + * @brief Get ADC group injected conversion data, range fit for + * ADC resolution 8 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_INJ_ReadConversionData32. + * @rmtoll JDR1 JDATA LL_ADC_INJ_ReadConversionData8\n + * JDR2 JDATA LL_ADC_INJ_ReadConversionData8\n + * JDR3 JDATA LL_ADC_INJ_ReadConversionData8\n + * JDR4 JDATA LL_ADC_INJ_ReadConversionData8 + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint8_t LL_ADC_INJ_ReadConversionData8(const ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t const *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JDRX_REGOFFSET_MASK)); + + return (uint8_t)(READ_BIT(*preg, + ADC_JDR1_JDATA) + ); +} + +/** + * @brief Get ADC group injected conversion data, range fit for + * ADC resolution 6 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_INJ_ReadConversionData32. + * @rmtoll JDR1 JDATA LL_ADC_INJ_ReadConversionData6\n + * JDR2 JDATA LL_ADC_INJ_ReadConversionData6\n + * JDR3 JDATA LL_ADC_INJ_ReadConversionData6\n + * JDR4 JDATA LL_ADC_INJ_ReadConversionData6 + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Value between Min_Data=0x00 and Max_Data=0x3F + */ +__STATIC_INLINE uint8_t LL_ADC_INJ_ReadConversionData6(const ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t const *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JDRX_REGOFFSET_MASK)); + + return (uint8_t)(READ_BIT(*preg, + ADC_JDR1_JDATA) + ); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_FLAG_Management ADC flag management + * @{ + */ + +/** + * @brief Get flag ADC group regular end of unitary conversion + * or end of sequence conversions, depending on + * ADC configuration. + * @note To configure flag of end of conversion, + * use function @ref LL_ADC_REG_SetFlagEndOfConversion(). + * @rmtoll SR EOC LL_ADC_IsActiveFlag_EOCS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_EOCS(const ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SR, LL_ADC_FLAG_EOCS) == (LL_ADC_FLAG_EOCS)); +} + +/** + * @brief Get flag ADC group regular overrun. + * @rmtoll SR OVR LL_ADC_IsActiveFlag_OVR + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_OVR(const ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SR, LL_ADC_FLAG_OVR) == (LL_ADC_FLAG_OVR)); +} + + +/** + * @brief Get flag ADC group injected end of sequence conversions. + * @rmtoll SR JEOC LL_ADC_IsActiveFlag_JEOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_JEOS(const ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCx->SR, LL_ADC_FLAG_JEOS) == (LL_ADC_FLAG_JEOS)); +} + +/** + * @brief Get flag ADC analog watchdog 1 flag + * @rmtoll SR AWD LL_ADC_IsActiveFlag_AWD1 + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_AWD1(const ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SR, LL_ADC_FLAG_AWD1) == (LL_ADC_FLAG_AWD1)); +} + +/** + * @brief Clear flag ADC group regular end of unitary conversion + * or end of sequence conversions, depending on + * ADC configuration. + * @note To configure flag of end of conversion, + * use function @ref LL_ADC_REG_SetFlagEndOfConversion(). + * @rmtoll SR EOC LL_ADC_ClearFlag_EOCS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_EOCS(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->SR, ~LL_ADC_FLAG_EOCS); +} + +/** + * @brief Clear flag ADC group regular overrun. + * @rmtoll SR OVR LL_ADC_ClearFlag_OVR + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_OVR(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->SR, ~LL_ADC_FLAG_OVR); +} + + +/** + * @brief Clear flag ADC group injected end of sequence conversions. + * @rmtoll SR JEOC LL_ADC_ClearFlag_JEOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_JEOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + WRITE_REG(ADCx->SR, ~LL_ADC_FLAG_JEOS); +} + +/** + * @brief Clear flag ADC analog watchdog 1. + * @rmtoll SR AWD LL_ADC_ClearFlag_AWD1 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_AWD1(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->SR, ~LL_ADC_FLAG_AWD1); +} + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Get flag multimode ADC group regular end of unitary conversion + * or end of sequence conversions, depending on + * ADC configuration, of the ADC master. + * @note To configure flag of end of conversion, + * use function @ref LL_ADC_REG_SetFlagEndOfConversion(). + * @rmtoll CSR EOC1 LL_ADC_IsActiveFlag_MST_EOCS + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_MST_EOCS(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_EOCS_MST) == (LL_ADC_FLAG_EOCS_MST)); +} + +/** + * @brief Get flag multimode ADC group regular end of unitary conversion + * or end of sequence conversions, depending on + * ADC configuration, of the ADC slave 1. + * @note To configure flag of end of conversion, + * use function @ref LL_ADC_REG_SetFlagEndOfConversion(). + * @rmtoll CSR EOC2 LL_ADC_IsActiveFlag_SLV1_EOCS + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV1_EOCS(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_EOCS_SLV1) == (LL_ADC_FLAG_EOCS_SLV1)); +} + +/** + * @brief Get flag multimode ADC group regular end of unitary conversion + * or end of sequence conversions, depending on + * ADC configuration, of the ADC slave 2. + * @note To configure flag of end of conversion, + * use function @ref LL_ADC_REG_SetFlagEndOfConversion(). + * @rmtoll CSR EOC3 LL_ADC_IsActiveFlag_SLV2_EOCS + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV2_EOCS(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_EOCS_SLV2) == (LL_ADC_FLAG_EOCS_SLV2)); +} +/** + * @brief Get flag multimode ADC group regular overrun of the ADC master. + * @rmtoll CSR OVR1 LL_ADC_IsActiveFlag_MST_OVR + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_MST_OVR(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_OVR_MST) == (LL_ADC_FLAG_OVR_MST)); +} + +/** + * @brief Get flag multimode ADC group regular overrun of the ADC slave 1. + * @rmtoll CSR OVR2 LL_ADC_IsActiveFlag_SLV1_OVR + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV1_OVR(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_OVR_SLV1) == (LL_ADC_FLAG_OVR_SLV1)); +} + +/** + * @brief Get flag multimode ADC group regular overrun of the ADC slave 2. + * @rmtoll CSR OVR3 LL_ADC_IsActiveFlag_SLV2_OVR + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV2_OVR(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_OVR_SLV2) == (LL_ADC_FLAG_OVR_SLV2)); +} + + +/** + * @brief Get flag multimode ADC group injected end of sequence conversions of the ADC master. + * @rmtoll CSR JEOC LL_ADC_IsActiveFlag_MST_JEOS + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_MST_JEOS(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCxy_COMMON->CSR, ADC_CSR_JEOC1) == (ADC_CSR_JEOC1)); +} + +/** + * @brief Get flag multimode ADC group injected end of sequence conversions of the ADC slave 1. + * @rmtoll CSR JEOC2 LL_ADC_IsActiveFlag_SLV1_JEOS + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV1_JEOS(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCxy_COMMON->CSR, ADC_CSR_JEOC2) == (ADC_CSR_JEOC2)); +} + +/** + * @brief Get flag multimode ADC group injected end of sequence conversions of the ADC slave 2. + * @rmtoll CSR JEOC3 LL_ADC_IsActiveFlag_SLV2_JEOS + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV2_JEOS(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCxy_COMMON->CSR, ADC_CSR_JEOC3) == (ADC_CSR_JEOC3)); +} + +/** + * @brief Get flag multimode ADC analog watchdog 1 of the ADC master. + * @rmtoll CSR AWD1 LL_ADC_IsActiveFlag_MST_AWD1 + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_MST_AWD1(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_AWD1_MST) == (LL_ADC_FLAG_AWD1_MST)); +} + +/** + * @brief Get flag multimode analog watchdog 1 of the ADC slave 1. + * @rmtoll CSR AWD2 LL_ADC_IsActiveFlag_SLV1_AWD1 + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV1_AWD1(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_AWD1_SLV1) == (LL_ADC_FLAG_AWD1_SLV1)); +} + +/** + * @brief Get flag multimode analog watchdog 1 of the ADC slave 2. + * @rmtoll CSR AWD3 LL_ADC_IsActiveFlag_SLV2_AWD1 + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV2_AWD1(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_AWD1_SLV2) == (LL_ADC_FLAG_AWD1_SLV2)); +} + +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_IT_Management ADC IT management + * @{ + */ + +/** + * @brief Enable interruption ADC group regular end of unitary conversion + * or end of sequence conversions, depending on + * ADC configuration. + * @note To configure flag of end of conversion, + * use function @ref LL_ADC_REG_SetFlagEndOfConversion(). + * @rmtoll CR1 EOCIE LL_ADC_EnableIT_EOCS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_EOCS(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR1, LL_ADC_IT_EOCS); +} + +/** + * @brief Enable ADC group regular interruption overrun. + * @rmtoll CR1 OVRIE LL_ADC_EnableIT_OVR + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_OVR(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR1, LL_ADC_IT_OVR); +} + + +/** + * @brief Enable interruption ADC group injected end of sequence conversions. + * @rmtoll CR1 JEOCIE LL_ADC_EnableIT_JEOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_JEOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + SET_BIT(ADCx->CR1, LL_ADC_IT_JEOS); +} + +/** + * @brief Enable interruption ADC analog watchdog 1. + * @rmtoll CR1 AWDIE LL_ADC_EnableIT_AWD1 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_AWD1(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR1, LL_ADC_IT_AWD1); +} + +/** + * @brief Disable interruption ADC group regular end of unitary conversion + * or end of sequence conversions, depending on + * ADC configuration. + * @note To configure flag of end of conversion, + * use function @ref LL_ADC_REG_SetFlagEndOfConversion(). + * @rmtoll CR1 EOCIE LL_ADC_DisableIT_EOCS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_EOCS(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR1, LL_ADC_IT_EOCS); +} + +/** + * @brief Disable interruption ADC group regular overrun. + * @rmtoll CR1 OVRIE LL_ADC_DisableIT_OVR + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_OVR(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR1, LL_ADC_IT_OVR); +} + + +/** + * @brief Disable interruption ADC group injected end of sequence conversions. + * @rmtoll CR1 JEOCIE LL_ADC_EnableIT_JEOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_JEOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + CLEAR_BIT(ADCx->CR1, LL_ADC_IT_JEOS); +} + +/** + * @brief Disable interruption ADC analog watchdog 1. + * @rmtoll CR1 AWDIE LL_ADC_EnableIT_AWD1 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_AWD1(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR1, LL_ADC_IT_AWD1); +} + +/** + * @brief Get state of interruption ADC group regular end of unitary conversion + * or end of sequence conversions, depending on + * ADC configuration. + * @note To configure flag of end of conversion, + * use function @ref LL_ADC_REG_SetFlagEndOfConversion(). + * (0: interrupt disabled, 1: interrupt enabled) + * @rmtoll CR1 EOCIE LL_ADC_IsEnabledIT_EOCS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_EOCS(const ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR1, LL_ADC_IT_EOCS) == (LL_ADC_IT_EOCS)); +} + +/** + * @brief Get state of interruption ADC group regular overrun + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll CR1 OVRIE LL_ADC_IsEnabledIT_OVR + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_OVR(const ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR1, LL_ADC_IT_OVR) == (LL_ADC_IT_OVR)); +} + + +/** + * @brief Get state of interruption ADC group injected end of sequence conversions + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll CR1 JEOCIE LL_ADC_EnableIT_JEOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_JEOS(const ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCx->CR1, LL_ADC_IT_JEOS) == (LL_ADC_IT_JEOS)); +} + +/** + * @brief Get state of interruption ADC analog watchdog 1 + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll CR1 AWDIE LL_ADC_EnableIT_AWD1 + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_AWD1(const ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR1, LL_ADC_IT_AWD1) == (LL_ADC_IT_AWD1)); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup ADC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/* Initialization of some features of ADC common parameters and multimode */ +ErrorStatus LL_ADC_CommonDeInit(ADC_Common_TypeDef *ADCxy_COMMON); +ErrorStatus LL_ADC_CommonInit(ADC_Common_TypeDef *ADCxy_COMMON, LL_ADC_CommonInitTypeDef *ADC_CommonInitStruct); +void LL_ADC_CommonStructInit(LL_ADC_CommonInitTypeDef *ADC_CommonInitStruct); + +/* De-initialization of ADC instance, ADC group regular and ADC group injected */ +/* (availability of ADC group injected depends on STM32 families) */ +ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx); + +/* Initialization of some features of ADC instance */ +ErrorStatus LL_ADC_Init(ADC_TypeDef *ADCx, LL_ADC_InitTypeDef *ADC_InitStruct); +void LL_ADC_StructInit(LL_ADC_InitTypeDef *ADC_InitStruct); + +/* Initialization of some features of ADC instance and ADC group regular */ +ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct); +void LL_ADC_REG_StructInit(LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct); + +/* Initialization of some features of ADC instance and ADC group injected */ +ErrorStatus LL_ADC_INJ_Init(ADC_TypeDef *ADCx, LL_ADC_INJ_InitTypeDef *ADC_INJ_InitStruct); +void LL_ADC_INJ_StructInit(LL_ADC_INJ_InitTypeDef *ADC_INJ_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ADC1 || ADC2 || ADC3 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_LL_ADC_H */ + diff --git a/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c b/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c new file mode 100644 index 00000000..f37d00e1 --- /dev/null +++ b/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c @@ -0,0 +1,2110 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_adc.c + * @author MCD Application Team + * @brief This file provides firmware functions to manage the following + * functionalities of the Analog to Digital Converter (ADC) peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + Peripheral State 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 + ============================================================================== + ##### ADC Peripheral features ##### + ============================================================================== + [..] + (#) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution. + (#) Interrupt generation at the end of conversion, end of injected conversion, + and in case of analog watchdog or overrun events + (#) Single and continuous conversion modes. + (#) Scan mode for automatic conversion of channel 0 to channel x. + (#) Data alignment with in-built data coherency. + (#) Channel-wise programmable sampling time. + (#) External trigger option with configurable polarity for both regular and + injected conversion. + (#) Dual/Triple mode (on devices with 2 ADCs or more). + (#) Configurable DMA data storage in Dual/Triple ADC mode. + (#) Configurable delay between conversions in Dual/Triple interleaved mode. + (#) ADC conversion type (refer to the datasheets). + (#) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at + slower speed. + (#) ADC input range: VREF(minus) = VIN = VREF(plus). + (#) DMA request generation during regular channel conversion. + + + ##### How to use this driver ##### + ============================================================================== + [..] + (#)Initialize the ADC low level resources by implementing the HAL_ADC_MspInit(): + (##) Enable the ADC interface clock using __HAL_RCC_ADC_CLK_ENABLE() + (##) ADC pins configuration + (+++) Enable the clock for the ADC GPIOs using the following function: + __HAL_RCC_GPIOx_CLK_ENABLE() + (+++) Configure these ADC pins in analog mode using HAL_GPIO_Init() + (##) In case of using interrupts (e.g. HAL_ADC_Start_IT()) + (+++) Configure the ADC interrupt priority using HAL_NVIC_SetPriority() + (+++) Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ() + (+++) In ADC IRQ handler, call HAL_ADC_IRQHandler() + (##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA()) + (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE() + (+++) Configure and enable two DMA streams stream for managing data + transfer from peripheral to memory (output stream) + (+++) Associate the initialized DMA handle to the CRYP DMA handle + using __HAL_LINKDMA() + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the two DMA Streams. The output stream should have higher + priority than the input stream. + + *** Configuration of ADC, groups regular/injected, channels parameters *** + ============================================================================== + [..] + (#) Configure the ADC parameters (resolution, data alignment, ...) + and regular group parameters (conversion trigger, sequencer, ...) + using function HAL_ADC_Init(). + + (#) Configure the channels for regular group parameters (channel number, + channel rank into sequencer, ..., into regular group) + using function HAL_ADC_ConfigChannel(). + + (#) Optionally, configure the injected group parameters (conversion trigger, + sequencer, ..., of injected group) + and the channels for injected group parameters (channel number, + channel rank into sequencer, ..., into injected group) + using function HAL_ADCEx_InjectedConfigChannel(). + + (#) Optionally, configure the analog watchdog parameters (channels + monitored, thresholds, ...) using function HAL_ADC_AnalogWDGConfig(). + + (#) Optionally, for devices with several ADC instances: configure the + multimode parameters using function HAL_ADCEx_MultiModeConfigChannel(). + + *** Execution of ADC conversions *** + ============================================================================== + [..] + (#) ADC driver can be used among three modes: polling, interruption, + transfer by DMA. + + *** Polling mode IO operation *** + ================================= + [..] + (+) Start the ADC peripheral using HAL_ADC_Start() + (+) Wait for end of conversion using HAL_ADC_PollForConversion(), at this stage + user can specify the value of timeout according to his end application + (+) To read the ADC converted values, use the HAL_ADC_GetValue() function. + (+) Stop the ADC peripheral using HAL_ADC_Stop() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Start the ADC peripheral using HAL_ADC_Start_IT() + (+) Use HAL_ADC_IRQHandler() called under ADC_IRQHandler() Interrupt subroutine + (+) At ADC end of conversion HAL_ADC_ConvCpltCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADC_ConvCpltCallback + (+) In case of ADC Error, HAL_ADC_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADC_ErrorCallback + (+) Stop the ADC peripheral using HAL_ADC_Stop_IT() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Start the ADC peripheral using HAL_ADC_Start_DMA(), at this stage the user specify the length + of data to be transferred at each end of conversion + (+) At The end of data transfer by HAL_ADC_ConvCpltCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADC_ConvCpltCallback + (+) In case of transfer Error, HAL_ADC_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADC_ErrorCallback + (+) Stop the ADC peripheral using HAL_ADC_Stop_DMA() + + *** ADC HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in ADC HAL driver. + + (+) __HAL_ADC_ENABLE : Enable the ADC peripheral + (+) __HAL_ADC_DISABLE : Disable the ADC peripheral + (+) __HAL_ADC_ENABLE_IT: Enable the ADC end of conversion interrupt + (+) __HAL_ADC_DISABLE_IT: Disable the ADC end of conversion interrupt + (+) __HAL_ADC_GET_IT_SOURCE: Check if the specified ADC interrupt source is enabled or disabled + (+) __HAL_ADC_CLEAR_FLAG: Clear the ADC's pending flags + (+) __HAL_ADC_GET_FLAG: Get the selected ADC's flag status + (+) ADC_GET_RESOLUTION: Return resolution bits in CR1 register + + [..] + (@) You can refer to the ADC HAL driver header file for more useful macros + + *** Deinitialization of ADC *** + ============================================================================== + [..] + (#) Disable the ADC interface + (++) ADC clock can be hard reset and disabled at RCC top level. + (++) Hard reset of ADC peripherals + using macro __HAL_RCC_ADC_FORCE_RESET(), __HAL_RCC_ADC_RELEASE_RESET(). + (++) ADC clock disable using the equivalent macro/functions as configuration step. + (+++) Example: + Into HAL_ADC_MspDeInit() (recommended code location) or with + other device clock parameters configuration: + (+++) HAL_RCC_GetOscConfig(&RCC_OscInitStructure); + (+++) RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSI; + (+++) RCC_OscInitStructure.HSIState = RCC_HSI_OFF; (if not used for system clock) + (+++) HAL_RCC_OscConfig(&RCC_OscInitStructure); + + (#) ADC pins configuration + (++) Disable the clock for the ADC GPIOs using macro __HAL_RCC_GPIOx_CLK_DISABLE() + + (#) Optionally, in case of usage of ADC with interruptions: + (++) Disable the NVIC for ADC using function HAL_NVIC_DisableIRQ(ADCx_IRQn) + + (#) Optionally, in case of usage of DMA: + (++) Deinitialize the DMA using function HAL_DMA_DeInit(). + (++) Disable the NVIC for DMA using function HAL_NVIC_DisableIRQ(DMAx_Channelx_IRQn) + *** Callback registration *** + ============================================================================== + [..] + + The compilation flag USE_HAL_ADC_REGISTER_CALLBACKS, when set to 1, + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_ADC_RegisterCallback() + to register an interrupt callback. + [..] + + Function HAL_ADC_RegisterCallback() allows to register following callbacks: + (+) ConvCpltCallback : ADC conversion complete callback + (+) ConvHalfCpltCallback : ADC conversion DMA half-transfer callback + (+) LevelOutOfWindowCallback : ADC analog watchdog 1 callback + (+) ErrorCallback : ADC error callback + (+) InjectedConvCpltCallback : ADC group injected conversion complete callback + (+) InjectedQueueOverflowCallback : ADC group injected context queue overflow callback + (+) LevelOutOfWindow2Callback : ADC analog watchdog 2 callback + (+) LevelOutOfWindow3Callback : ADC analog watchdog 3 callback + (+) EndOfSamplingCallback : ADC end of sampling callback + (+) MspInitCallback : ADC Msp Init callback + (+) MspDeInitCallback : ADC Msp DeInit callback + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + [..] + + Use function HAL_ADC_UnRegisterCallback to reset a callback to the default + weak function. + [..] + + HAL_ADC_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) ConvCpltCallback : ADC conversion complete callback + (+) ConvHalfCpltCallback : ADC conversion DMA half-transfer callback + (+) LevelOutOfWindowCallback : ADC analog watchdog 1 callback + (+) ErrorCallback : ADC error callback + (+) InjectedConvCpltCallback : ADC group injected conversion complete callback + (+) InjectedQueueOverflowCallback : ADC group injected context queue overflow callback + (+) LevelOutOfWindow2Callback : ADC analog watchdog 2 callback + (+) LevelOutOfWindow3Callback : ADC analog watchdog 3 callback + (+) EndOfSamplingCallback : ADC end of sampling callback + (+) MspInitCallback : ADC Msp Init callback + (+) MspDeInitCallback : ADC Msp DeInit callback + [..] + + By default, after the HAL_ADC_Init() and when the state is HAL_ADC_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_ADC_ConvCpltCallback(), HAL_ADC_ErrorCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the HAL_ADC_Init()/ HAL_ADC_DeInit() only when + these callbacks are null (not registered beforehand). + [..] + + If MspInit or MspDeInit are not null, the HAL_ADC_Init()/ HAL_ADC_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + [..] + + Callbacks can be registered/unregistered in HAL_ADC_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in HAL_ADC_STATE_READY or HAL_ADC_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + [..] + + Then, the user first registers the MspInit/MspDeInit user callbacks + using HAL_ADC_RegisterCallback() before calling HAL_ADC_DeInit() + or HAL_ADC_Init() function. + [..] + + When the compilation flag USE_HAL_ADC_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available and all callbacks + are set to the corresponding weak functions. + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup ADC ADC + * @brief ADC driver modules + * @{ + */ + +#ifdef HAL_ADC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup ADC_Private_Functions + * @{ + */ +/* Private function prototypes -----------------------------------------------*/ +static void ADC_Init(ADC_HandleTypeDef *hadc); +static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma); +static void ADC_DMAError(DMA_HandleTypeDef *hdma); +static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma); +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup ADC_Exported_Functions ADC Exported Functions + * @{ + */ + +/** @defgroup ADC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the ADC. + (+) De-initialize the ADC. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the ADCx peripheral according to the specified parameters + * in the ADC_InitStruct and initializes the ADC MSP. + * + * @note This function is used to configure the global features of the ADC ( + * ClockPrescaler, Resolution, Data Alignment and number of conversion), however, + * the rest of the configuration parameters are specific to the regular + * channels group (scan mode activation, continuous mode activation, + * External trigger source and edge, DMA continuous request after the + * last transfer and End of conversion selection). + * + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check ADC handle */ + if (hadc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_CLOCKPRESCALER(hadc->Init.ClockPrescaler)); + assert_param(IS_ADC_RESOLUTION(hadc->Init.Resolution)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ScanConvMode)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG(hadc->Init.ExternalTrigConv)); + assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign)); + assert_param(IS_ADC_REGULAR_LENGTH(hadc->Init.NbrOfConversion)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests)); + assert_param(IS_ADC_EOCSelection(hadc->Init.EOCSelection)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode)); + + if (hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START) + { + assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + } + + if (hadc->State == HAL_ADC_STATE_RESET) + { +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + /* Init the ADC Callback settings */ + hadc->ConvCpltCallback = HAL_ADC_ConvCpltCallback; /* Legacy weak callback */ + hadc->ConvHalfCpltCallback = HAL_ADC_ConvHalfCpltCallback; /* Legacy weak callback */ + hadc->LevelOutOfWindowCallback = HAL_ADC_LevelOutOfWindowCallback; /* Legacy weak callback */ + hadc->ErrorCallback = HAL_ADC_ErrorCallback; /* Legacy weak callback */ + hadc->InjectedConvCpltCallback = HAL_ADCEx_InjectedConvCpltCallback; /* Legacy weak callback */ + if (hadc->MspInitCallback == NULL) + { + hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware */ + hadc->MspInitCallback(hadc); +#else + /* Init the low level hardware */ + HAL_ADC_MspInit(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Initialize ADC error code */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Allocate lock resource and initialize it */ + hadc->Lock = HAL_UNLOCKED; + } + + /* Configuration of ADC parameters if previous preliminary actions are */ + /* correctly completed. */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL)) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_BUSY_INTERNAL); + + /* Set ADC parameters */ + ADC_Init(hadc); + + /* Set ADC error code to none */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Set the ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_BUSY_INTERNAL, + HAL_ADC_STATE_READY); + } + else + { + tmp_hal_status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Deinitializes the ADCx peripheral registers to their default reset values. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check ADC handle */ + if (hadc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL); + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Configuration of ADC parameters if previous preliminary actions are */ + /* correctly completed. */ + if (HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) + { +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + if (hadc->MspDeInitCallback == NULL) + { + hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: RCC clock, NVIC */ + hadc->MspDeInitCallback(hadc); +#else + /* DeInit the low level hardware: RCC clock, NVIC */ + HAL_ADC_MspDeInit(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Set ADC error code to none */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Set ADC state */ + hadc->State = HAL_ADC_STATE_RESET; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User ADC Callback + * To be used instead of the weak predefined callback + * @param hadc Pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID ADC conversion complete callback ID + * @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID ADC conversion DMA half-transfer callback ID + * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID ADC analog watchdog 1 callback ID + * @arg @ref HAL_ADC_ERROR_CB_ID ADC error callback ID + * @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID ADC group injected conversion complete callback ID + * @arg @ref HAL_ADC_MSPINIT_CB_ID ADC Msp Init callback ID + * @arg @ref HAL_ADC_MSPDEINIT_CB_ID ADC Msp DeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_RegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID, pADC_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if ((hadc->State & HAL_ADC_STATE_READY) != 0UL) + { + switch (CallbackID) + { + case HAL_ADC_CONVERSION_COMPLETE_CB_ID : + hadc->ConvCpltCallback = pCallback; + break; + + case HAL_ADC_CONVERSION_HALF_CB_ID : + hadc->ConvHalfCpltCallback = pCallback; + break; + + case HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID : + hadc->LevelOutOfWindowCallback = pCallback; + break; + + case HAL_ADC_ERROR_CB_ID : + hadc->ErrorCallback = pCallback; + break; + + case HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID : + hadc->InjectedConvCpltCallback = pCallback; + break; + + case HAL_ADC_MSPINIT_CB_ID : + hadc->MspInitCallback = pCallback; + break; + + case HAL_ADC_MSPDEINIT_CB_ID : + hadc->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_ADC_STATE_RESET == hadc->State) + { + switch (CallbackID) + { + case HAL_ADC_MSPINIT_CB_ID : + hadc->MspInitCallback = pCallback; + break; + + case HAL_ADC_MSPDEINIT_CB_ID : + hadc->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a ADC Callback + * ADC callback is redirected to the weak predefined callback + * @param hadc Pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID ADC conversion complete callback ID + * @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID ADC conversion DMA half-transfer callback ID + * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID ADC analog watchdog 1 callback ID + * @arg @ref HAL_ADC_ERROR_CB_ID ADC error callback ID + * @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID ADC group injected conversion complete callback ID + * @arg @ref HAL_ADC_MSPINIT_CB_ID ADC Msp Init callback ID + * @arg @ref HAL_ADC_MSPDEINIT_CB_ID ADC Msp DeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_UnRegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if ((hadc->State & HAL_ADC_STATE_READY) != 0UL) + { + switch (CallbackID) + { + case HAL_ADC_CONVERSION_COMPLETE_CB_ID : + hadc->ConvCpltCallback = HAL_ADC_ConvCpltCallback; + break; + + case HAL_ADC_CONVERSION_HALF_CB_ID : + hadc->ConvHalfCpltCallback = HAL_ADC_ConvHalfCpltCallback; + break; + + case HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID : + hadc->LevelOutOfWindowCallback = HAL_ADC_LevelOutOfWindowCallback; + break; + + case HAL_ADC_ERROR_CB_ID : + hadc->ErrorCallback = HAL_ADC_ErrorCallback; + break; + + case HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID : + hadc->InjectedConvCpltCallback = HAL_ADCEx_InjectedConvCpltCallback; + break; + + case HAL_ADC_MSPINIT_CB_ID : + hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_ADC_MSPDEINIT_CB_ID : + hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_ADC_STATE_RESET == hadc->State) + { + switch (CallbackID) + { + case HAL_ADC_MSPINIT_CB_ID : + hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_ADC_MSPDEINIT_CB_ID : + hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + +/** + * @brief Initializes the ADC MSP. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the ADC MSP. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion of regular channel. + (+) Stop conversion of regular channel. + (+) Start conversion of regular channel and enable interrupt. + (+) Stop conversion of regular channel and disable interrupt. + (+) Start conversion of regular channel and enable DMA transfer. + (+) Stop conversion of regular channel and disable DMA transfer. + (+) Handle ADC interrupt request. + +@endverbatim + * @{ + */ + +/** + * @brief Enables ADC and starts conversion of the regular channels. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc) +{ + __IO uint32_t counter = 0U; + ADC_Common_TypeDef *tmpADC_Common; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if ((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for ADC stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U)); + while (counter != 0U) + { + counter--; + } + } + + /* Start conversion if ADC is effectively enabled */ + if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular group operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR, + HAL_ADC_STATE_REG_BUSY); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + + /* State machine update: Check if an injected conversion is ongoing */ + if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + /* Reset ADC error code fields related to conversions on group regular */ + CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); + } + else + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADCs and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* Clear regular group conversion flag and overrun flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC | ADC_FLAG_OVR); + + /* Check if Multimode enabled */ + if (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_MULTI)) + { +#if defined(ADC2) && defined(ADC3) + if ((hadc->Instance == ADC1) || ((hadc->Instance == ADC2) && ((ADC->CCR & ADC_CCR_MULTI_Msk) < ADC_CCR_MULTI_0)) \ + || ((hadc->Instance == ADC3) && ((ADC->CCR & ADC_CCR_MULTI_Msk) < ADC_CCR_MULTI_4))) + { +#endif /* ADC2 || ADC3 */ + /* if no external trigger present enable software conversion of regular channels */ + if ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } +#if defined(ADC2) && defined(ADC3) + } +#endif /* ADC2 || ADC3 */ + } + else + { + /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */ + if ((hadc->Instance == ADC1) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables ADC and stop conversion of regular channels. + * + * @note Caution: This function will stop also injected channels. + * + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef *hadc) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Check if ADC is effectively disabled */ + if (HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Poll for regular conversion complete + * @note ADC conversion flags EOS (end of sequence) and EOC (end of + * conversion) are cleared by this function. + * @note This function cannot be used in a particular setup: ADC configured + * in DMA mode and polling for end of each conversion (ADC init + * parameter "EOCSelection" set to ADC_EOC_SINGLE_CONV). + * In this case, DMA resets the flag EOC and polling cannot be + * performed on each conversion. Nevertheless, polling can still + * be performed on the complete sequence. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param Timeout Timeout value in millisecond. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout) +{ + uint32_t tickstart = 0U; + + /* Verification that ADC configuration is compliant with polling for */ + /* each conversion: */ + /* Particular case is ADC configured in DMA mode and ADC sequencer with */ + /* several ranks and polling for end of each conversion. */ + /* For code simplicity sake, this particular case is generalized to */ + /* ADC configured in DMA mode and polling for end of each conversion. */ + if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_EOCS) && + HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_DMA)) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check End of conversion flag */ + while (!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC))) + { + /* Check if timeout is disabled (set to infinite wait) */ + if (Timeout != HAL_MAX_DELAY) + { + if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) + { + /* New check to avoid false timeout detection in case of preemption */ + if (!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC))) + { + /* Update ADC state machine to timeout */ + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_TIMEOUT; + } + } + } + } + + /* Clear regular group conversion flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC); + + /* Update ADC state machine */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + + /* Determine whether any further conversion upcoming on group regular */ + /* by external trigger, continuous mode or scan sequence on going. */ + /* Note: On STM32F4, there is no independent flag of end of sequence. */ + /* The test of scan sequence on going is done either with scan */ + /* sequence disabled or with end of conversion flag set to */ + /* of end of sequence. */ + if (ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) && + (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) || + HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS))) + { + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Return ADC state */ + return HAL_OK; +} + +/** + * @brief Poll for conversion event + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param EventType the ADC event type. + * This parameter can be one of the following values: + * @arg ADC_AWD_EVENT: ADC Analog watch Dog event. + * @arg ADC_OVR_EVENT: ADC Overrun event. + * @param Timeout Timeout value in millisecond. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef *hadc, uint32_t EventType, uint32_t Timeout) +{ + uint32_t tickstart = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_EVENT_TYPE(EventType)); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check selected event flag */ + while (!(__HAL_ADC_GET_FLAG(hadc, EventType))) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) + { + /* New check to avoid false timeout detection in case of preemption */ + if (!(__HAL_ADC_GET_FLAG(hadc, EventType))) + { + /* Update ADC state machine to timeout */ + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_TIMEOUT; + } + } + } + } + + /* Analog watchdog (level out of window) event */ + if (EventType == ADC_AWD_EVENT) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD1); + + /* Clear ADC analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD); + } + /* Overrun event */ + else + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_OVR); + /* Set ADC error code to overrun */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR); + + /* Clear ADC overrun flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); + } + + /* Return ADC state */ + return HAL_OK; +} + + +/** + * @brief Enables the interrupt and starts ADC conversion of regular channels. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef *hadc) +{ + __IO uint32_t counter = 0U; + ADC_Common_TypeDef *tmpADC_Common; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if ((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for ADC stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U)); + while (counter != 0U) + { + counter--; + } + } + + /* Start conversion if ADC is effectively enabled */ + if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular group operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR, + HAL_ADC_STATE_REG_BUSY); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + + /* State machine update: Check if an injected conversion is ongoing */ + if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + /* Reset ADC error code fields related to conversions on group regular */ + CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); + } + else + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADCs and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* Clear regular group conversion flag and overrun flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC | ADC_FLAG_OVR); + + /* Enable end of conversion interrupt for regular group */ + __HAL_ADC_ENABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_OVR)); + + /* Check if Multimode enabled */ + if (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_MULTI)) + { +#if defined(ADC2) && defined(ADC3) + if ((hadc->Instance == ADC1) || ((hadc->Instance == ADC2) && ((ADC->CCR & ADC_CCR_MULTI_Msk) < ADC_CCR_MULTI_0)) \ + || ((hadc->Instance == ADC3) && ((ADC->CCR & ADC_CCR_MULTI_Msk) < ADC_CCR_MULTI_4))) + { +#endif /* ADC2 || ADC3 */ + /* if no external trigger present enable software conversion of regular channels */ + if ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } +#if defined(ADC2) && defined(ADC3) + } +#endif /* ADC2 || ADC3 */ + } + else + { + /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */ + if ((hadc->Instance == ADC1) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables the interrupt and stop ADC conversion of regular channels. + * + * @note Caution: This function will stop also injected channels. + * + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef *hadc) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Check if ADC is effectively disabled */ + if (HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Disable ADC end of conversion interrupt for regular group */ + __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_OVR)); + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Handles ADC interrupt request + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc) +{ + uint32_t tmp1 = 0U, tmp2 = 0U; + + uint32_t tmp_sr = hadc->Instance->SR; + uint32_t tmp_cr1 = hadc->Instance->CR1; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_REGULAR_LENGTH(hadc->Init.NbrOfConversion)); + assert_param(IS_ADC_EOCSelection(hadc->Init.EOCSelection)); + + tmp1 = tmp_sr & ADC_FLAG_EOC; + tmp2 = tmp_cr1 & ADC_IT_EOC; + /* Check End of conversion flag for regular channels */ + if (tmp1 && tmp2) + { + /* Update state machine on conversion status if not in error state */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL)) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + } + + /* Determine whether any further conversion upcoming on group regular */ + /* by external trigger, continuous mode or scan sequence on going. */ + /* Note: On STM32F4, there is no independent flag of end of sequence. */ + /* The test of scan sequence on going is done either with scan */ + /* sequence disabled or with end of conversion flag set to */ + /* of end of sequence. */ + if (ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) && + (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) || + HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS))) + { + /* Disable ADC end of single conversion interrupt on group regular */ + /* Note: Overrun interrupt was enabled with EOC interrupt in */ + /* HAL_ADC_Start_IT(), but is not disabled here because can be used */ + /* by overrun IRQ process below. */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); + + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Conversion complete callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ConvCpltCallback(hadc); +#else + HAL_ADC_ConvCpltCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear regular group conversion flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC); + } + + tmp1 = tmp_sr & ADC_FLAG_JEOC; + tmp2 = tmp_cr1 & ADC_IT_JEOC; + /* Check End of conversion flag for injected channels */ + if (tmp1 && tmp2) + { + /* Update state machine on conversion status if not in error state */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL)) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC); + } + + /* Determine whether any further conversion upcoming on group injected */ + /* by external trigger, scan sequence on going or by automatic injected */ + /* conversion from group regular (same conditions as group regular */ + /* interruption disabling above). */ + if (ADC_IS_SOFTWARE_START_INJECTED(hadc) && + (HAL_IS_BIT_CLR(hadc->Instance->JSQR, ADC_JSQR_JL) || + HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS)) && + (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) && + (ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE)))) + { + /* Disable ADC end of single conversion interrupt on group injected */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); + + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Conversion complete callback */ + /* Conversion complete callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->InjectedConvCpltCallback(hadc); +#else + HAL_ADCEx_InjectedConvCpltCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear injected group conversion flag */ + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC)); + } + + tmp1 = tmp_sr & ADC_FLAG_AWD; + tmp2 = tmp_cr1 & ADC_IT_AWD; + /* Check Analog watchdog flag */ + if (tmp1 && tmp2) + { + if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD)) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD1); + + /* Level out of window callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->LevelOutOfWindowCallback(hadc); +#else + HAL_ADC_LevelOutOfWindowCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear the ADC analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD); + } + } + + tmp1 = tmp_sr & ADC_FLAG_OVR; + tmp2 = tmp_cr1 & ADC_IT_OVR; + /* Check Overrun flag */ + if (tmp1 && tmp2) + { + /* Note: On STM32F4, ADC overrun can be set through other parameters */ + /* refer to description of parameter "EOCSelection" for more */ + /* details. */ + + /* Set ADC error code to overrun */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR); + + /* Clear ADC overrun flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); + + /* Error callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ErrorCallback(hadc); +#else + HAL_ADC_ErrorCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear the Overrun flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); + } +} + +/** + * @brief Enables ADC DMA request after last transfer (Single-ADC mode) and enables ADC peripheral + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param pData The destination Buffer address. + * @param Length The length of data to be transferred from ADC peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length) +{ + __IO uint32_t counter = 0U; + ADC_Common_TypeDef *tmpADC_Common; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if ((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for ADC stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U)); + while (counter != 0U) + { + counter--; + } + } + + /* Check ADC DMA Mode */ + /* - disable the DMA Mode if it is already enabled */ + if ((hadc->Instance->CR2 & ADC_CR2_DMA) == ADC_CR2_DMA) + { + CLEAR_BIT(hadc->Instance->CR2, ADC_CR2_DMA); + } + + /* Start conversion if ADC is effectively enabled */ + if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular group operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR, + HAL_ADC_STATE_REG_BUSY); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + + /* State machine update: Check if an injected conversion is ongoing */ + if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + /* Reset ADC error code fields related to conversions on group regular */ + CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); + } + else + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADCs and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* Set the DMA transfer complete callback */ + hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt; + + /* Set the DMA half transfer complete callback */ + hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt; + + /* Set the DMA error callback */ + hadc->DMA_Handle->XferErrorCallback = ADC_DMAError; + + + /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */ + /* start (in case of SW start): */ + + /* Clear regular group conversion flag and overrun flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC | ADC_FLAG_OVR); + + /* Enable ADC overrun interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + + /* Enable ADC DMA mode */ + hadc->Instance->CR2 |= ADC_CR2_DMA; + + /* Start the DMA channel */ + tmp_hal_status = HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length); + + /* Check if Multimode enabled */ + if (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_MULTI)) + { +#if defined(ADC2) && defined(ADC3) + if ((hadc->Instance == ADC1) || ((hadc->Instance == ADC2) && ((ADC->CCR & ADC_CCR_MULTI_Msk) < ADC_CCR_MULTI_0)) \ + || ((hadc->Instance == ADC3) && ((ADC->CCR & ADC_CCR_MULTI_Msk) < ADC_CCR_MULTI_4))) + { +#endif /* ADC2 || ADC3 */ + /* if no external trigger present enable software conversion of regular channels */ + if ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } +#if defined(ADC2) && defined(ADC3) + } +#endif /* ADC2 || ADC3 */ + } + else + { + /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */ + if ((hadc->Instance == ADC1) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Disables ADC DMA (Single-ADC mode) and disables ADC peripheral + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Check if ADC is effectively disabled */ + if (HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Disable the selected ADC DMA mode */ + hadc->Instance->CR2 &= ~ADC_CR2_DMA; + + /* Disable the DMA channel (in case of DMA in circular mode or stop while */ + /* DMA transfer is on going) */ + if (hadc->DMA_Handle->State == HAL_DMA_STATE_BUSY) + { + tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); + + /* Check if DMA channel effectively disabled */ + if (tmp_hal_status != HAL_OK) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA); + } + } + + /* Disable ADC overrun interrupt */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Gets the converted value from data register of regular channel. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval Converted value + */ +uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc) +{ + /* Return the selected ADC converted value */ + return hadc->Instance->DR; +} + +/** + * @brief Regular conversion complete callback in non blocking mode + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_ConvCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Regular conversion half DMA transfer callback in non blocking mode + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_ConvHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Analog watchdog callback in non blocking mode + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_LevelOoutOfWindowCallback could be implemented in the user file + */ +} + +/** + * @brief Error ADC callback. + * @note In case of error due to overrun when using ADC with DMA transfer + * (HAL ADC handle parameter "ErrorCode" to state "HAL_ADC_ERROR_OVR"): + * - Reinitialize the DMA using function "HAL_ADC_Stop_DMA()". + * - If needed, restart a new ADC conversion using function + * "HAL_ADC_Start_DMA()" + * (this function is also clearing overrun flag) + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure regular channels. + (+) Configure injected channels. + (+) Configure multimode. + (+) Configure the analog watch dog. + +@endverbatim + * @{ + */ + +/** +* @brief Configures for the selected ADC regular channel its corresponding +* rank in the sequencer and its sample time. +* @param hadc pointer to a ADC_HandleTypeDef structure that contains +* the configuration information for the specified ADC. +* @param sConfig ADC configuration structure. +* @retval HAL status +*/ +HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConfTypeDef *sConfig) +{ + __IO uint32_t counter = 0U; + ADC_Common_TypeDef *tmpADC_Common; + + /* Check the parameters */ + assert_param(IS_ADC_CHANNEL(sConfig->Channel)); + assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank)); + assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ + if (sConfig->Channel > ADC_CHANNEL_9) + { + /* Clear the old sample time */ + hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel); + + /* Set the new sample time */ + hadc->Instance->SMPR1 |= ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel); + } + else /* ADC_Channel include in ADC_Channel_[0..9] */ + { + /* Clear the old sample time */ + hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel); + + /* Set the new sample time */ + hadc->Instance->SMPR2 |= ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel); + } + + /* For Rank 1 to 6 */ + if (sConfig->Rank < 7U) + { + /* Clear the old SQx bits for the selected rank */ + hadc->Instance->SQR3 &= ~ADC_SQR3_RK(ADC_SQR3_SQ1, sConfig->Rank); + + /* Set the SQx bits for the selected rank */ + hadc->Instance->SQR3 |= ADC_SQR3_RK(sConfig->Channel, sConfig->Rank); + } + /* For Rank 7 to 12 */ + else if (sConfig->Rank < 13U) + { + /* Clear the old SQx bits for the selected rank */ + hadc->Instance->SQR2 &= ~ADC_SQR2_RK(ADC_SQR2_SQ7, sConfig->Rank); + + /* Set the SQx bits for the selected rank */ + hadc->Instance->SQR2 |= ADC_SQR2_RK(sConfig->Channel, sConfig->Rank); + } + /* For Rank 13 to 16 */ + else + { + /* Clear the old SQx bits for the selected rank */ + hadc->Instance->SQR1 &= ~ADC_SQR1_RK(ADC_SQR1_SQ13, sConfig->Rank); + + /* Set the SQx bits for the selected rank */ + hadc->Instance->SQR1 |= ADC_SQR1_RK(sConfig->Channel, sConfig->Rank); + } + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADCs and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* if ADC1 Channel_18 is selected for VBAT Channel ennable VBATE */ + if ((hadc->Instance == ADC1) && (sConfig->Channel == ADC_CHANNEL_VBAT)) + { + /* Disable the TEMPSENSOR channel in case of using board with multiplixed ADC_CHANNEL_VBAT & ADC_CHANNEL_TEMPSENSOR*/ + if ((uint16_t)ADC_CHANNEL_TEMPSENSOR == (uint16_t)ADC_CHANNEL_VBAT) + { + tmpADC_Common->CCR &= ~ADC_CCR_TSVREFE; + } + /* Enable the VBAT channel*/ + tmpADC_Common->CCR |= ADC_CCR_VBATE; + } + + /* if ADC1 Channel_16 or Channel_18 is selected for Temperature sensor or + Channel_17 is selected for VREFINT enable TSVREFE */ + if ((hadc->Instance == ADC1) && ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) || (sConfig->Channel == ADC_CHANNEL_VREFINT))) + { + /* Disable the VBAT channel in case of using board with multiplixed ADC_CHANNEL_VBAT & ADC_CHANNEL_TEMPSENSOR*/ + if ((uint16_t)ADC_CHANNEL_TEMPSENSOR == (uint16_t)ADC_CHANNEL_VBAT) + { + tmpADC_Common->CCR &= ~ADC_CCR_VBATE; + } + /* Enable the Temperature sensor and VREFINT channel*/ + tmpADC_Common->CCR |= ADC_CCR_TSVREFE; + + if (sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) + { + /* Delay for temperature sensor stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000U)); + while (counter != 0U) + { + counter--; + } + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configures the analog watchdog. + * @note Analog watchdog thresholds can be modified while ADC conversion + * is on going. + * In this case, some constraints must be taken into account: + * The programmed threshold values are effective from the next + * ADC EOC (end of unitary conversion). + * Considering that registers write delay may happen due to + * bus activity, this might cause an uncertainty on the + * effective timing of the new programmed threshold values. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param AnalogWDGConfig pointer to an ADC_AnalogWDGConfTypeDef structure + * that contains the configuration information of ADC analog watchdog. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, ADC_AnalogWDGConfTypeDef *AnalogWDGConfig) +{ +#ifdef USE_FULL_ASSERT + uint32_t tmp = 0U; +#endif /* USE_FULL_ASSERT */ + + /* Check the parameters */ + assert_param(IS_ADC_ANALOG_WATCHDOG(AnalogWDGConfig->WatchdogMode)); + assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel)); + assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode)); + +#ifdef USE_FULL_ASSERT + tmp = ADC_GET_RESOLUTION(hadc); + assert_param(IS_ADC_RANGE(tmp, AnalogWDGConfig->HighThreshold)); + assert_param(IS_ADC_RANGE(tmp, AnalogWDGConfig->LowThreshold)); +#endif /* USE_FULL_ASSERT */ + + /* Process locked */ + __HAL_LOCK(hadc); + + if (AnalogWDGConfig->ITMode == ENABLE) + { + /* Enable the ADC Analog watchdog interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_AWD); + } + else + { + /* Disable the ADC Analog watchdog interrupt */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD); + } + + /* Clear AWDEN, JAWDEN and AWDSGL bits */ + hadc->Instance->CR1 &= ~(ADC_CR1_AWDSGL | ADC_CR1_JAWDEN | ADC_CR1_AWDEN); + + /* Set the analog watchdog enable mode */ + hadc->Instance->CR1 |= AnalogWDGConfig->WatchdogMode; + + /* Set the high threshold */ + hadc->Instance->HTR = AnalogWDGConfig->HighThreshold; + + /* Set the low threshold */ + hadc->Instance->LTR = AnalogWDGConfig->LowThreshold; + + /* Clear the Analog watchdog channel select bits */ + hadc->Instance->CR1 &= ~ADC_CR1_AWDCH; + + /* Set the Analog watchdog channel */ + hadc->Instance->CR1 |= (uint32_t)((uint16_t)(AnalogWDGConfig->Channel)); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions_Group4 ADC Peripheral State functions + * @brief ADC Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the ADC state + (+) Check the ADC Error + +@endverbatim + * @{ + */ + +/** + * @brief return the ADC state + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL state + */ +uint32_t HAL_ADC_GetState(ADC_HandleTypeDef *hadc) +{ + /* Return ADC state */ + return hadc->State; +} + +/** + * @brief Return the ADC error code + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval ADC Error Code + */ +uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc) +{ + return hadc->ErrorCode; +} + +/** + * @} + */ + +/** @addtogroup ADC_Private_Functions + * @{ + */ + +/** + * @brief Initializes the ADCx peripheral according to the specified parameters + * in the ADC_InitStruct without initializing the ADC MSP. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +static void ADC_Init(ADC_HandleTypeDef *hadc) +{ + ADC_Common_TypeDef *tmpADC_Common; + + /* Set ADC parameters */ + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADCs and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* Set the ADC clock prescaler */ + tmpADC_Common->CCR &= ~(ADC_CCR_ADCPRE); + tmpADC_Common->CCR |= hadc->Init.ClockPrescaler; + + /* Set ADC scan mode */ + hadc->Instance->CR1 &= ~(ADC_CR1_SCAN); + hadc->Instance->CR1 |= ADC_CR1_SCANCONV(hadc->Init.ScanConvMode); + + /* Set ADC resolution */ + hadc->Instance->CR1 &= ~(ADC_CR1_RES); + hadc->Instance->CR1 |= hadc->Init.Resolution; + + /* Set ADC data alignment */ + hadc->Instance->CR2 &= ~(ADC_CR2_ALIGN); + hadc->Instance->CR2 |= hadc->Init.DataAlign; + + /* Enable external trigger if trigger selection is different of software */ + /* start. */ + /* Note: This configuration keeps the hardware feature of parameter */ + /* ExternalTrigConvEdge "trigger edge none" equivalent to */ + /* software start. */ + if (hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START) + { + /* Select external trigger to start conversion */ + hadc->Instance->CR2 &= ~(ADC_CR2_EXTSEL); + hadc->Instance->CR2 |= hadc->Init.ExternalTrigConv; + + /* Select external trigger polarity */ + hadc->Instance->CR2 &= ~(ADC_CR2_EXTEN); + hadc->Instance->CR2 |= hadc->Init.ExternalTrigConvEdge; + } + else + { + /* Reset the external trigger */ + hadc->Instance->CR2 &= ~(ADC_CR2_EXTSEL); + hadc->Instance->CR2 &= ~(ADC_CR2_EXTEN); + } + + /* Enable or disable ADC continuous conversion mode */ + hadc->Instance->CR2 &= ~(ADC_CR2_CONT); + hadc->Instance->CR2 |= ADC_CR2_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode); + + if (hadc->Init.DiscontinuousConvMode != DISABLE) + { + assert_param(IS_ADC_REGULAR_DISC_NUMBER(hadc->Init.NbrOfDiscConversion)); + + /* Enable the selected ADC regular discontinuous mode */ + hadc->Instance->CR1 |= (uint32_t)ADC_CR1_DISCEN; + + /* Set the number of channels to be converted in discontinuous mode */ + hadc->Instance->CR1 &= ~(ADC_CR1_DISCNUM); + hadc->Instance->CR1 |= ADC_CR1_DISCONTINUOUS(hadc->Init.NbrOfDiscConversion); + } + else + { + /* Disable the selected ADC regular discontinuous mode */ + hadc->Instance->CR1 &= ~(ADC_CR1_DISCEN); + } + + /* Set ADC number of conversion */ + hadc->Instance->SQR1 &= ~(ADC_SQR1_L); + hadc->Instance->SQR1 |= ADC_SQR1(hadc->Init.NbrOfConversion); + + /* Enable or disable ADC DMA continuous request */ + hadc->Instance->CR2 &= ~(ADC_CR2_DDS); + hadc->Instance->CR2 |= ADC_CR2_DMAContReq((uint32_t)hadc->Init.DMAContinuousRequests); + + /* Enable or disable ADC end of conversion selection */ + hadc->Instance->CR2 &= ~(ADC_CR2_EOCS); + hadc->Instance->CR2 |= ADC_CR2_EOCSelection(hadc->Init.EOCSelection); +} + +/** + * @brief DMA transfer complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Update state machine on conversion status if not in error state */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) + { + /* Update ADC state machine */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + + /* Determine whether any further conversion upcoming on group regular */ + /* by external trigger, continuous mode or scan sequence on going. */ + /* Note: On STM32F4, there is no independent flag of end of sequence. */ + /* The test of scan sequence on going is done either with scan */ + /* sequence disabled or with end of conversion flag set to */ + /* of end of sequence. */ + if (ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) && + (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) || + HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS))) + { + /* Disable ADC end of single conversion interrupt on group regular */ + /* Note: Overrun interrupt was enabled with EOC interrupt in */ + /* HAL_ADC_Start_IT(), but is not disabled here because can be used */ + /* by overrun IRQ process below. */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); + + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Conversion complete callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ConvCpltCallback(hadc); +#else + HAL_ADC_ConvCpltCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + } + else /* DMA and-or internal error occurred */ + { + if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) != 0UL) + { + /* Call HAL ADC Error Callback function */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ErrorCallback(hadc); +#else + HAL_ADC_ErrorCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + } + else + { + /* Call DMA error callback */ + hadc->DMA_Handle->XferErrorCallback(hdma); + } + } +} + +/** + * @brief DMA half transfer complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma) +{ + ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + /* Half conversion callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ConvHalfCpltCallback(hadc); +#else + HAL_ADC_ConvHalfCpltCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA error callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_DMAError(DMA_HandleTypeDef *hdma) +{ + ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + hadc->State = HAL_ADC_STATE_ERROR_DMA; + /* Set ADC error code to DMA error */ + hadc->ErrorCode |= HAL_ADC_ERROR_DMA; + /* Error callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ErrorCallback(hadc); +#else + HAL_ADC_ErrorCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_ADC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c b/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c new file mode 100644 index 00000000..9e7a6699 --- /dev/null +++ b/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c @@ -0,0 +1,1115 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_adc_ex.c + * @author MCD Application Team + * @brief This file provides firmware functions to manage the following + * functionalities of the ADC extension peripheral: + * + Extended features 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 ##### + ============================================================================== + [..] + (#)Initialize the ADC low level resources by implementing the HAL_ADC_MspInit(): + (##) Enable the ADC interface clock using __HAL_RCC_ADC_CLK_ENABLE() + (##) ADC pins configuration + (+++) Enable the clock for the ADC GPIOs using the following function: + __HAL_RCC_GPIOx_CLK_ENABLE() + (+++) Configure these ADC pins in analog mode using HAL_GPIO_Init() + (##) In case of using interrupts (e.g. HAL_ADC_Start_IT()) + (+++) Configure the ADC interrupt priority using HAL_NVIC_SetPriority() + (+++) Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ() + (+++) In ADC IRQ handler, call HAL_ADC_IRQHandler() + (##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA()) + (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE() + (+++) Configure and enable two DMA streams stream for managing data + transfer from peripheral to memory (output stream) + (+++) Associate the initialized DMA handle to the ADC DMA handle + using __HAL_LINKDMA() + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the two DMA Streams. The output stream should have higher + priority than the input stream. + (#) Configure the ADC Prescaler, conversion resolution and data alignment + using the HAL_ADC_Init() function. + + (#) Configure the ADC Injected channels group features, use HAL_ADC_Init() + and HAL_ADC_ConfigChannel() functions. + + (#) Three operation modes are available within this driver: + + *** Polling mode IO operation *** + ================================= + [..] + (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart() + (+) Wait for end of conversion using HAL_ADC_PollForConversion(), at this stage + user can specify the value of timeout according to his end application + (+) To read the ADC converted values, use the HAL_ADCEx_InjectedGetValue() function. + (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart_IT() + (+) Use HAL_ADC_IRQHandler() called under ADC_IRQHandler() Interrupt subroutine + (+) At ADC end of conversion HAL_ADCEx_InjectedConvCpltCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADCEx_InjectedConvCpltCallback + (+) In case of ADC Error, HAL_ADCEx_InjectedErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADCEx_InjectedErrorCallback + (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop_IT() + + *** Multi mode ADCs Regular channels configuration *** + ====================================================== + [..] + (+) Select the Multi mode ADC regular channels features (dual or triple mode) + and configure the DMA mode using HAL_ADCEx_MultiModeConfigChannel() functions. + (+) Start the ADC peripheral using HAL_ADCEx_MultiModeStart_DMA(), at this stage the user specify the length + of data to be transferred at each end of conversion + (+) Read the ADCs converted values using the HAL_ADCEx_MultiModeGetValue() function. + + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup ADCEx ADCEx + * @brief ADC Extended driver modules + * @{ + */ + +#ifdef HAL_ADC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup ADCEx_Private_Functions + * @{ + */ +/* Private function prototypes -----------------------------------------------*/ +static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma); +static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma); +static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup ADCEx_Exported_Functions ADC Exported Functions + * @{ + */ + +/** @defgroup ADCEx_Exported_Functions_Group1 Extended features functions + * @brief Extended features functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion of injected channel. + (+) Stop conversion of injected channel. + (+) Start multimode and enable DMA transfer. + (+) Stop multimode and disable DMA transfer. + (+) Get result of injected channel conversion. + (+) Get result of multimode conversion. + (+) Configure injected channels. + (+) Configure multimode. + +@endverbatim + * @{ + */ + +/** + * @brief Enables the selected ADC software start conversion of the injected channels. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef *hadc) +{ + __IO uint32_t counter = 0U; + uint32_t tmp1 = 0U, tmp2 = 0U; + ADC_Common_TypeDef *tmpADC_Common; + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if ((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for ADC stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U)); + while (counter != 0U) + { + counter--; + } + } + + /* Start conversion if ADC is effectively enabled */ + if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Set ADC state */ + /* - Clear state bitfield related to injected group conversion results */ + /* - Set state bitfield related to injected operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC, + HAL_ADC_STATE_INJ_BUSY); + + /* Check if a regular conversion is ongoing */ + /* Note: On this device, there is no ADC error code fields related to */ + /* conversions on group injected only. In case of conversion on */ + /* going on group regular, no error code is reset. */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)) + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Clear injected group conversion flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC); + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADC and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* Check if Multimode enabled */ + if (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_MULTI)) + { + tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); + tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); + if (tmp1 && tmp2) + { + /* Enable the selected ADC software conversion for injected group */ + hadc->Instance->CR2 |= ADC_CR2_JSWSTART; + } + } + else + { + tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); + tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); + if ((hadc->Instance == ADC1) && tmp1 && tmp2) + { + /* Enable the selected ADC software conversion for injected group */ + hadc->Instance->CR2 |= ADC_CR2_JSWSTART; + } + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Enables the interrupt and starts ADC conversion of injected channels. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef *hadc) +{ + __IO uint32_t counter = 0U; + uint32_t tmp1 = 0U, tmp2 = 0U; + ADC_Common_TypeDef *tmpADC_Common; + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if ((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for ADC stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U)); + while (counter != 0U) + { + counter--; + } + } + + /* Start conversion if ADC is effectively enabled */ + if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Set ADC state */ + /* - Clear state bitfield related to injected group conversion results */ + /* - Set state bitfield related to injected operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC, + HAL_ADC_STATE_INJ_BUSY); + + /* Check if a regular conversion is ongoing */ + /* Note: On this device, there is no ADC error code fields related to */ + /* conversions on group injected only. In case of conversion on */ + /* going on group regular, no error code is reset. */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)) + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Clear injected group conversion flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC); + + /* Enable end of conversion interrupt for injected channels */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC); + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADC and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* Check if Multimode enabled */ + if (HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_MULTI)) + { + tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); + tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); + if (tmp1 && tmp2) + { + /* Enable the selected ADC software conversion for injected group */ + hadc->Instance->CR2 |= ADC_CR2_JSWSTART; + } + } + else + { + tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); + tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); + if ((hadc->Instance == ADC1) && tmp1 && tmp2) + { + /* Enable the selected ADC software conversion for injected group */ + hadc->Instance->CR2 |= ADC_CR2_JSWSTART; + } + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop conversion of injected channels. Disable ADC peripheral if + * no regular conversion is on going. + * @note If ADC must be disabled and if conversion is on going on + * regular group, function HAL_ADC_Stop must be used to stop both + * injected and regular groups, and disable the ADC. + * @note If injected group mode auto-injection is enabled, + * function HAL_ADC_Stop must be used. + * @note In case of auto-injection mode, HAL_ADC_Stop must be used. + * @param hadc ADC handle + * @retval None + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion and disable ADC peripheral */ + /* Conditioned to: */ + /* - No conversion on the other group (regular group) is intended to */ + /* continue (injected and regular groups stop conversion and ADC disable */ + /* are common) */ + /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */ + if (((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) && + HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO)) + { + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Check if ADC is effectively disabled */ + if (HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Poll for injected conversion complete + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param Timeout Timeout value in millisecond. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout) +{ + uint32_t tickstart = 0U; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check End of conversion flag */ + while (!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC))) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) + { + /* New check to avoid false timeout detection in case of preemption */ + if (!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC))) + { + hadc->State = HAL_ADC_STATE_TIMEOUT; + /* Process unlocked */ + __HAL_UNLOCK(hadc); + return HAL_TIMEOUT; + } + } + } + } + + /* Clear injected group conversion flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JSTRT | ADC_FLAG_JEOC); + + /* Update ADC state machine */ + SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC); + + /* Determine whether any further conversion upcoming on group injected */ + /* by external trigger, continuous mode or scan sequence on going. */ + /* Note: On STM32F4, there is no independent flag of end of sequence. */ + /* The test of scan sequence on going is done either with scan */ + /* sequence disabled or with end of conversion flag set to */ + /* of end of sequence. */ + if (ADC_IS_SOFTWARE_START_INJECTED(hadc) && + (HAL_IS_BIT_CLR(hadc->Instance->JSQR, ADC_JSQR_JL) || + HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS)) && + (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) && + (ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE)))) + { + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Return ADC state */ + return HAL_OK; +} + +/** + * @brief Stop conversion of injected channels, disable interruption of + * end-of-conversion. Disable ADC peripheral if no regular conversion + * is on going. + * @note If ADC must be disabled and if conversion is on going on + * regular group, function HAL_ADC_Stop must be used to stop both + * injected and regular groups, and disable the ADC. + * @note If injected group mode auto-injection is enabled, + * function HAL_ADC_Stop must be used. + * @param hadc ADC handle + * @retval None + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion and disable ADC peripheral */ + /* Conditioned to: */ + /* - No conversion on the other group (regular group) is intended to */ + /* continue (injected and regular groups stop conversion and ADC disable */ + /* are common) */ + /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */ + if (((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) && + HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO)) + { + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Check if ADC is effectively disabled */ + if (HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Disable ADC end of conversion interrupt for injected channels */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Gets the converted value from data register of injected channel. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param InjectedRank the ADC injected rank. + * This parameter can be one of the following values: + * @arg ADC_INJECTED_RANK_1: Injected Channel1 selected + * @arg ADC_INJECTED_RANK_2: Injected Channel2 selected + * @arg ADC_INJECTED_RANK_3: Injected Channel3 selected + * @arg ADC_INJECTED_RANK_4: Injected Channel4 selected + * @retval None + */ +uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef *hadc, uint32_t InjectedRank) +{ + __IO uint32_t tmp = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_INJECTED_RANK(InjectedRank)); + + /* Clear injected group conversion flag to have similar behaviour as */ + /* regular group: reading data register also clears end of conversion flag. */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC); + + /* Return the selected ADC converted value */ + switch (InjectedRank) + { + case ADC_INJECTED_RANK_4: + { + tmp = hadc->Instance->JDR4; + } + break; + case ADC_INJECTED_RANK_3: + { + tmp = hadc->Instance->JDR3; + } + break; + case ADC_INJECTED_RANK_2: + { + tmp = hadc->Instance->JDR2; + } + break; + case ADC_INJECTED_RANK_1: + { + tmp = hadc->Instance->JDR1; + } + break; + default: + break; + } + return tmp; +} + +/** + * @brief Enables ADC DMA request after last transfer (Multi-ADC mode) and enables ADC peripheral + * + * @note Caution: This function must be used only with the ADC master. + * + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param pData Pointer to buffer in which transferred from ADC peripheral to memory will be stored. + * @param Length The length of data to be transferred from ADC peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length) +{ + __IO uint32_t counter = 0U; + ADC_Common_TypeDef *tmpADC_Common; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if ((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for temperature sensor stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U)); + while (counter != 0U) + { + counter--; + } + } + + /* Start conversion if ADC is effectively enabled */ + if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular group operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR, + HAL_ADC_STATE_REG_BUSY); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + + /* State machine update: Check if an injected conversion is ongoing */ + if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + /* Reset ADC error code fields related to conversions on group regular */ + CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); + } + else + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Set the DMA transfer complete callback */ + hadc->DMA_Handle->XferCpltCallback = ADC_MultiModeDMAConvCplt; + + /* Set the DMA half transfer complete callback */ + hadc->DMA_Handle->XferHalfCpltCallback = ADC_MultiModeDMAHalfConvCplt; + + /* Set the DMA error callback */ + hadc->DMA_Handle->XferErrorCallback = ADC_MultiModeDMAError ; + + /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */ + /* start (in case of SW start): */ + + /* Clear regular group conversion flag and overrun flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC); + + /* Enable ADC overrun interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADC and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + if (hadc->Init.DMAContinuousRequests != DISABLE) + { + /* Enable the selected ADC DMA request after last transfer */ + tmpADC_Common->CCR |= ADC_CCR_DDS; + } + else + { + /* Disable the selected ADC EOC rising on each regular channel conversion */ + tmpADC_Common->CCR &= ~ADC_CCR_DDS; + } + + /* Enable the DMA Stream */ + tmp_hal_status = HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&tmpADC_Common->CDR, (uint32_t)pData, Length); + + /* if no external trigger present enable software conversion of regular channels */ + if ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Disables ADC DMA (multi-ADC mode) and disables ADC peripheral + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + ADC_Common_TypeDef *tmpADC_Common; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADC and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* Check if ADC is effectively disabled */ + if (HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) + { + /* Disable the selected ADC DMA mode for multimode */ + tmpADC_Common->CCR &= ~ADC_CCR_DDS; + + /* Disable the DMA channel (in case of DMA in circular mode or stop while */ + /* DMA transfer is on going) */ + tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); + + /* Disable ADC overrun interrupt */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Returns the last ADC1, ADC2 and ADC3 regular conversions results + * data in the selected multi mode. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval The converted data value. + */ +uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef *hadc) +{ + ADC_Common_TypeDef *tmpADC_Common; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADC and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* Return the multi mode conversion value */ + return tmpADC_Common->CDR; +} + +/** + * @brief Injected conversion complete callback in non blocking mode + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_InjectedConvCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Configures for the selected ADC injected channel its corresponding + * rank in the sequencer and its sample time. + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param sConfigInjected ADC configuration structure for injected channel. + * @retval None + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, ADC_InjectionConfTypeDef *sConfigInjected) +{ + +#ifdef USE_FULL_ASSERT + uint32_t tmp = 0U; + +#endif /* USE_FULL_ASSERT */ + + ADC_Common_TypeDef *tmpADC_Common; + + /* Check the parameters */ + assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel)); + assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank)); + assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime)); + assert_param(IS_ADC_EXT_INJEC_TRIG(sConfigInjected->ExternalTrigInjecConv)); + assert_param(IS_ADC_INJECTED_LENGTH(sConfigInjected->InjectedNbrOfConversion)); + assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv)); + assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode)); + +#ifdef USE_FULL_ASSERT + tmp = ADC_GET_RESOLUTION(hadc); + assert_param(IS_ADC_RANGE(tmp, sConfigInjected->InjectedOffset)); +#endif /* USE_FULL_ASSERT */ + + if (sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START) + { + assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(sConfigInjected->ExternalTrigInjecConvEdge)); + } + + /* Process locked */ + __HAL_LOCK(hadc); + + /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ + if (sConfigInjected->InjectedChannel > ADC_CHANNEL_9) + { + /* Clear the old sample time */ + hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel); + + /* Set the new sample time */ + hadc->Instance->SMPR1 |= ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel); + } + else /* ADC_Channel include in ADC_Channel_[0..9] */ + { + /* Clear the old sample time */ + hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel); + + /* Set the new sample time */ + hadc->Instance->SMPR2 |= ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel); + } + + /*---------------------------- ADCx JSQR Configuration -----------------*/ + hadc->Instance->JSQR &= ~(ADC_JSQR_JL); + hadc->Instance->JSQR |= ADC_SQR1(sConfigInjected->InjectedNbrOfConversion); + + /* Rank configuration */ + + /* Clear the old SQx bits for the selected rank */ + hadc->Instance->JSQR &= ~ADC_JSQR(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion); + + /* Set the SQx bits for the selected rank */ + hadc->Instance->JSQR |= ADC_JSQR(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion); + + /* Enable external trigger if trigger selection is different of software */ + /* start. */ + /* Note: This configuration keeps the hardware feature of parameter */ + /* ExternalTrigConvEdge "trigger edge none" equivalent to */ + /* software start. */ + if (sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START) + { + /* Select external trigger to start conversion */ + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); + hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConv; + + /* Select external trigger polarity */ + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN); + hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConvEdge; + } + else + { + /* Reset the external trigger */ + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN); + } + + if (sConfigInjected->AutoInjectedConv != DISABLE) + { + /* Enable the selected ADC automatic injected group conversion */ + hadc->Instance->CR1 |= ADC_CR1_JAUTO; + } + else + { + /* Disable the selected ADC automatic injected group conversion */ + hadc->Instance->CR1 &= ~(ADC_CR1_JAUTO); + } + + if (sConfigInjected->InjectedDiscontinuousConvMode != DISABLE) + { + /* Enable the selected ADC injected discontinuous mode */ + hadc->Instance->CR1 |= ADC_CR1_JDISCEN; + } + else + { + /* Disable the selected ADC injected discontinuous mode */ + hadc->Instance->CR1 &= ~(ADC_CR1_JDISCEN); + } + + switch (sConfigInjected->InjectedRank) + { + case 1U: + /* Set injected channel 1 offset */ + hadc->Instance->JOFR1 &= ~(ADC_JOFR1_JOFFSET1); + hadc->Instance->JOFR1 |= sConfigInjected->InjectedOffset; + break; + case 2U: + /* Set injected channel 2 offset */ + hadc->Instance->JOFR2 &= ~(ADC_JOFR2_JOFFSET2); + hadc->Instance->JOFR2 |= sConfigInjected->InjectedOffset; + break; + case 3U: + /* Set injected channel 3 offset */ + hadc->Instance->JOFR3 &= ~(ADC_JOFR3_JOFFSET3); + hadc->Instance->JOFR3 |= sConfigInjected->InjectedOffset; + break; + default: + /* Set injected channel 4 offset */ + hadc->Instance->JOFR4 &= ~(ADC_JOFR4_JOFFSET4); + hadc->Instance->JOFR4 |= sConfigInjected->InjectedOffset; + break; + } + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADC and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* if ADC1 Channel_18 is selected enable VBAT Channel */ + if ((hadc->Instance == ADC1) && (sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT)) + { + /* Enable the VBAT channel*/ + tmpADC_Common->CCR |= ADC_CCR_VBATE; + } + + /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */ + if ((hadc->Instance == ADC1) && ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT))) + { + /* Enable the TSVREFE channel*/ + tmpADC_Common->CCR |= ADC_CCR_TSVREFE; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configures the ADC multi-mode + * @param hadc pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param multimode pointer to an ADC_MultiModeTypeDef structure that contains + * the configuration information for multimode. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef *hadc, ADC_MultiModeTypeDef *multimode) +{ + + ADC_Common_TypeDef *tmpADC_Common; + + /* Check the parameters */ + assert_param(IS_ADC_MODE(multimode->Mode)); + assert_param(IS_ADC_DMA_ACCESS_MODE(multimode->DMAAccessMode)); + assert_param(IS_ADC_SAMPLING_DELAY(multimode->TwoSamplingDelay)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Pointer to the common control register to which is belonging hadc */ + /* (Depending on STM32F4 product, there may be up to 3 ADC and 1 common */ + /* control register) */ + tmpADC_Common = ADC_COMMON_REGISTER(hadc); + + /* Set ADC mode */ + tmpADC_Common->CCR &= ~(ADC_CCR_MULTI); + tmpADC_Common->CCR |= multimode->Mode; + + /* Set the ADC DMA access mode */ + tmpADC_Common->CCR &= ~(ADC_CCR_DMA); + tmpADC_Common->CCR |= multimode->DMAAccessMode; + + /* Set delay between two sampling phases */ + tmpADC_Common->CCR &= ~(ADC_CCR_DELAY); + tmpADC_Common->CCR |= multimode->TwoSamplingDelay; + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** + * @brief DMA transfer complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Update state machine on conversion status if not in error state */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) + { + /* Update ADC state machine */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + + /* Determine whether any further conversion upcoming on group regular */ + /* by external trigger, continuous mode or scan sequence on going. */ + /* Note: On STM32F4, there is no independent flag of end of sequence. */ + /* The test of scan sequence on going is done either with scan */ + /* sequence disabled or with end of conversion flag set to */ + /* of end of sequence. */ + if (ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) && + (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) || + HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS))) + { + /* Disable ADC end of single conversion interrupt on group regular */ + /* Note: Overrun interrupt was enabled with EOC interrupt in */ + /* HAL_ADC_Start_IT(), but is not disabled here because can be used */ + /* by overrun IRQ process below. */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); + + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Conversion complete callback */ + HAL_ADC_ConvCpltCallback(hadc); + } + else + { + /* Call DMA error callback */ + hadc->DMA_Handle->XferErrorCallback(hdma); + } +} + +/** + * @brief DMA half transfer complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma) +{ + ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + /* Conversion complete callback */ + HAL_ADC_ConvHalfCpltCallback(hadc); +} + +/** + * @brief DMA error callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma) +{ + ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + hadc->State = HAL_ADC_STATE_ERROR_DMA; + /* Set ADC error code to DMA error */ + hadc->ErrorCode |= HAL_ADC_ERROR_DMA; + HAL_ADC_ErrorCallback(hadc); +} + +/** + * @} + */ + +#endif /* HAL_ADC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/Inc/FreeRTOSConfig.h b/Inc/FreeRTOSConfig.h index 7090954b..c07a15d4 100644 --- a/Inc/FreeRTOSConfig.h +++ b/Inc/FreeRTOSConfig.h @@ -74,19 +74,11 @@ #define configUSE_16_BIT_TICKS 0 #define configUSE_MUTEXES 1 #define configQUEUE_REGISTRY_SIZE 8 +#define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_MALLOC_FAILED_HOOK 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -/* USER CODE BEGIN FREE_RTOS_CONFIG_HARDENING */ -/* 栈溢出机械检测(2026-09-20 存储套件死机事故后加):模式 2 在每次上下文切换 - * 检查栈底水位线,溢出即调 vApplicationStackOverflowHook(报任务名+复位)。 - * 关闭检测时溢出会静默腐蚀堆相邻块(其它任务栈/TCB),表现为无异常、不可定位 - * 的全系统冻结——本次事故签名。开销:每次切换一次字比较,可忽略。 - * ⚠ 本段为手工添加,CubeMX 重生成会删除(2026-09-29 实测),改完须核对本块存在 */ -#define configCHECK_FOR_STACK_OVERFLOW 2 -/* pvPortMalloc 失败钩子(只告警不复位:分配失败路径由各调用点 NULL 检查处理) */ -#define configUSE_MALLOC_FAILED_HOOK 1 -/* USER CODE END FREE_RTOS_CONFIG_HARDENING */ /* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ /* Defaults to size_t for backward compatibility, but can be changed if lengths will always be less than the number of bytes in a size_t. */ diff --git a/Inc/adc.h b/Inc/adc.h new file mode 100644 index 00000000..864984b6 --- /dev/null +++ b/Inc/adc.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.h + * @brief This file contains all the function prototypes for + * the adc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 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. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __ADC_H__ +#define __ADC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern ADC_HandleTypeDef hadc1; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_ADC1_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ADC_H__ */ diff --git a/Inc/main.h b/Inc/main.h index cc8e661d..dffdca16 100644 --- a/Inc/main.h +++ b/Inc/main.h @@ -59,6 +59,24 @@ void Error_Handler(void); /* Private defines -----------------------------------------------------------*/ #define CH395_INT_Pin GPIO_PIN_5 #define CH395_INT_GPIO_Port GPIOE +#define ADC9_RES_Pin GPIO_PIN_0 +#define ADC9_RES_GPIO_Port GPIOA +#define ADC10_IC_Pin GPIO_PIN_1 +#define ADC10_IC_GPIO_Port GPIOA +#define ADC11_IN_Pin GPIO_PIN_2 +#define ADC11_IN_GPIO_Port GPIOA +#define ADC12_UC_Pin GPIO_PIN_3 +#define ADC12_UC_GPIO_Port GPIOA +#define ADC13_RES_Pin GPIO_PIN_4 +#define ADC13_RES_GPIO_Port GPIOA +#define ADC14_TEMP_Pin GPIO_PIN_5 +#define ADC14_TEMP_GPIO_Port GPIOA +#define ADC15_IB_Pin GPIO_PIN_6 +#define ADC15_IB_GPIO_Port GPIOA +#define ADC16_RES_Pin GPIO_PIN_7 +#define ADC16_RES_GPIO_Port GPIOA +#define ADC17_UB_Pin GPIO_PIN_4 +#define ADC17_UB_GPIO_Port GPIOC #define LED1_Pin GPIO_PIN_5 #define LED1_GPIO_Port GPIOC #define LED2_Pin GPIO_PIN_0 diff --git a/Inc/stm32f4xx_hal_conf.h b/Inc/stm32f4xx_hal_conf.h index db48ddc4..1d0fb16a 100644 --- a/Inc/stm32f4xx_hal_conf.h +++ b/Inc/stm32f4xx_hal_conf.h @@ -38,7 +38,7 @@ #define HAL_MODULE_ENABLED /* #define HAL_CRYP_MODULE_ENABLED */ -/* #define HAL_ADC_MODULE_ENABLED */ +#define HAL_ADC_MODULE_ENABLED /* #define HAL_CAN_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CAN_LEGACY_MODULE_ENABLED */ diff --git a/MDK-ARM/STM32F407-Demo.uvprojx b/MDK-ARM/STM32F407-Demo.uvprojx index 0568effb..83898078 100644 --- a/MDK-ARM/STM32F407-Demo.uvprojx +++ b/MDK-ARM/STM32F407-Demo.uvprojx @@ -1,10 +1,7 @@ - - - + + 2.1 -
### uVision Project, (C) Keil Software
- STM32F407-Demo @@ -19,28 +16,28 @@ Keil.STM32F4xx_DFP.3.1.1 https://www.keil.com/pack/ IRAM(0x20000000-0x2001BFFF) IRAM2(0x2001C000-0x2001FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) FPU2 CPUTYPE("Cortex-M4") TZ - - - + + + 0 - - - - - - - - - - + + + + + + + + + + $$Device:STM32F407ZGTx$CMSIS\SVD\STM32F407.svd 0 0 - - - - - + + + + + 0 0 @@ -55,15 +52,15 @@ 1 1 1 - + 1 0 0 0 0 - - + + 0 0 0 @@ -72,8 +69,8 @@ 0 0 - - + + 0 0 0 @@ -82,15 +79,15 @@ 0 1 - - + + 0 0 0 0 1 - + 0 @@ -104,8 +101,8 @@ 0 0 3 - - + + 0 @@ -139,10 +136,10 @@ 1 BIN\UL2CM3.DLL "" () - - - - + + + + 0 @@ -175,7 +172,7 @@ 0 0 "Cortex-M4" - + 0 0 0 @@ -310,7 +307,7 @@ 0x0 - + 1 @@ -339,7 +336,7 @@ --diag_suppress=1,68,111,188,191,546,1293 USE_HAL_DRIVER,STM32F407xx,NDEBUG - + ../Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP;../Drivers/BSP/CH395F;../Drivers/BSP/GD5F2GQ5UE;../Drivers/BSP/TPAFE5160;../Drivers/BSP/SD2506;../Drivers/BSP/RS485;../Drivers/BSP/NET;../Drivers/BSP/NET/lftpd;../Drivers/BSP/NETCFG;../App;../App/app;../App/cfg;../App/fs;../App/log;../App/sync;../App/task;../App/util;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../Lib/dhara;../Lib/FatFs;../test/board;../Lib/lvgl;../Drivers/BSP/UI;../Lib @@ -355,9 +352,9 @@ 0 1 - - - + + + ../Drivers/CMSIS/Include @@ -368,15 +365,15 @@ 0 1 1 - - - + + + STM32F407-Demo\STM32F407-Demo.sct - - - - - + + + + + @@ -421,8 +418,6 @@ 2 2 11 - - 1 @@ -450,16 +445,70 @@ 2 2 2 - - - - - - + + adc.c + 1 + ../Src/adc.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + + + + dma.c 1 @@ -477,8 +526,6 @@ 2 2 11 - - 1 @@ -506,12 +553,6 @@ 2 2 2 - - - - - - @@ -533,8 +574,6 @@ 2 2 11 - - 1 @@ -562,12 +601,6 @@ 2 2 2 - - - - - - @@ -589,8 +622,6 @@ 2 2 11 - - 1 @@ -618,12 +649,6 @@ 2 2 2 - - - - - - @@ -645,8 +670,6 @@ 2 2 11 - - 1 @@ -674,12 +697,6 @@ 2 2 2 - - - - - - @@ -701,8 +718,6 @@ 2 2 11 - - 1 @@ -730,12 +745,6 @@ 2 2 2 - - - - - - @@ -767,8 +776,6 @@ 2 2 11 - - 1 @@ -796,12 +803,6 @@ 2 2 2 - - - - - - @@ -893,8 +894,6 @@ 2 2 11 - - 1 @@ -922,12 +921,6 @@ 2 2 2 - - - - - - @@ -949,8 +942,6 @@ 2 2 11 - - 1 @@ -978,16 +969,130 @@ 2 2 2 - - - - - - + + stm32f4xx_hal_adc.c + 1 + ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + + + + + + stm32f4xx_hal_adc_ex.c + 1 + ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + + + + stm32f4xx_hal_rcc.c 1 @@ -1070,8 +1175,6 @@ 2 2 11 - - 1 @@ -1099,12 +1202,6 @@ 2 2 2 - - - - - - @@ -1126,8 +1223,6 @@ 2 2 11 - - 1 @@ -1155,12 +1250,6 @@ 2 2 2 - - - - - - @@ -1182,8 +1271,6 @@ 2 2 11 - - 1 @@ -1211,12 +1298,6 @@ 2 2 2 - - - - - - @@ -1238,8 +1319,6 @@ 2 2 11 - - 1 @@ -1267,12 +1346,6 @@ 2 2 2 - - - - - - @@ -1294,8 +1367,6 @@ 2 2 11 - - 1 @@ -1323,12 +1394,6 @@ 2 2 2 - - - - - - @@ -1435,8 +1500,6 @@ 2 2 11 - - 1 @@ -1464,12 +1527,6 @@ 2 2 2 - - - - - - 2 @@ -1482,12 +1539,6 @@ 2 2 1 - - - - - - @@ -1509,8 +1560,6 @@ 2 2 11 - - 1 @@ -1538,12 +1587,6 @@ 2 2 2 - - - - - - @@ -1565,8 +1608,6 @@ 2 2 11 - - 1 @@ -1594,12 +1635,6 @@ 2 2 2 - - - - - - @@ -1621,8 +1656,6 @@ 2 2 11 - - 1 @@ -1650,12 +1683,6 @@ 2 2 2 - - - - - - @@ -1677,8 +1704,6 @@ 2 2 11 - - 1 @@ -1706,12 +1731,6 @@ 2 2 2 - - - - - - @@ -1733,8 +1752,6 @@ 2 2 11 - - 1 @@ -1762,12 +1779,6 @@ 2 2 2 - - - - - - @@ -1789,8 +1800,6 @@ 2 2 11 - - 1 @@ -1818,12 +1827,6 @@ 2 2 2 - - - - - - @@ -1845,8 +1848,6 @@ 2 2 11 - - 1 @@ -1874,12 +1875,6 @@ 2 2 2 - - - - - - @@ -1901,8 +1896,6 @@ 2 2 11 - - 1 @@ -1930,12 +1923,6 @@ 2 2 2 - - - - - - @@ -1957,8 +1944,6 @@ 2 2 11 - - 1 @@ -1986,12 +1971,6 @@ 2 2 2 - - - - - - @@ -2013,8 +1992,6 @@ 2 2 11 - - 1 @@ -2042,12 +2019,6 @@ 2 2 2 - - - - - - @@ -2069,8 +2040,8 @@ 2 2 11 - - + + 1 @@ -2100,9 +2071,9 @@ 2 --diag_suppress=177 - - - + + + @@ -2117,10 +2088,10 @@ 2 1 - - - - + + + + @@ -2208,8 +2179,8 @@ 0 0 3 - - + + 0 @@ -2238,10 +2209,10 @@ 2 2 - - - - + + + + @@ -2256,10 +2227,10 @@ 2 0 - - - - + + + + @@ -3368,20 +3339,18 @@ - - + - + - + - + - @@ -3390,5 +3359,4 @@ -
diff --git a/STM32F407-Demo.ioc b/STM32F407-Demo.ioc index 4b2915fc..40d02f54 100644 --- a/STM32F407-Demo.ioc +++ b/STM32F407-Demo.ioc @@ -1,32 +1,26 @@ #MicroXplorer Configuration settings - do not modify -ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_0 -ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_1 -ADC1.Channel-2\#ChannelRegularConversion=ADC_CHANNEL_2 -ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_3 -ADC1.Channel-4\#ChannelRegularConversion=ADC_CHANNEL_4 -ADC1.Channel-5\#ChannelRegularConversion=ADC_CHANNEL_5 -ADC1.Channel-6\#ChannelRegularConversion=ADC_CHANNEL_6 -ADC1.Channel-7\#ChannelRegularConversion=ADC_CHANNEL_7 -ADC1.Channel-8\#ChannelRegularConversion=ADC_CHANNEL_14 -ADC1.ContinuousConvMode=DISABLE -ADC1.DataAlign=ADC_DATAALIGN_RIGHT -ADC1.DiscontinuousConvMode=DISABLE -ADC1.DMAContinuousRequests=DISABLE -ADC1.EOCSelection=ADC_EOC_SINGLE_CONV -ADC1.ExternalTrigConv=ADC_SOFTWARE_START -ADC1.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE -ADC1.IPParameters=ScanConvMode,ContinuousConvMode,DiscontinuousConvMode,DMAContinuousRequests,EOCSelection,DataAlign,ExternalTrigConv,ExternalTrigConvEdge,Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,Rank-2\#ChannelRegularConversion,Channel-2\#ChannelRegularConversion,SamplingTime-2\#ChannelRegularConversion,Rank-3\#ChannelRegularConversion,Channel-3\#ChannelRegularConversion,SamplingTime-3\#ChannelRegularConversion,Rank-4\#ChannelRegularConversion,Channel-4\#ChannelRegularConversion,SamplingTime-4\#ChannelRegularConversion,Rank-5\#ChannelRegularConversion,Channel-5\#ChannelRegularConversion,SamplingTime-5\#ChannelRegularConversion,Rank-6\#ChannelRegularConversion,Channel-6\#ChannelRegularConversion,SamplingTime-6\#ChannelRegularConversion,Rank-7\#ChannelRegularConversion,Channel-7\#ChannelRegularConversion,SamplingTime-7\#ChannelRegularConversion,Rank-8\#ChannelRegularConversion,Channel-8\#ChannelRegularConversion,SamplingTime-8\#ChannelRegularConversion,NbrOfConversionFlag,master -ADC1.NbrOfConversionFlag=9 -ADC1.Rank-0\#ChannelRegularConversion=1 -ADC1.Rank-1\#ChannelRegularConversion=2 -ADC1.Rank-2\#ChannelRegularConversion=3 -ADC1.Rank-3\#ChannelRegularConversion=4 -ADC1.Rank-4\#ChannelRegularConversion=5 -ADC1.Rank-5\#ChannelRegularConversion=6 -ADC1.Rank-6\#ChannelRegularConversion=7 -ADC1.Rank-7\#ChannelRegularConversion=8 -ADC1.Rank-8\#ChannelRegularConversion=9 -ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES +ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_0 +ADC1.Channel-2\#ChannelRegularConversion=ADC_CHANNEL_1 +ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_2 +ADC1.Channel-4\#ChannelRegularConversion=ADC_CHANNEL_3 +ADC1.Channel-5\#ChannelRegularConversion=ADC_CHANNEL_4 +ADC1.Channel-6\#ChannelRegularConversion=ADC_CHANNEL_5 +ADC1.Channel-7\#ChannelRegularConversion=ADC_CHANNEL_6 +ADC1.Channel-8\#ChannelRegularConversion=ADC_CHANNEL_7 +ADC1.Channel-9\#ChannelRegularConversion=ADC_CHANNEL_14 +ADC1.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4 +ADC1.IPParameters=Rank-1\#ChannelRegularConversion,master,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,NbrOfConversionFlag,ScanConvMode,Rank-2\#ChannelRegularConversion,Channel-2\#ChannelRegularConversion,SamplingTime-2\#ChannelRegularConversion,Rank-3\#ChannelRegularConversion,Channel-3\#ChannelRegularConversion,SamplingTime-3\#ChannelRegularConversion,Rank-4\#ChannelRegularConversion,Channel-4\#ChannelRegularConversion,SamplingTime-4\#ChannelRegularConversion,Rank-5\#ChannelRegularConversion,Channel-5\#ChannelRegularConversion,SamplingTime-5\#ChannelRegularConversion,Rank-6\#ChannelRegularConversion,Channel-6\#ChannelRegularConversion,SamplingTime-6\#ChannelRegularConversion,Rank-7\#ChannelRegularConversion,Channel-7\#ChannelRegularConversion,SamplingTime-7\#ChannelRegularConversion,Rank-8\#ChannelRegularConversion,Channel-8\#ChannelRegularConversion,SamplingTime-8\#ChannelRegularConversion,Rank-9\#ChannelRegularConversion,Channel-9\#ChannelRegularConversion,SamplingTime-9\#ChannelRegularConversion,NbrOfConversion,ClockPrescaler +ADC1.NbrOfConversion=9 +ADC1.NbrOfConversionFlag=1 +ADC1.Rank-1\#ChannelRegularConversion=1 +ADC1.Rank-2\#ChannelRegularConversion=2 +ADC1.Rank-3\#ChannelRegularConversion=3 +ADC1.Rank-4\#ChannelRegularConversion=4 +ADC1.Rank-5\#ChannelRegularConversion=5 +ADC1.Rank-6\#ChannelRegularConversion=6 +ADC1.Rank-7\#ChannelRegularConversion=7 +ADC1.Rank-8\#ChannelRegularConversion=8 +ADC1.Rank-9\#ChannelRegularConversion=9 ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES ADC1.SamplingTime-2\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES ADC1.SamplingTime-3\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES @@ -35,6 +29,7 @@ ADC1.SamplingTime-5\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES ADC1.SamplingTime-6\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES ADC1.SamplingTime-7\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES ADC1.SamplingTime-8\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES +ADC1.SamplingTime-9\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES ADC1.ScanConvMode=ENABLE ADC1.master=1 CAD.formats=[] @@ -109,11 +104,13 @@ Dma.USART1_TX.0.Priority=DMA_PRIORITY_LOW Dma.USART1_TX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode FREERTOS.Events01=sys_evt,Dynamic,NULL FREERTOS.FootprintOK=true -FREERTOS.IPParameters=Tasks01,configENABLE_FPU,FootprintOK,configTOTAL_HEAP_SIZE,Queues01,Events01 +FREERTOS.IPParameters=Tasks01,configENABLE_FPU,FootprintOK,configTOTAL_HEAP_SIZE,Queues01,Events01,configCHECK_FOR_STACK_OVERFLOW,configUSE_MALLOC_FAILED_HOOK FREERTOS.Queues01=netMsgQueue,8,net_msg_t,0,Dynamic,NULL,NULL FREERTOS.Tasks01=defaultTask,24,1024,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;netTask,24,960,StartNetTask,Default,NULL,Dynamic,NULL,NULL;ftpTask,24,1024,StartFtpTask,As weak,NULL,Dynamic,NULL,NULL;testTask,16,2048,start_test_task,As weak,NULL,Dynamic,NULL,NULL;uiTask,16,4096,StartUiTask,Default,NULL,Dynamic,NULL,NULL +FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2 FREERTOS.configENABLE_FPU=1 FREERTOS.configTOTAL_HEAP_SIZE=49152 +FREERTOS.configUSE_MALLOC_FAILED_HOOK=1 File.Version=6 GPIO.groupedBy=Group By Peripherals IWDG.IPParameters=Prescaler,Reload @@ -122,84 +119,94 @@ IWDG.Reload=1249 KeepUserPlacement=false Mcu.CPN=STM32F407ZGT6 Mcu.Family=STM32F4 -Mcu.IP0=DMA -Mcu.IP1=FREERTOS -Mcu.IP10=UART5 -Mcu.IP11=USART1 -Mcu.IP12=USART2 -Mcu.IP13=USART3 -Mcu.IP2=I2C1 -Mcu.IP3=IWDG -Mcu.IP4=NVIC -Mcu.IP5=RCC -Mcu.IP6=SPI1 -Mcu.IP7=SPI2 -Mcu.IP8=SYS -Mcu.IP9=UART4 -Mcu.IPNb=14 +Mcu.IP0=ADC1 +Mcu.IP1=DMA +Mcu.IP10=UART4 +Mcu.IP11=UART5 +Mcu.IP12=USART1 +Mcu.IP13=USART2 +Mcu.IP14=USART3 +Mcu.IP2=FREERTOS +Mcu.IP3=I2C1 +Mcu.IP4=IWDG +Mcu.IP5=NVIC +Mcu.IP6=RCC +Mcu.IP7=SPI1 +Mcu.IP8=SPI2 +Mcu.IP9=SYS +Mcu.IPNb=15 Mcu.Name=STM32F407Z(E-G)Tx Mcu.Package=LQFP144 Mcu.Pin0=PE5 Mcu.Pin1=PH0-OSC_IN -Mcu.Pin10=PG1 -Mcu.Pin11=PB10 -Mcu.Pin12=PB11 -Mcu.Pin13=PB12 -Mcu.Pin14=PB13 -Mcu.Pin15=PB14 -Mcu.Pin16=PB15 -Mcu.Pin17=PG2 -Mcu.Pin18=PG3 -Mcu.Pin19=PG4 +Mcu.Pin10=PA7 +Mcu.Pin11=PC4 +Mcu.Pin12=PC5 +Mcu.Pin13=PB0 +Mcu.Pin14=PB1 +Mcu.Pin15=PB2 +Mcu.Pin16=PF11 +Mcu.Pin17=PF12 +Mcu.Pin18=PG0 +Mcu.Pin19=PG1 Mcu.Pin2=PH1-OSC_OUT -Mcu.Pin20=PG5 -Mcu.Pin21=PG6 -Mcu.Pin22=PG7 -Mcu.Pin23=PG8 -Mcu.Pin24=PC6 -Mcu.Pin25=PC7 -Mcu.Pin26=PC8 -Mcu.Pin27=PC9 -Mcu.Pin28=PA8 -Mcu.Pin29=PA9 -Mcu.Pin3=PC5 -Mcu.Pin30=PA10 -Mcu.Pin31=PA11 -Mcu.Pin32=PA12 -Mcu.Pin33=PA13 -Mcu.Pin34=PA14 -Mcu.Pin35=PA15 -Mcu.Pin36=PC10 -Mcu.Pin37=PC11 -Mcu.Pin38=PC12 -Mcu.Pin39=PD2 -Mcu.Pin4=PB0 -Mcu.Pin40=PD5 -Mcu.Pin41=PD6 -Mcu.Pin42=PG9 -Mcu.Pin43=PG10 -Mcu.Pin44=PG11 -Mcu.Pin45=PG12 -Mcu.Pin46=PG13 -Mcu.Pin47=PG14 -Mcu.Pin48=PG15 -Mcu.Pin49=PB3 -Mcu.Pin5=PB1 -Mcu.Pin50=PB4 -Mcu.Pin51=PB5 -Mcu.Pin52=PB6 -Mcu.Pin53=PB7 -Mcu.Pin54=PB8 -Mcu.Pin55=PE0 -Mcu.Pin56=PE1 -Mcu.Pin57=VP_FREERTOS_VS_CMSIS_V2 -Mcu.Pin58=VP_IWDG_VS_IWDG -Mcu.Pin59=VP_SYS_VS_tim7 -Mcu.Pin6=PB2 -Mcu.Pin7=PF11 -Mcu.Pin8=PF12 -Mcu.Pin9=PG0 -Mcu.PinsNb=60 +Mcu.Pin20=PB10 +Mcu.Pin21=PB11 +Mcu.Pin22=PB12 +Mcu.Pin23=PB13 +Mcu.Pin24=PB14 +Mcu.Pin25=PB15 +Mcu.Pin26=PG2 +Mcu.Pin27=PG3 +Mcu.Pin28=PG4 +Mcu.Pin29=PG5 +Mcu.Pin3=PA0-WKUP +Mcu.Pin30=PG6 +Mcu.Pin31=PG7 +Mcu.Pin32=PG8 +Mcu.Pin33=PC6 +Mcu.Pin34=PC7 +Mcu.Pin35=PC8 +Mcu.Pin36=PC9 +Mcu.Pin37=PA8 +Mcu.Pin38=PA9 +Mcu.Pin39=PA10 +Mcu.Pin4=PA1 +Mcu.Pin40=PA11 +Mcu.Pin41=PA12 +Mcu.Pin42=PA13 +Mcu.Pin43=PA14 +Mcu.Pin44=PA15 +Mcu.Pin45=PC10 +Mcu.Pin46=PC11 +Mcu.Pin47=PC12 +Mcu.Pin48=PD2 +Mcu.Pin49=PD5 +Mcu.Pin5=PA2 +Mcu.Pin50=PD6 +Mcu.Pin51=PG9 +Mcu.Pin52=PG10 +Mcu.Pin53=PG11 +Mcu.Pin54=PG12 +Mcu.Pin55=PG13 +Mcu.Pin56=PG14 +Mcu.Pin57=PG15 +Mcu.Pin58=PB3 +Mcu.Pin59=PB4 +Mcu.Pin6=PA3 +Mcu.Pin60=PB5 +Mcu.Pin61=PB6 +Mcu.Pin62=PB7 +Mcu.Pin63=PB8 +Mcu.Pin64=PE0 +Mcu.Pin65=PE1 +Mcu.Pin66=VP_FREERTOS_VS_CMSIS_V2 +Mcu.Pin67=VP_IWDG_VS_IWDG +Mcu.Pin68=VP_SYS_VS_tim7 +Mcu.Pin7=PA4 +Mcu.Pin8=PA5 +Mcu.Pin9=PA6 +Mcu.PinsNb=69 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F407ZGTx @@ -236,38 +243,14 @@ NVIC.USART1_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true NVIC.USART2_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true NVIC.USART3_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false -PA0.GPIOParameters=GPIO_Label -PA0.GPIO_Label=ADC9_RES -PA0.Locked=true -PA0.Signal=ADC1_IN0 +PA0-WKUP.GPIOParameters=GPIO_Label +PA0-WKUP.GPIO_Label=ADC9_RES +PA0-WKUP.Locked=true +PA0-WKUP.Signal=ADCx_IN0 PA1.GPIOParameters=GPIO_Label PA1.GPIO_Label=ADC10_IC PA1.Locked=true -PA1.Signal=ADC1_IN1 -PA2.GPIOParameters=GPIO_Label -PA2.GPIO_Label=ADC11_IN -PA2.Locked=true -PA2.Signal=ADC1_IN2 -PA3.GPIOParameters=GPIO_Label -PA3.GPIO_Label=ADC12_UC -PA3.Locked=true -PA3.Signal=ADC1_IN3 -PA4.GPIOParameters=GPIO_Label -PA4.GPIO_Label=ADC13_RES -PA4.Locked=true -PA4.Signal=ADC1_IN4 -PA5.GPIOParameters=GPIO_Label -PA5.GPIO_Label=ADC14_TEMP -PA5.Locked=true -PA5.Signal=ADC1_IN5 -PA6.GPIOParameters=GPIO_Label -PA6.GPIO_Label=ADC15_IB -PA6.Locked=true -PA6.Signal=ADC1_IN6 -PA7.GPIOParameters=GPIO_Label -PA7.GPIO_Label=ADC16_RES -PA7.Locked=true -PA7.Signal=ADC1_IN7 +PA1.Signal=ADCx_IN1 PA10.GPIOParameters=GPIO_ModeDefaultPP,GPIO_Speed,GPIO_PuPd PA10.GPIO_ModeDefaultPP=GPIO_MODE_AF_PP PA10.GPIO_PuPd=GPIO_NOPULL @@ -291,6 +274,30 @@ PA15.GPIOParameters=GPIO_Label PA15.GPIO_Label=ST_DIR4 PA15.Locked=true PA15.Signal=GPIO_Output +PA2.GPIOParameters=GPIO_Label +PA2.GPIO_Label=ADC11_IN +PA2.Locked=true +PA2.Signal=ADCx_IN2 +PA3.GPIOParameters=GPIO_Label +PA3.GPIO_Label=ADC12_UC +PA3.Locked=true +PA3.Signal=ADCx_IN3 +PA4.GPIOParameters=GPIO_Label +PA4.GPIO_Label=ADC13_RES +PA4.Locked=true +PA4.Signal=ADCx_IN4 +PA5.GPIOParameters=GPIO_Label +PA5.GPIO_Label=ADC14_TEMP +PA5.Locked=true +PA5.Signal=ADCx_IN5 +PA6.GPIOParameters=GPIO_Label +PA6.GPIO_Label=ADC15_IB +PA6.Locked=true +PA6.Signal=ADCx_IN6 +PA7.GPIOParameters=GPIO_Label +PA7.GPIO_Label=ADC16_RES +PA7.Locked=true +PA7.Signal=ADCx_IN7 PA8.GPIOParameters=GPIO_Speed,GPIO_Label PA8.GPIO_Label=TP_OS2 PA8.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH @@ -408,7 +415,7 @@ PC12.Signal=UART5_TX PC4.GPIOParameters=GPIO_Label PC4.GPIO_Label=ADC17_UB PC4.Locked=true -PC4.Signal=ADC1_IN14 +PC4.Signal=ADCx_IN14 PC5.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label PC5.GPIO_Label=LED1 PC5.GPIO_PuPd=GPIO_PULLUP @@ -594,7 +601,7 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= 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_USART1_UART_Init-USART1-false-HAL-true,5-MX_SPI2_Init-SPI2-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_I2C1_Init-I2C1-false-HAL-true,8-MX_UART4_Init-UART4-false-HAL-true,9-MX_UART5_Init-UART5-false-HAL-true,10-MX_USART2_UART_Init-USART2-false-HAL-true,11-MX_USART3_UART_Init-USART3-false-HAL-true,12-MX_IWDG_Init-IWDG-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_USART1_UART_Init-USART1-false-HAL-true,5-MX_SPI2_Init-SPI2-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_I2C1_Init-I2C1-false-HAL-true,8-MX_UART4_Init-UART4-false-HAL-true,9-MX_UART5_Init-UART5-false-HAL-true,10-MX_USART2_UART_Init-USART2-false-HAL-true,11-MX_USART3_UART_Init-USART3-false-HAL-true,12-MX_IWDG_Init-IWDG-false-HAL-true,13-MX_ADC1_Init-ADC1-false-HAL-true RCC.48MHZClocksFreq_Value=84000000 RCC.AHBFreq_Value=168000000 RCC.APB1CLKDivider=RCC_HCLK_DIV4 @@ -628,6 +635,24 @@ RCC.VCOI2SOutputFreq_Value=384000000 RCC.VCOInputFreq_Value=2000000 RCC.VCOOutputFreq_Value=336000000 RCC.VcooutputI2S=192000000 +SH.ADCx_IN0.0=ADC1_IN0,IN0 +SH.ADCx_IN0.ConfNb=1 +SH.ADCx_IN1.0=ADC1_IN1,IN1 +SH.ADCx_IN1.ConfNb=1 +SH.ADCx_IN14.0=ADC1_IN14,IN14 +SH.ADCx_IN14.ConfNb=1 +SH.ADCx_IN2.0=ADC1_IN2,IN2 +SH.ADCx_IN2.ConfNb=1 +SH.ADCx_IN3.0=ADC1_IN3,IN3 +SH.ADCx_IN3.ConfNb=1 +SH.ADCx_IN4.0=ADC1_IN4,IN4 +SH.ADCx_IN4.ConfNb=1 +SH.ADCx_IN5.0=ADC1_IN5,IN5 +SH.ADCx_IN5.ConfNb=1 +SH.ADCx_IN6.0=ADC1_IN6,IN6 +SH.ADCx_IN6.ConfNb=1 +SH.ADCx_IN7.0=ADC1_IN7,IN7 +SH.ADCx_IN7.ConfNb=1 SH.GPXTI7.0=GPIO_EXTI7 SH.GPXTI7.ConfNb=1 SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2 diff --git a/Src/adc.c b/Src/adc.c new file mode 100644 index 00000000..fb0a802b --- /dev/null +++ b/Src/adc.c @@ -0,0 +1,226 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.c + * @brief This file provides code for the configuration + * of the ADC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 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. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "adc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +ADC_HandleTypeDef hadc1; + +/* ADC1 init function */ +void MX_ADC1_Init(void) +{ + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + ADC_ChannelConfTypeDef sConfig = {0}; + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + + /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) + */ + hadc1.Instance = ADC1; + hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; + hadc1.Init.Resolution = ADC_RESOLUTION_12B; + hadc1.Init.ScanConvMode = ENABLE; + hadc1.Init.ContinuousConvMode = DISABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 9; + hadc1.Init.DMAContinuousRequests = DISABLE; + hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + if (HAL_ADC_Init(&hadc1) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_0; + sConfig.Rank = 1; + sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_1; + sConfig.Rank = 2; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_2; + sConfig.Rank = 3; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_3; + sConfig.Rank = 4; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_4; + sConfig.Rank = 5; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_5; + sConfig.Rank = 6; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_6; + sConfig.Rank = 7; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_7; + sConfig.Rank = 8; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_14; + sConfig.Rank = 9; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ + +} + +void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(adcHandle->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspInit 0 */ + + /* USER CODE END ADC1_MspInit 0 */ + /* ADC1 clock enable */ + __HAL_RCC_ADC1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + /**ADC1 GPIO Configuration + PA0-WKUP ------> ADC1_IN0 + PA1 ------> ADC1_IN1 + PA2 ------> ADC1_IN2 + PA3 ------> ADC1_IN3 + PA4 ------> ADC1_IN4 + PA5 ------> ADC1_IN5 + PA6 ------> ADC1_IN6 + PA7 ------> ADC1_IN7 + PC4 ------> ADC1_IN14 + */ + GPIO_InitStruct.Pin = ADC9_RES_Pin|ADC10_IC_Pin|ADC11_IN_Pin|ADC12_UC_Pin + |ADC13_RES_Pin|ADC14_TEMP_Pin|ADC15_IB_Pin|ADC16_RES_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = ADC17_UB_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(ADC17_UB_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN ADC1_MspInit 1 */ + + /* USER CODE END ADC1_MspInit 1 */ + } +} + +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) +{ + + if(adcHandle->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspDeInit 0 */ + + /* USER CODE END ADC1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ADC1_CLK_DISABLE(); + + /**ADC1 GPIO Configuration + PA0-WKUP ------> ADC1_IN0 + PA1 ------> ADC1_IN1 + PA2 ------> ADC1_IN2 + PA3 ------> ADC1_IN3 + PA4 ------> ADC1_IN4 + PA5 ------> ADC1_IN5 + PA6 ------> ADC1_IN6 + PA7 ------> ADC1_IN7 + PC4 ------> ADC1_IN14 + */ + HAL_GPIO_DeInit(GPIOA, ADC9_RES_Pin|ADC10_IC_Pin|ADC11_IN_Pin|ADC12_UC_Pin + |ADC13_RES_Pin|ADC14_TEMP_Pin|ADC15_IB_Pin|ADC16_RES_Pin); + + HAL_GPIO_DeInit(ADC17_UB_GPIO_Port, ADC17_UB_Pin); + + /* USER CODE BEGIN ADC1_MspDeInit 1 */ + + /* USER CODE END ADC1_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Src/freertos.c b/Src/freertos.c index 252c150e..a3a09278 100644 --- a/Src/freertos.c +++ b/Src/freertos.c @@ -47,7 +47,31 @@ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ +/* + * 名称指针合法性校验(栈溢出/越界可能已破坏 TCB,指针不可信): + * 只接受落在 Flash / 主 SRAM / CCM 映射范围内的指针;不校验就直接交给 UART, + * 钩子自身也会以同样方式崩(2026-09-24 实测 HardFault:BFAR=0x10010000 恰为 + * CCM 末尾+1,PC 落在 HAL_UART_Transmit 的缓冲读取处)。 + * ⚠ 本辅助函数须定义在钩子**之前**:两个钩子本体已迁入 CubeMX 生成的 + * `USER CODE BEGIN 4 / 5` 区(位置在 `MX_FREERTOS_Init` 原型之后,比 + * `Application` 区靠前),故 helper 一并搬到此标准保护位(L2)。 + */ +static int hook_ptr_ok(const void *p) +{ + uint32_t a = (uint32_t)p; + uint32_t win = 32u; /* 将要读取的最大字节数(任务名 ≤ 32) */ + if ((a >= 0x08000000u) && (a <= (0x08100000u - win))) { + return 1; /* Flash(RO 区) */ + } + if ((a >= 0x20000000u) && (a <= (0x20020000u - win))) { + return 1; /* SRAM1 + SRAM2 */ + } + if ((a >= 0x10000000u) && (a <= (0x10010000u - win))) { + return 1; /* CCM(FreeRTOS 堆:TCB/栈所在) */ + } + return 0; +} /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ @@ -57,6 +81,29 @@ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN Variables */ +/* + * ===== 任务栈核算依据(受保护记录,勿删本块)===== + * ⚠ 栈**值**的事实源是 `.ioc` 的 `FREERTOS.Tasks01`——改栈改那里,CubeMX 会生成到下面各 + * `.stack_size`。本块只记录"为什么是这个值":原先这些注释贴在各自 `.stack_size` 旁边, + * 但那里位于生成区之外,2026-09-29 与 2026-10-09 共四次重生成里丢了三次,故集中搬进 + * `USER CODE BEGIN Variables` 这个标准保护位(模板真实生成、名字从未变过 → 重生成不丢)。 + * 数据来源:`scripts/stack_report.py`(Keil 静态调用图最坏链)+ 串口 `[STACK]` 运行时水位; + * 底线规则:余量 ≥ max(1024 B ISR, 30%)。完整核算见 docs/内存管理/RAM使用分析与优化方案.md, + * 全表(含 ftpTask 1024 / uiTask 4096 的现值)见 AGENTS.md 任务表。 + * + * defaultTask 1024 words:扛 mount+mkfs+FAT 探针+cfg 加载+syslog 写+配置引擎 + * (全深层 FatFS I/O)。原 512,2KB 实测峰值溢出——开启 + * configCHECK_FOR_STACK_OVERFLOW=2 后被钩子抓到(2026-09-21)。 + * netTask 960 words:静态最坏链 2664 B(发送停滞→断连→重监听→SPI 故障→日志尾, + * 真实直调链,日志主导:链上 5 帧各含 192 B __con_line + 尾部 ~696 B);3840 B + * 配置余量 1176 B(30.6%),过 stack_report 规则。运行时水位仅 ~1.1 KB(错误尾未 + * 触发,不可作依据)。曾试 net_drain_chip_rx scratch 静态化,实测仅省 16 B 栈 + * (ARMCC 已叠放不重叠局部量)反增 256 B BSS,已回退——见 net_socket.c 注释。 + * testTask 2048 words:存储套件 deep call chain + 局部缓冲,原 1024(4 KB)实测溢出 + * (2026-09-20)。仅启用测试套件时创建。 + * timeSyncTask 512 words:本区下方手工定义(不在 `.ioc` 的 Tasks01 里 → 重生成会丢, + * 靠审计 WARN 提示),只做读 RTC + 置就绪事件位,无深调用链。 + */ /* 存储测试变量(g_storage_stats / s_perf_buf)已迁至 test/board/storage_test_task.c */ osThreadId_t timeSyncTaskHandle; const osThreadAttr_t timeSyncTask_attributes = { @@ -69,10 +116,6 @@ const osThreadAttr_t timeSyncTask_attributes = { osThreadId_t defaultTaskHandle; const osThreadAttr_t defaultTask_attributes = { .name = "defaultTask", - /* 512→1024: 该任务扛 mount+mkfs+FAT探针+cfg加载+syslog写+配置引擎 - * (全深层 FatFS I/O),2KB 实测峰值溢出——开启 - * configCHECK_FOR_STACK_OVERFLOW=2 后被钩子抓到(2026-09-21)。 - * ⚠ 注释位于 .ioc 生成区之外,CubeMX 重生成会丢(值本身在 FREERTOS.Tasks01 里,不丢)。 */ .stack_size = 1024 * 4, .priority = (osPriority_t) osPriorityNormal, }; @@ -80,12 +123,6 @@ const osThreadAttr_t defaultTask_attributes = { osThreadId_t netTaskHandle; const osThreadAttr_t netTask_attributes = { .name = "netTask", - /* 1024→960: 静态最坏链 2664B(发送停滞→断连→重监听→SPI故障→日志尾,真实直调链, - * 日志主导:链上 5 帧各含 192B __con_line + 尾部 ~696B);3840B 配置余量 1176B - * (30.6%),过 stack_report 规则(≥max(1024B ISR, 30%))。运行时水位仅 ~1.1KB - * (错误尾未触发,不可作依据)。曾试 net_drain_chip_rx scratch 静态化,实测仅省 - * 16B 栈(ARMCC 已叠放不重叠局部量)反增 256B BSS,已回退——见 net_socket.c 注释。 - * ⚠ 注释位于 .ioc 生成区之外,CubeMX 重生成会丢(值本身在 FREERTOS.Tasks01 里,不丢)。 */ .stack_size = 960 * 4, .priority = (osPriority_t) osPriorityNormal, }; @@ -100,8 +137,6 @@ const osThreadAttr_t ftpTask_attributes = { osThreadId_t testTaskHandle; const osThreadAttr_t testTask_attributes = { .name = "testTask", - /* 1024→2048: 存储套件 deep call chain + 局部缓冲,4KB 实测溢出(2026-09-20)。 - * ⚠ 注释位于 .ioc 生成区之外,CubeMX 重生成会丢(值本身在 FREERTOS.Tasks01 里,不丢)。 */ .stack_size = 2048 * 4, .priority = (osPriority_t) osPriorityBelowNormal, }; @@ -136,6 +171,65 @@ void StartUiTask(void *argument); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ +/* Hook prototypes */ +void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName); +void vApplicationMallocFailedHook(void); + +/* USER CODE BEGIN 4 */ +/* + * 栈溢出钩子(configCHECK_FOR_STACK_OVERFLOW=2,2026-09-20 存储套件死机事故后加): + * 溢出 = 内核状态已不可信,禁止走 printf/内核对象/控制台锁,裸发固定文本后复位。 + * 2026-09-24 加固:任务名先经范围校验并拷入本地缓冲(不再把 TCB 指针交给 UART), + * 指针不可信时打印占位文本——避免"上报崩溃的代码自己再崩一次"。 + * ⚠ 落点说明(2026-10-09):整个函数放在 CubeMX 生成的 `USER CODE BEGIN 4` 区内。 + * 该区的存在由 `.ioc` 启用钩子(FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2)保证; + * 若实现留在 `Application` 区、又让 CubeMX 生成空桩,两处同名定义 = 编译错。 + * 签名与 CubeMX 生成的钩子原型一致(xTaskHandle → TaskHandle_t,即 void *)。 + */ +void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName) +{ + static const char msg_head[] = "\r\n[ERR] STACK OVERFLOW task="; + static const char msg_bad[] = "(name unavailable)"; + uint16_t len = 0u; + + (void)xTask; + dbg_console_write_raw(msg_head, (unsigned)(sizeof(msg_head) - 1u)); + + if ((pcTaskName != NULL) && (hook_ptr_ok(pcTaskName) != 0)) { + while ((len < 32u) && (pcTaskName[len] != '\0')) { + len++; + } + } + if (len == 0u) { + dbg_console_write_raw(msg_bad, (unsigned)(sizeof(msg_bad) - 1u)); + } else { + char name[33]; /* 拷入本地缓冲:UART 永不接触 TCB 指针 */ + + memcpy(name, pcTaskName, (size_t)len); + name[len] = '\0'; + dbg_console_write_raw(name, (unsigned)len); + } + dbg_console_write_raw("\r\n", 2u); + HAL_Delay(200); + NVIC_SystemReset(); +} +/* USER CODE END 4 */ + +/* USER CODE BEGIN 5 */ +/* + * 堆分配失败钩子:只告警不复位(NULL 由各调用点自行处理并上报自检)。 + * 同样走裸 UART 有界发送——钩子可能在临界区内被调,printf/信号量不可用。 + * ⚠ 落点同上:整个函数在 CubeMX 生成的 `USER CODE BEGIN 5` 区内 + * (由 `.ioc` 的 FREERTOS.configUSE_MALLOC_FAILED_HOOK=1 保证该区存在)。 + */ +void vApplicationMallocFailedHook(void) +{ + static const char msg[] = "\r\n[ERR] MALLOC FAILED (heap exhausted)\r\n"; + + dbg_console_write_raw(msg, (unsigned)(sizeof(msg) - 1u)); +} +/* USER CODE END 5 */ + /** * @brief FreeRTOS initialization * @param None @@ -326,74 +420,6 @@ void StartUiTask(void *argument) /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ -/* - * 名称指针合法性校验(栈溢出/越界可能已破坏 TCB,指针不可信): - * 只接受落在 Flash / 主 SRAM / CCM 映射范围内的指针;不校验就直接交给 UART, - * 钩子自身也会以同样方式崩(2026-09-24 实测 HardFault:BFAR=0x10010000 恰为 - * CCM 末尾+1,PC 落在 HAL_UART_Transmit 的缓冲读取处)。 - */ -static int hook_ptr_ok(const void *p) -{ - uint32_t a = (uint32_t)p; - uint32_t win = 32u; /* 将要读取的最大字节数(任务名 ≤ 32) */ - - if ((a >= 0x08000000u) && (a <= (0x08100000u - win))) { - return 1; /* Flash(RO 区) */ - } - if ((a >= 0x20000000u) && (a <= (0x20020000u - win))) { - return 1; /* SRAM1 + SRAM2 */ - } - if ((a >= 0x10000000u) && (a <= (0x10010000u - win))) { - return 1; /* CCM(FreeRTOS 堆:TCB/栈所在) */ - } - return 0; -} - -/* - * 栈溢出钩子(configCHECK_FOR_STACK_OVERFLOW=2,2026-09-20 存储套件死机事故后加): - * 溢出 = 内核状态已不可信,禁止走 printf/内核对象/控制台锁,裸发固定文本后复位。 - * 2026-09-24 加固:任务名先经范围校验并拷入本地缓冲(不再把 TCB 指针交给 UART), - * 指针不可信时打印占位文本——避免"上报崩溃的代码自己再崩一次"。 - */ -void vApplicationStackOverflowHook(void *xTask, signed char *pcTaskName) -{ - static const char msg_head[] = "\r\n[ERR] STACK OVERFLOW task="; - static const char msg_bad[] = "(name unavailable)"; - uint16_t len = 0u; - - (void)xTask; - dbg_console_write_raw(msg_head, (unsigned)(sizeof(msg_head) - 1u)); - - if ((pcTaskName != NULL) && (hook_ptr_ok(pcTaskName) != 0)) { - while ((len < 32u) && (pcTaskName[len] != '\0')) { - len++; - } - } - if (len == 0u) { - dbg_console_write_raw(msg_bad, (unsigned)(sizeof(msg_bad) - 1u)); - } else { - char name[33]; /* 拷入本地缓冲:UART 永不接触 TCB 指针 */ - - memcpy(name, pcTaskName, (size_t)len); - name[len] = '\0'; - dbg_console_write_raw(name, (unsigned)len); - } - dbg_console_write_raw("\r\n", 2u); - HAL_Delay(200); - NVIC_SystemReset(); -} - -/* - * 堆分配失败钩子:只告警不复位(NULL 由各调用点自行处理并上报自检)。 - * 同样走裸 UART 有界发送——钩子可能在临界区内被调,printf/信号量不可用。 - */ -void vApplicationMallocFailedHook(void) -{ - static const char msg[] = "\r\n[ERR] MALLOC FAILED (heap exhausted)\r\n"; - - dbg_console_write_raw(msg, (unsigned)(sizeof(msg) - 1u)); -} - /* * 断言失败钩子(2026-09-29,配合 IWDG;见 Inc/FreeRTOSConfig.h 的 configASSERT)。 * 与栈溢出钩子同为"内核状态已不可信"路径:裸 UART 有界输出 + 主动复位, diff --git a/Src/gpio.c b/Src/gpio.c index 7eccb834..0f1f1ef5 100644 --- a/Src/gpio.c +++ b/Src/gpio.c @@ -47,11 +47,11 @@ void MX_GPIO_Init(void) /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /*Configure GPIO pin Output Level */ diff --git a/Src/main.c b/Src/main.c index 080254a2..7b82386d 100644 --- a/Src/main.c +++ b/Src/main.c @@ -19,6 +19,7 @@ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "cmsis_os.h" +#include "adc.h" #include "dma.h" #include "i2c.h" #include "iwdg.h" @@ -129,6 +130,7 @@ int main(void) MX_USART2_UART_Init(); MX_USART3_UART_Init(); MX_IWDG_Init(); + MX_ADC1_Init(); /* USER CODE BEGIN 2 */ HAL_Delay(100); diff --git a/docs/代码规范/pre-commit使用说明.md b/docs/代码规范/pre-commit使用说明.md index 3be4fd8a..a009a8e7 100644 --- a/docs/代码规范/pre-commit使用说明.md +++ b/docs/代码规范/pre-commit使用说明.md @@ -60,18 +60,29 @@ git commit |---|---| | **触发条件** | 文件任意行末尾含空格或 Tab | | **处理方式** | **自动修复**(直接改写文件,删除行尾空白) | -| **影响范围** | 所有被 git 跟踪的文件 | +| **影响范围** | 项目自有代码;**豁免 CubeMX / Keil 生成文件**(见下方"豁免清单") | | **典型报错** | `Trim Trailing Whitespace` → `Fixing path/to/file.c` | | **修复方式** | 无需手动修复,钩子已自动改写;重新 `git add` 即可 | > **注意**:首次对全库运行时,可能批量修改大量文件的行尾空格。这是正常行为,不会改变代码逻辑。 +> **豁免清单(2026-10-09 定,`trailing-whitespace` 与 `end-of-file-fixer` 共用同一份, +> 配置里以 YAML 锚点 `&cubemx-generated` 定义)**:`Src/*.{c,h}`、`Inc/*.{c,h}`、 +> `Drivers/CMSIS/`、`Drivers/STM32F4xx_HAL_Driver/`、`Middlewares/`、 +> `MDK-ARM/*.{uvprojx,uvoptx,sct,map}`、`.mxproject`、`*.ioc`。 +> 理由:这些文件的内容事实源是 `.ioc` 与工具链,每次重生成都按工具自己的风格写回 +> (行尾空白、文件末尾不带换行)——2026-10-09 实测每次重生成后 `Src/`/`Inc/` 下 10+ 个 +> 文件各被补 1 行末尾空行,纯属提交抖动。 +> ⚠ **只豁免"改写型"钩子**:`cppcheck` / 乱码 / `cubemx-survival` / `task-table` / +> `mem-numbers` 等**只读检查仍覆盖** `Src/`、`Inc/`(存活审计必须能看到这些文件)。 + ### 2.2 end-of-file-fixer — 文件尾换行 | 项 | 说明 | |---|---| | **触发条件** | 文件最后一行不是换行符(`\n`) | | **处理方式** | **自动修复**(在文件尾部追加换行) | +| **影响范围** | 项目自有代码;**豁免 CubeMX / Keil 生成文件**(同 2.1 豁免清单) | | **典型报错** | `Fix End of Files` → `Fixing path/to/file.c` | | **修复方式** | 无需手动修复,钩子已自动改写;重新 `git add` 即可 | diff --git a/docs/内存管理/RAM使用分析与优化方案.md b/docs/内存管理/RAM使用分析与优化方案.md index 15a83b9f..2624ee8a 100644 --- a/docs/内存管理/RAM使用分析与优化方案.md +++ b/docs/内存管理/RAM使用分析与优化方案.md @@ -36,10 +36,10 @@ | 区域 | 用量 | 容量 | 占比 | |---|---|---|---| -| ER_IROM1 | 266,632 B (260.38 KB) | 1,048,576 B (1024 KB) | 25.4% | -| RW_IRAM1 | 84,960 B (82.97 KB) | 131,072 B (128 KB) | 64.8% | +| ER_IROM1 | 267,740 B (261.46 KB) | 1,048,576 B (1024 KB) | 25.5% | +| RW_IRAM1 | 85,032 B (83.04 KB) | 131,072 B (128 KB) | 64.9% | | RW_CCM | 49,184 B (48.03 KB) | 65,280 B (64 KB) | 75.3% | -| **Flash (ROM 合计)** | **267,372 B (261.1 KB)** | 1,048,576 B (1024 KB) | **25.5%** | +| **Flash (ROM 合计)** | **268,480 B (262.2 KB)** | 1,048,576 B (1024 KB) | **25.6%** | 各区的容量与常量来源: diff --git a/docs/子系统设计/看门狗设计说明.md b/docs/子系统设计/看门狗设计说明.md index 45ac72c3..11f07379 100644 --- a/docs/子系统设计/看门狗设计说明.md +++ b/docs/子系统设计/看门狗设计说明.md @@ -818,6 +818,13 @@ external pin → "pin reset" (新增) > 真发生溢出/耗尽时才起作用,且 `HardFault_Handler` 被打回空死循环后 > **崩溃时连现场都打不出来**(只剩 IWDG 兜底复位,但归因信息全丢)。 > 故本次已把这三个宏搬进 `USER CODE BEGIN FREE_RTOS_CONFIG_HARDENING` 区。 +> +> **2026-10-09 第三次重生成(启用 ADC1):同一批定制再次全被抹,并暴露两个新事实** +> +> 1. **"自造区不可信"再次成立**:`FREE_RTOS_CONFIG_HARDENING` 连标记带内容**第二次**消失。已按 §10.2 改走 **L1**——`.ioc` 的 `FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2` / `FREERTOS.configUSE_MALLOC_FAILED_HOOK=1`(GUI 里就能设,见上),自造区删除,审计两项也从"校验自造区"升级为"校验 `.ioc`"。 +> 2. **新坑**:在 GUI 里启用这两个钩子后,CubeMX 会在 `Src/freertos.c` 生成 `USER CODE BEGIN 4 / 5` 区(默认内容是**空桩**),与 `Application` 区的真实实现**重复定义 → 编译错**(这是本项目唯一一次重生成后直接编译不过)。**最终落点:整个钩子函数写进 4 / 5 区**(见 §10.2),`Application` 区的旧实现搬走;配套 helper `hook_ptr_ok()` 须在钩子之前 → 放 `USER CODE BEGIN PD` 区。 +> 3. `Src/iwdg.c` 与 4 个 Fault Handler(L3)**第三次**被抹,锚点全部检出并按 HEAD 复原;`Src/freertos.c` 三处栈注释再次丢失(栈**值**未丢)→ 第四次重生成又丢一次,已**集中成一段"任务栈核算依据"放进 `USER CODE BEGIN Variables` 区**(L2,重生成不丢);各 `.stack_size` 旁不再留注释——那里在生成区之外,补了也留不住。 +> 4. 审计清单 18 → **21 项**(新增 `adc1-hal-enabled` 与钩子落点三项 `stack-overflow-hook-impl`(区 4) / `malloc-failed-hook-impl`(区 5) / `stack-overflow-hook-helper`(区 PD),两项加固检查升级为 `.ioc` 校验),现 21 通过 / 1 警告 / 0 失败。 > **每步改完必须 `@build` 0 错误 0 警告**(`AGENTS.md` 铁律)。 @@ -887,6 +894,8 @@ external pin → "pin reset" (新增) | 事件组 `sys_evt` | `FREERTOS.Events01` | ✅ | | FreeRTOS 堆大小 | `FREERTOS.configTOTAL_HEAP_SIZE=49152` | ✅ | | FPU 使能 | `FREERTOS.configENABLE_FPU=1` | ✅ | +| **栈溢出检测(模式 2)** | `FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2` | ✅ **2026-10-09 迁入 L1**(原先写在 `FreeRTOSConfig.h` 的自造区里,**两次重生成两次被抹**)。GUI 位置:FreeRTOS 页 → **Config parameters** 标签 → **Hook function related definitions** 组 | +| **堆分配失败钩子** | `FREERTOS.configUSE_MALLOC_FAILED_HOOK=1` | ✅ 同上(同一组,可选 0/1) | | IWDG 分频 / 重载 | `IWDG.IPParameters` + `IWDG.Prescaler` / `IWDG.Reload` | ✅ 本次新增,见 §2.2 | | 时钟树(含 LSI) | `RCC.*` | ✅ | | `KeepUserCode=true` | `ProjectManager.KeepUserCode` | ✅ **这个必须为 true**,否则 L2 整体失效 | @@ -895,12 +904,15 @@ external pin → "pin reset" (新增) | 定制 | 现状 | 建议 | |---|---|---| -| `configCHECK_FOR_STACK_OVERFLOW` | 在 `USER CODE BEGIN FREE_RTOS_CONFIG_HARDENING` 区(L2) | ⚠️ CubeMX 的 FreeRTOS 界面**没有**这一项的勾选框,只能靠 L2 + 审计。**保持现状** | -| `configUSE_MALLOC_FAILED_HOOK` | 同上 | 同上 | -| `configASSERT` 定义 | 在 `USER CODE BEGIN 1` 区(L2) | 同上。CubeMX 无对应界面项 | +| `configASSERT` 定义 | 在 `USER CODE BEGIN 1` 区(L2) | CubeMX 无对应界面项,保持 L2 + 审计 | | 4 个 Fault Handler 实体 | `stm32f4xx_it.c` 标记区**外**(L3) | ⚠️ CubeMX 为这些函数**不生成** `USER CODE` 区,无法 L2。见下方"存量清单" | | `fault_handler_enable()`(SHCSR 使能三位) | `Src/stm32f4xx_it.c` 的 `USER CODE BEGIN 1` 区(L2) | ❌ **CubeMX 无此配置项**(已查模板源码证实,见下) | +> ✅ **2026-10-09 更正**:本节原先写"CubeMX 的 FreeRTOS 界面**没有** `configCHECK_FOR_STACK_OVERFLOW` / `configUSE_MALLOC_FAILED_HOOK` 这一项的勾选框"——**判断有误,该项一直在 GUI 里**:FreeRTOS 页 → **Config parameters** 标签 → **Hook function related definitions** 组(DB 证据:`db/mcu/IP/FREERTOS-*-v*_Cube_Modes.xml` 里两个 `RefParameter`,可选值 0/1/2 与 0/1)。现已迁入 `.ioc`(见上一表),`Inc/FreeRTOSConfig.h` 里自造的 `FREE_RTOS_CONFIG_HARDENING` 区**随之删除**——它正是"自造区名不可信"的又一例(两次重生成两次被抹,2026-09-29 与 2026-10-09 各一次)。 +> +> ⚠️ **连带坑与最终落点(2026-10-09 实测)**:一旦在 GUI 里启用这两个钩子,CubeMX 会在 `Src/freertos.c` 生成 `USER CODE BEGIN 4 / 5` 区,默认内容是**空桩**——若实现仍留在 `USER CODE Application` 区,就出现**同名函数两处定义 → 编译错**。 +> **正确做法:整个钩子函数(含签名)写进 4 / 5 区**,`Application` 区里的旧实现删掉。这两个区名由 CubeMX 当前模板生成,且**其存在由 `.ioc` 启用钩子保证**(L1 兜住 L2),比"每次重生成后删桩"更省事也更不易漏。签名与生成原型保持一致(`xTaskHandle` → `TaskHandle_t`,即 `void *`)。配套 helper `hook_ptr_ok()` 必须在钩子之前定义 → 放 `USER CODE BEGIN PD` 区。审计项 `stack-overflow-hook-impl`(区 4)/ `malloc-failed-hook-impl`(区 5)/ `stack-overflow-hook-helper`(区 PD)分别校验。 + ##### 为什么 `fault_handler_enable()` 写不进 `.ioc`(2026-10-01 查模板源码证实) 用户问"能否通过 CubeMX 配置",逐条查证 CubeMX 安装目录 @@ -926,14 +938,16 @@ external pin → "pin reset" (新增) > 与 `SHCSR` 使能位无关。**不要误以为勾了 CubeMX 的 Enabled 就等于使能了故障。** > **判断口诀**:能在外设/中间件的图形界面里找到对应输入框的 → 一定写 `.ioc`; -> 找不到(如 FreeRTOS 的两个加固宏、断言定义、故障异常处理函数体)→ 只能 L2/L3。 +> 找不到(如 `configASSERT` 定义、故障异常处理函数体、`SHCSR` 使能位)→ 只能 L2/L3。 +> ⚠️ 但**别凭印象断言"界面里没有"**——先翻一遍各标签页或查 `db/mcu/IP/*_Modes.xml`: +> FreeRTOS 那两个加固宏就一直躺在 "Config parameters" 标签页里,因此白丢了两次。 #### L2:`USER CODE` 区的可用位置(本项目实测) | 文件 | 可用标记区 | 已用于 | |---|---|---| -| `Inc/FreeRTOSConfig.h` | `Header` / `Includes` / `FREE_RTOS_CONFIG_HARDENING` / `MESSAGE_BUFFER_LENGTH_TYPE` / `1` / `Defines` | 加固宏(HARDENING)、`configASSERT`(1) | -| `Src/freertos.c` | 共 25 个,含 `Includes` / `Application` / `Variables` / `PD` / `PTD` / … | 钩子实现(`Application`)、`timeSyncTask` 属性定义(`Variables`) | +| `Inc/FreeRTOSConfig.h` | `Header` / `Includes` / `MESSAGE_BUFFER_LENGTH_TYPE` / `1` / `Defines` | `configASSERT`(`1`)。加固宏已迁 L1(写 `.ioc`、由模板生成),不再占标记区 | +| `Src/freertos.c` | 共 25 个,含 `Includes` / `PD` / `PTD` / `Variables` / `4` / `5` / `Application` / … | 栈溢出钩子(`4`)、malloc 失败钩子(`5`)、helper `hook_ptr_ok`(`PD`)、**任务栈核算依据 + `timeSyncTask` 属性定义(`Variables`)**、断言钩子及其余应用代码(`Application`) | | `Src/stm32f4xx_it.c` | 共 52 个,含文件头 `0`(标准保护位)+ 各中断函数**内部**的 `_IRQn 0` / `W1__IRQn 0` | 崩溃报告实现(`0`) | | `Src/main.c` | 共 19 个,含 `Init` / `SysInit` / `2` / `PV` / `PFP` | 复位原因锁存(`Init`) | | `Src/iwdg.c` | 共 7 个,含 `IWDG_Init 0/1/2` | ❌ **本次改动用不上**(见下方特例) | diff --git a/docs/待处理内容.md b/docs/待处理内容.md index 32e2f575..9a2b454f 100644 --- a/docs/待处理内容.md +++ b/docs/待处理内容.md @@ -70,7 +70,7 @@ | 序 | 任务 | 前置 | 说明 | |---|---|---|---| | **B0** | **产品定义确认**(阻塞项) | — | 需甲方明确:① 采集是否持续 ② 采样率(**通道语义已于 2026-10-09 确认并固化 → `docs/硬件平台/ADC通道映射说明.md`**:UA/UB/UC/UN=`AIN1~4`、IA/IB/IC/IN=`AIN8~11`、V_ZL2=温度、其余 8 路备用;主板只做监视/辅助测量,计量在子板) ③ 转发目标(MODBUS RTU?上行 TCP?)④ `APP_ADC_ENABLE`/`APP_RS485_ENABLE` 语义。**B1/B2 的规模完全取决于此** | -| **B1** | **ADC 采集链路实现**(消化 P1-1、E-58) | B0 + **E-59 门禁** | 周期 CONVST 重触发 + `adc_task` 消费 `get_buf`;**先修 E-58**(原子快照 API,否则接入即撕裂);栈预算核算(两任务未入 `freertos.c` 栈表);**取数必须按 `docs/硬件平台/ADC通道映射说明.md`**(TPAFE `buf[2]=IA`/`buf[5]=UN`/`buf[6]=UA`;STM32 侧 9 路含 UB/UC/IB/IC/IN/温度,需先启用 `HAL_ADC_MODULE_ENABLED`,网名 ADC17=PC4 用 `ADC_CHANNEL_14`) | +| **B1** | **ADC 采集链路实现**(消化 P1-1、E-58) | B0 + **E-59 门禁** | 周期 CONVST 重触发 + `adc_task` 消费 `get_buf`;**先修 E-58**(原子快照 API,否则接入即撕裂);栈预算核算(两任务未入 `freertos.c` 栈表);**取数必须按 `docs/硬件平台/ADC通道映射说明.md`**(TPAFE `buf[2]=IA`/`buf[5]=UN`/`buf[6]=UA`;STM32 侧 ADC1 **已于 2026-10-09 生成**:`hadc1` + `MX_ADC1_Init()`、9 通道 Rank1~9、144 cycles、ADCCLK=21 MHz、软件触发,网名 ADC17=PC4 用 `ADC_CHANNEL_14`;剩活只剩消费者与 `adc_task` 建任务) | | **B2** | **RS-485 采集链路实现**(消化 E-50、E-49) | B0 + **E-59 门禁** | 双缓冲 + 序号(防包撕裂)+ DE 收尾(超时路径等 TC)+ 协议状态机(`App/protocol/` 正是为此预留) | | **B3** | **E-59 门禁固化入 `AGENTS.md`** | — | 把"接消费者前必须先修 E-36/E-44/E-45/E-58 + 栈预算"写成强制门禁,与"改栈前跑 `stack_report.py`"同级。**这是防止 B1/B2 带缺陷上线的关键** | diff --git a/docs/硬件平台/ADC通道映射说明.md b/docs/硬件平台/ADC通道映射说明.md index eb1e4930..f182f63a 100644 --- a/docs/硬件平台/ADC通道映射说明.md +++ b/docs/硬件平台/ADC通道映射说明.md @@ -101,7 +101,7 @@ STM32(U17)为 LQFP144 脚号。 > ⚠️ **`ADC17` 网名 ≠ `ADC_CHANNEL_17`**。PC4 在 F407 上是 `ADC123_IN14`,代码必须写 `ADC_CHANNEL_14`;`ADC_CHANNEL_12` 是 **PC2(pin 30)**,写错就读到另一只脚。 -**CubeMX 侧标签(2026-10-09 已写入 `STM32F407-Demo.ioc`,格式 `板级网名_语义`)**:`ADC9_RES` / `ADC10_IC` / `ADC11_IN` / `ADC12_UC` / `ADC13_RES` / `ADC14_TEMP` / `ADC15_IB` / `ADC16_RES` / `ADC17_UB`(9 脚信号已设为 `ADC1_IN0..IN7` + `ADC1_IN14`)。 +**CubeMX 侧标签(2026-10-09 已写入 `STM32F407-Demo.ioc` 并生成代码,格式 `板级网名_语义`)**:`ADC9_RES` / `ADC10_IC` / `ADC11_IN` / `ADC12_UC` / `ADC13_RES` / `ADC14_TEMP` / `ADC15_IB` / `ADC16_RES` / `ADC17_UB`(9 脚已配到 ADC1 的 IN0..IN7 + IN14,生成代码里对应 `main.h` 的 `ADC9_RES_Pin`…`ADC17_UB_Pin`)。⚠ PA0 标签首次配置时误写成 `AD9_RES`(少个 C),已改回 `ADC9_RES`(`.ioc` + `Inc/main.h` + `Src/adc.c` 三处同步)。 **引脚可用性核查(2026-10-09)**:`STM32F407-Demo.ioc` 中 PA0~PA7、PC4 **此前均未分配**(PC5 = LED1,与 ADC 无关)→ 这 9 路做模拟输入无冲突,现已配给 ADC1。PA4/PA5 兼 `DAC_OUT1/2`,作模拟输入期间须保持 DAC 关闭(当前固件未启用 DAC ✓);PA4/PA5/PA6/PA7 的 SPI1 复用未使用(SPI1 走 PB3/PB4/PB5)✓。 @@ -118,8 +118,8 @@ STM32(U17)为 LQFP144 脚号。 | 项 | 现状 | 影响 | |---|---|---| -| STM32 ADC 外设 | **`.ioc` 已配 ADC1(9 通道 / Rank 1~9 / 采样 144 cycles / 软件触发 / Scan=ENABLE),但尚未生成代码**:`Inc/stm32f4xx_hal_conf.h` 的 `HAL_ADC_MODULE_ENABLED` 仍是注释,`Src/adc.c` 与 HAL adc 驱动(`stm32f4xx_hal_adc.c/_ex.c`)不在仓库(HAL 为裁剪子集) | 运行时仍采不到;须在 CubeMX 6.17.0 + FW_F4 V1.28.3 里 Generate Code,再把新文件注册进 `MDK-ARM/*.uvprojx` 并 `@build` | -| ADC 时钟(生成后注意) | CubeMX 对 F4 固定生成 `ADC_CLOCK_SYNC_PCLK_DIV2` → ADCCLK = APB2/2 = **42 MHz**,超 DS 表 67 的 36 MHz 上限 | 代码侧改 `__HAL_RCC_ADC_CONFIG(RCC_ADCPCLK2_DIV4)`(21 MHz,放 `USER CODE` 区或 `MX_ADC1_Init()` 之后);按 144+12 cycles 算 ≈ 7.4 µs/通道、9 通道一轮 ≈ 67 µs | +| STM32 ADC 外设 | **已生成(2026-10-09,CubeMX 6.17 + FW_F4)**:`Src/adc.c`/`Inc/adc.h` 已入库并挂进 `MDK-ARM/*.uvprojx`;`Inc/stm32f4xx_hal_conf.h` 的 `HAL_ADC_MODULE_ENABLED` 已生效;HAL `stm32f4xx_hal_adc.c/_ex.c` + `stm32f4xx_ll_adc.h` 已补入仓库(HAL 原本是裁剪子集);`Src/main.c` 里 `MX_ADC1_Init()` 排在 `MX_IWDG_Init()` 之后。生成配置核对无误:9 通道 / Rank 1~9 / 全部 144 cycles / `ScanConvMode=ENABLE` / `ContinuousConvMode=DISABLE` / `ExternalTrigConv=ADC_SOFTWARE_START` + `EDGE_NONE` / `EOCSelection=ADC_EOC_SINGLE_CONV` / `DataAlign=RIGHT` / 12 位;`HAL_ADC_MspInit()` 已把 PA0~PA7+PC4 配成 `GPIO_MODE_ANALOG` | 硬件通路已打通(`hadc1` 可用);**仍无消费者**——见下面两行 | +| ADC 时钟 | CubeMX 的 F4 ADC 面板**有** Clock Prescaler 一项(此前"面板没有该项、固定 DIV2"的判断有误),已选 **PCLK2/4 → ADCCLK = 21 MHz** ✓。面板里 **DIV2 是灰的、选不到**:DB 里 `FadcConstraint Max=36000000`,APB2 = 84 MHz → DIV2 = 42 MHz 超限,该候选值被 `Action="DISABLE"` 禁掉,超规值进不来 | **不设额外防护(2026-10-09 决定)**:约束已由 CubeMX 把关;`.ioc` 虽不保存 `ADC1.ClockPrescaler` 键,重生成也只会回落到约束允许的值。按 144+12 cycles 算 ≈ 7.4 µs/通道、9 通道一轮 ≈ 67 µs | | `adc_task` | **空桩**:`App/task/adc_task.c` 只 `osDelay(1000)`,且任务未在 `Src/freertos.c` 创建 | 无消费者,数据路径死(登记簿 P1-1) | | TPAFE 采样触发 | `tpafe5160_start_conv_irq()` 仅在 `app_main_init` 调一次,**无周期 CONVST 重触发** | 只采到一帧,无连续波形 | | 前端偏置 | 每路 1k 串联 + 1k 到 `*_GND` + 滤波 C,**无中点偏置** | STM32 侧只能测 **0~3.3 V 单极性**,交流量负半周被削顶;主板侧只做监视可接受,若要算 RMS/功率需硬件补偏置或明确算法口径 | @@ -141,3 +141,4 @@ STM32(U17)为 LQFP144 脚号。 | 日期 | 内容 | |---|---| | 2026-10-09 | 建档:固化 V0.1 语义分配(UA/UB/UC/UN、IA/IB/IC/IN、V_ZL2=温度、其余备用)与 17 路端到端映射;确立"主板只做监视/辅助测量、计量在子板"口径;勘误 PC4 通道号(IN12→IN14)与 PB0 定性(=IN8) | +| 2026-10-09 | **CubeMX 生成 ADC1(9 通道)落地**:新增 `Src/adc.c`/`Inc/adc.h` + HAL adc 三文件并挂进 uvprojx、`HAL_ADC_MODULE_ENABLED` 生效、`MX_ADC1_Init()` 入 `main.c`;分频 PCLK2/4 = 21 MHz——面板里 DIV2 已被 `FadcConstraint`(36 MHz)约束禁掉,**故不加 `.ioc` 键 / 代码守卫 / 审计项等额外防护**(曾加过,按决定撤除,理由见 §7"ADC 时钟"行);修正 PA0 标签笔误 `AD9_RES`→`ADC9_RES`。⚠ 本次重生成打回了 5 处定制(IWDG 延迟启动锚点、HardFault + 3 个 Fault 手工 Handler、`FreeRTOSConfig.h` 加固区、`freertos.c` 三处栈核算注释),已全部复原;存活审计新增 1 项 `adc1-hal-enabled`(共 19 项),现 19 通过 / 1 警告(timeSyncTask 手工定义)/ 0 失败,`@build` 0 错 0 警 | diff --git a/scripts/check_cubemx_survival.py b/scripts/check_cubemx_survival.py index 9999a1bd..dda73c85 100644 --- a/scripts/check_cubemx_survival.py +++ b/scripts/check_cubemx_survival.py @@ -147,22 +147,33 @@ CHECKS = [ "须在 USER CODE BEGIN 0 区内(生成区内的标准保护位)。", ), # ---------------- P1:FreeRTOS 加固 ---------------- + # ⚠ 2026-10-09 升级:这两项原先靠 FreeRTOSConfig.h 里**自造**的 + # `USER CODE BEGIN FREE_RTOS_CONFIG_HARDENING` 区——模板不认这个区名, + # 重生成连标记带内容一起消失(实测两次)。现已改为 **L1 写进 .ioc**: + # GUI = FreeRTOS 页 → "Config parameters" 标签 → "Hook function related + # definitions" 组 → CHECK_FOR_STACK_OVERFLOW=2 / USE_MALLOC_FAILED_HOOK=1, + # 由 CubeMX 模板自己生成到 FreeRTOSConfig.h,永不被打回。 dict( id="stack-overflow-check", - kind="protected", - path="Inc/FreeRTOSConfig.h", - region="FREE_RTOS_CONFIG_HARDENING", - must_contain=["configCHECK_FOR_STACK_OVERFLOW"], - hint="栈溢出机械检测必须开启(模式 2)。关闭后溢出静默腐蚀堆相邻块。", + kind="ioc", + key="FREERTOS.configCHECK_FOR_STACK_OVERFLOW", + want="2", + hint="栈溢出机械检测(模式 2)必须在 .ioc 里(GUI: FreeRTOS → Config parameters → " + "Hook function related definitions)。关闭后溢出静默腐蚀堆相邻块。", ), dict( id="malloc-failed-hook", - kind="protected", - path="Inc/FreeRTOSConfig.h", - region="FREE_RTOS_CONFIG_HARDENING", - must_contain=["configUSE_MALLOC_FAILED_HOOK"], - hint="堆分配失败钩子必须开启(1)。", + kind="ioc", + key="FREERTOS.configUSE_MALLOC_FAILED_HOOK", + want="1", + hint="堆分配失败钩子必须在 .ioc 里(同上 GUI 位置)。", ), + # ⚠ 2026-10-09 连带坑与最终落点:在 GUI 里启用这两个钩子后,CubeMX 会在 freertos.c + # 生成 `USER CODE BEGIN 4 / 5` 区(默认内容是空桩)。若把我们的实现留在 + # `Application` 区、又留着生成桩 → **同名函数两处定义 = 编译错**。 + # 最终落点(比"每次删桩"更稳):**整个钩子函数写进 4 / 5 区**——区名由 CubeMX + # 生成、且其存在由 `.ioc` 启用钩子保证,重生成时 CubeMX 只保留区内容、不再补桩。 + # 配套 helper `hook_ptr_ok()` 必须在钩子之前定义,故放 `USER CODE BEGIN PD` 区。 dict( id="assert-not-deadloop", kind="protected", @@ -185,9 +196,26 @@ CHECKS = [ id="stack-overflow-hook-impl", kind="protected", path="Src/freertos.c", - region="Application", - must_contain=["vApplicationStackOverflowHook"], - hint="栈溢出钩子实现(打印任务名后复位)。", + region="4", + must_contain=["vApplicationStackOverflowHook", "STACK OVERFLOW", "NVIC_SystemReset"], + hint="栈溢出钩子实现(裸 UART 打任务名后复位)须**整体**写在 `USER CODE BEGIN 4` 区内。", + ), + dict( + id="malloc-failed-hook-impl", + kind="protected", + path="Src/freertos.c", + region="5", + must_contain=["vApplicationMallocFailedHook", "MALLOC FAILED"], + hint="堆分配失败钩子实现(只告警不复位)须**整体**写在 `USER CODE BEGIN 5` 区内。", + ), + dict( + id="stack-overflow-hook-helper", + kind="protected", + path="Src/freertos.c", + region="PD", + must_contain=["hook_ptr_ok"], + hint="任务名指针范围校验 helper 须在钩子之前定义(现放 `USER CODE BEGIN PD` 区);" + "缺了它,钩子会因不可信 TCB 指针二次崩溃(2026-09-24 实测 HardFault)。", ), # ---------------- 看门狗模块 ---------------- dict( @@ -250,6 +278,17 @@ CHECKS = [ hint="任务栈大小必须写在 .ioc(FREERTOS.Tasks01)里——写入 .ioc 的栈值" "会被 CubeMX 直接生成到 freertos.c,是最彻底的防丢失手段。", ), + # ---------------- ADC1(2026-10-09 首次启用) ---------------- + dict( + id="adc1-hal-enabled", + kind="generated", + path="Inc/stm32f4xx_hal_conf.h", + must_contain=["#define HAL_ADC_MODULE_ENABLED"], + hint="HAL_ADC_MODULE_ENABLED 须为**生效**状态(非注释),否则 adc.c 不参与编译。", + ), + # 注:ADC 时钟分频**不设防护**(2026-10-09 决定)。CubeMX 面板里 DIV2 已被约束禁用 + # (FadcConstraint Max=36000000;APB2=84 MHz → DIV2=42 MHz 超限,选不到), + # .ioc 虽不保存 ADC1.ClockPrescaler 键,重生成也只会回落到约束允许的值。 ]